eventx-design-system
Version:
Design System do EventX
90 lines (84 loc) • 3.68 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
import styled from 'styled-components';
import { colors, typography, spacing, borderRadius } from '../../tokens/design-tokens';
const TabsContainer = styled.div `
width: 100%;
`;
const TabsList = styled.div `
display: flex;
border-bottom: 1px solid ${colors.neutral[300]};
margin-bottom: ${spacing[4]};
`;
const TabButton = styled.button `
background: none;
border: none;
padding: ${spacing[3]} ${spacing[4]};
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.base};
font-weight: ${({ active }) => active ? typography.fontWeight.semibold : typography.fontWeight.normal};
color: ${({ active }) => active ? colors.brand.primary[500] : colors.neutral[600]};
cursor: pointer;
transition: all 0.2s ease-in-out;
position: relative;
border-radius: ${borderRadius.base} ${borderRadius.base} 0 0;
margin-right: ${spacing[1]};
&:hover {
color: ${({ active }) => active ? colors.brand.primary[500] : colors.brand.primary[400]};
background-color: ${({ active }) => active ? colors.brand.primary[50] : colors.neutral[100]};
}
&:focus {
outline: none;
box-shadow: 0 0 0 2px ${colors.brand.primary[200]};
}
&::after {
content: '';
position: absolute;
bottom: -1px;
left: 0;
right: 0;
height: 2px;
background-color: ${({ active }) => active ? colors.brand.primary[500] : 'transparent'};
transition: background-color 0.2s ease-in-out;
}
`;
const TabContent = styled.div `
padding: ${spacing[4]} 0;
`;
const MobileTabsContainer = styled.div `
display: flex;
flex-direction: column;
gap: ${spacing[2]};
`;
const MobileTabButton = styled.button `
background: ${({ active }) => active ? colors.brand.primary[500] : colors.neutral[100]};
border: 1px solid ${({ active }) => active ? colors.brand.primary[500] : colors.neutral[300]};
border-radius: ${borderRadius.base};
padding: ${spacing[3]} ${spacing[4]};
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.base};
font-weight: ${({ active }) => active ? typography.fontWeight.semibold : typography.fontWeight.normal};
color: ${({ active }) => active ? colors.neutral[50] : colors.neutral[700]};
cursor: pointer;
transition: all 0.2s ease-in-out;
text-align: left;
&:hover {
background: ${({ active }) => active ? colors.brand.primary[600] : colors.neutral[200]};
}
&:focus {
outline: none;
box-shadow: 0 0 0 2px ${colors.brand.primary[200]};
}
`;
export const Tabs = ({ tabs, defaultActiveTab, onChange, variant = 'default', className, }) => {
const [activeTab, setActiveTab] = useState(defaultActiveTab || tabs[0]?.id || '');
const handleTabChange = (tabId) => {
setActiveTab(tabId);
onChange?.(tabId);
};
const activeTabContent = tabs.find(tab => tab.id === activeTab)?.content;
if (variant === 'mobile') {
return (_jsxs(TabsContainer, { className: className, children: [_jsx(MobileTabsContainer, { children: tabs.map((tab) => (_jsx(MobileTabButton, { active: activeTab === tab.id, onClick: () => !tab.disabled && handleTabChange(tab.id), disabled: tab.disabled, children: tab.label }, tab.id))) }), _jsx(TabContent, { children: activeTabContent })] }));
}
return (_jsxs(TabsContainer, { className: className, children: [_jsx(TabsList, { children: tabs.map((tab) => (_jsx(TabButton, { active: activeTab === tab.id, onClick: () => !tab.disabled && handleTabChange(tab.id), disabled: tab.disabled, children: tab.label }, tab.id))) }), _jsx(TabContent, { children: activeTabContent })] }));
};