@penaprieto/design-system
Version:
Multi-brand React design system with design tokens from Figma
63 lines (62 loc) • 3.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tabs = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
require("./Tabs.css");
const Icon_1 = require("../Icon");
const Tabs = ({ tabs, size = 'medium', activeTab: controlledActiveTab, defaultActiveTab, onTabChange, className = '', ariaLabel = 'Tabs', }) => {
var _a, _b;
const isControlled = controlledActiveTab !== undefined;
const [internalActiveTab, setInternalActiveTab] = (0, react_1.useState)(defaultActiveTab || ((_a = tabs.find((t) => !t.disabled)) === null || _a === void 0 ? void 0 : _a.id) || ((_b = tabs[0]) === null || _b === void 0 ? void 0 : _b.id) || '');
const activeTab = isControlled ? controlledActiveTab : internalActiveTab;
const tabRefs = (0, react_1.useRef)([]);
const handleTabClick = (tabId, disabled) => {
if (disabled)
return;
if (!isControlled) {
setInternalActiveTab(tabId);
}
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange(tabId);
};
const handleKeyDown = (e, currentIndex) => {
var _a;
if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft')
return;
e.preventDefault();
const direction = e.key === 'ArrowRight' ? 1 : -1;
let nextIndex = currentIndex;
// Find next non-disabled tab
do {
nextIndex = (nextIndex + direction + tabs.length) % tabs.length;
} while (tabs[nextIndex].disabled && nextIndex !== currentIndex);
if (!tabs[nextIndex].disabled) {
(_a = tabRefs.current[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus();
handleTabClick(tabs[nextIndex].id);
}
};
const rootClassName = [
'ds-tabs',
`ds-tabs--${size}`,
className,
]
.filter(Boolean)
.join(' ');
return ((0, jsx_runtime_1.jsxs)("div", { className: rootClassName, children: [(0, jsx_runtime_1.jsx)("div", { className: "ds-tabs__list", role: "tablist", "aria-label": ariaLabel, children: tabs.map((tab, index) => {
const isActive = activeTab === tab.id;
const tabClassName = [
'ds-tabs__item',
isActive && 'ds-tabs__item--active',
tab.disabled && 'ds-tabs__item--disabled',
]
.filter(Boolean)
.join(' ');
return ((0, jsx_runtime_1.jsxs)("div", { ref: (el) => {
tabRefs.current[index] = el;
}, className: tabClassName, role: "tab", "aria-selected": isActive, "aria-disabled": tab.disabled, tabIndex: isActive && !tab.disabled ? 0 : -1, onClick: () => handleTabClick(tab.id, tab.disabled), onKeyDown: (e) => handleKeyDown(e, index), children: [tab.icon && ((0, jsx_runtime_1.jsx)("span", { className: "ds-tabs__icon", children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: tab.icon, size: size === 'small' ? 16 : 24 }) })), (0, jsx_runtime_1.jsx)("span", { className: "ds-tabs__label", children: tab.label })] }, tab.id));
}) }), (0, jsx_runtime_1.jsx)("div", { className: "ds-tabs__panels", children: tabs.map((tab) => {
const isActive = activeTab === tab.id;
return ((0, jsx_runtime_1.jsx)("div", { className: "ds-tabs__panel", role: "tabpanel", "aria-labelledby": tab.id, hidden: !isActive, tabIndex: 0, children: tab.content }, `panel-${tab.id}`));
}) })] }));
};
exports.Tabs = Tabs;