saagie-ui
Version:
Saagie UI from Saagie Design System
76 lines (67 loc) • 1.67 kB
JavaScript
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import { useTabContext } from './TabsProvider';
const propTypes = {
/**
* Children to set inside the TabPanel.
*/
children: PropTypes.node,
/**
* The name of the panel. It should match the tab name to show itself when
* the matching tab is selected.
*/
name: PropTypes.string.isRequired,
/**
* A ref that will contains the current visible panel ref.
*/
selectedPanelRef: PropTypes.any,
/**
* The custom tag for the root of the Tab
*/
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
};
const defaultProps = {
children: '',
selectedPanelRef: null,
tag: 'div',
};
const assignRef = (ref, value) => {
if (ref == null) return;
if (typeof ref === 'function') {
ref(value);
} else {
try {
// eslint-disable-next-line no-param-reassign
ref.current = value;
} catch (error) {
throw new Error(`Cannot assign value "${value}" to ref "${ref}"`);
}
}
};
export const TabPanel = forwardRef(({
children, selectedPanelRef, name, tag: Tag, ...attributes
}, ref) => {
const { id, selectedName } = useTabContext();
const isSelected = name === selectedName;
if (!isSelected) {
return '';
}
return (
<Tag
ref={(node) => {
if (isSelected) {
assignRef(selectedPanelRef, node);
}
assignRef(ref, node);
}}
role="tabpanel"
aria-labelledby={`tab:${id}:${name}`}
id={`panel:${id}:${name}`}
{...attributes}
>
{children}
</Tag>
);
});
TabPanel.propTypes = propTypes;
TabPanel.defaultProps = defaultProps;