eventx-design-system
Version:
Design System do EventX
151 lines (139 loc) • 5.22 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
import styled, { css } from 'styled-components';
import { colors, typography, spacing, borderRadius, transitions } from '../tokens/design-tokens';
// Container dos tabs
const TabsContainer = styled.div `
width: ${({ fullWidth }) => fullWidth ? '100%' : 'auto'};
`;
// Lista de tabs
const TabList = styled.div `
display: flex;
border-bottom: ${({ variant }) => variant === 'underline' ? `1px solid ${colors.neutral[200]}` : 'none'};
gap: ${spacing[1]};
${({ fullWidth }) => fullWidth &&
css `
width: 100%;
`}
`;
// Tab individual
const TabButton = styled.button `
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
font-family: ${typography.fontFamily.primary};
font-weight: ${typography.fontWeight.medium};
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
position: relative;
white-space: nowrap;
${({ size }) => {
switch (size) {
case 'sm':
return css `
padding: ${spacing[2]} ${spacing[3]};
font-size: ${typography.fontSize.sm};
line-height: ${typography.lineHeight.normal};
min-height: 32px;
`;
case 'lg':
return css `
padding: ${spacing[4]} ${spacing[6]};
font-size: ${typography.fontSize.lg};
line-height: ${typography.lineHeight.relaxed};
min-height: 48px;
`;
default:
return css `
padding: ${spacing[3]} ${spacing[4]};
font-size: ${typography.fontSize.base};
line-height: ${typography.lineHeight.normal};
min-height: 40px;
`;
}
}}
${({ variant, isActive, fullWidth }) => {
switch (variant) {
case 'pills':
return css `
border-radius: ${borderRadius.full};
${fullWidth ? 'flex: 1;' : ''}
${isActive
? css `
background-color: ${colors.brand.primary[950]};
color: ${colors.neutral[50]};
`
: css `
background-color: transparent;
color: ${colors.neutral[600]};
&:hover:not(:disabled) {
background-color: ${colors.neutral[100]};
color: ${colors.neutral[800]};
}
`}
`;
case 'underline':
return css `
border-bottom: 2px solid transparent;
${fullWidth ? 'flex: 1;' : ''}
${isActive
? css `
color: ${colors.brand.primary[950]};
border-bottom-color: ${colors.brand.primary[950]};
`
: css `
color: ${colors.neutral[600]};
&:hover:not(:disabled) {
color: ${colors.neutral[800]};
border-bottom-color: ${colors.neutral[400]};
}
`}
`;
default:
return css `
border-radius: ${borderRadius.base};
${fullWidth ? 'flex: 1;' : ''}
${isActive
? css `
background-color: ${colors.brand.primary[50]};
color: ${colors.brand.primary[950]};
`
: css `
background-color: transparent;
color: ${colors.neutral[600]};
&:hover:not(:disabled) {
background-color: ${colors.neutral[100]};
color: ${colors.neutral[800]};
}
`}
`;
}
}}
${({ disabled }) => disabled &&
css `
opacity: 0.5;
color: ${colors.neutral[400]} !important;
`}
&:focus {
outline: 2px solid ${colors.brand.primary[500]};
outline-offset: 2px;
}
`;
// Conteúdo dos tabs
const TabContent = styled.div `
padding: ${spacing[6]} 0;
`;
export const Tabs = ({ tabs, defaultActiveTab, variant = 'default', size = 'md', fullWidth = false, className, onTabChange, ...props }) => {
const [activeTab, setActiveTab] = useState(defaultActiveTab || tabs[0]?.id || '');
const handleTabClick = (tabId) => {
const tab = tabs.find(t => t.id === tabId);
if (tab && !tab.disabled) {
setActiveTab(tabId);
onTabChange?.(tabId);
}
};
const activeTabContent = tabs.find(tab => tab.id === activeTab)?.content;
return (_jsxs(TabsContainer, { fullWidth: fullWidth, className: className, ...props, children: [_jsx(TabList, { variant: variant, fullWidth: fullWidth, children: tabs.map((tab) => (_jsx(TabButton, { isActive: tab.id === activeTab, variant: variant, size: size, fullWidth: fullWidth, disabled: tab.disabled || false, onClick: () => handleTabClick(tab.id), type: "button", role: "tab", "aria-selected": tab.id === activeTab, "aria-disabled": tab.disabled, children: tab.label }, tab.id))) }), _jsx(TabContent, { role: "tabpanel", children: activeTabContent })] }));
};