eventx-design-system
Version:
Design System do EventX
182 lines (177 loc) • 5.6 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 do alert
const AlertContainer = styled.div `
display: flex;
align-items: flex-start;
gap: ${spacing[3]};
padding: ${spacing[4]};
border-radius: ${borderRadius.lg};
border: 1px solid;
font-family: ${typography.fontFamily.primary};
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
${({ variant }) => {
switch (variant) {
case 'success':
return css `
background-color: ${colors.semantic.success[50]};
border-color: ${colors.semantic.success[200]};
color: ${colors.semantic.success[800]};
`;
case 'error':
return css `
background-color: ${colors.semantic.error[50]};
border-color: ${colors.semantic.error[200]};
color: ${colors.semantic.error[800]};
`;
case 'warning':
return css `
background-color: ${colors.semantic.warning[50]};
border-color: ${colors.semantic.warning[200]};
color: ${colors.semantic.warning[800]};
`;
case 'info':
return css `
background-color: ${colors.semantic.info[50]};
border-color: ${colors.semantic.info[200]};
color: ${colors.semantic.info[800]};
`;
default:
return css `
background-color: ${colors.neutral[50]};
border-color: ${colors.neutral[200]};
color: ${colors.neutral[800]};
`;
}
}}
`;
// Ícone do alert
const AlertIcon = styled.div `
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
flex-shrink: 0;
margin-top: 2px;
${({ variant }) => {
switch (variant) {
case 'success':
return css `color: ${colors.semantic.success[600]};`;
case 'error':
return css `color: ${colors.semantic.error[600]};`;
case 'warning':
return css `color: ${colors.semantic.warning[600]};`;
case 'info':
return css `color: ${colors.semantic.info[600]};`;
default:
return css `color: ${colors.neutral[600]};`;
}
}}
`;
// Conteúdo do alert
const AlertContent = styled.div `
flex: 1;
min-width: 0;
`;
// Título do alert
const AlertTitle = styled.h4 `
margin: 0 0 ${spacing[1]} 0;
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.base};
font-weight: ${typography.fontWeight.semibold};
line-height: ${typography.lineHeight.tight};
`;
// Mensagem do alert
const AlertMessage = styled.div `
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.sm};
font-weight: ${typography.fontWeight.normal};
line-height: ${typography.lineHeight.normal};
`;
// Botão de fechar
const CloseButton = styled.button `
background: none;
border: none;
padding: ${spacing[1]};
cursor: pointer;
border-radius: ${borderRadius.base};
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
flex-shrink: 0;
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
${({ variant }) => {
switch (variant) {
case 'success':
return css `
color: ${colors.semantic.success[600]};
&:hover {
background-color: ${colors.semantic.success[100]};
}
`;
case 'error':
return css `
color: ${colors.semantic.error[600]};
&:hover {
background-color: ${colors.semantic.error[100]};
}
`;
case 'warning':
return css `
color: ${colors.semantic.warning[600]};
&:hover {
background-color: ${colors.semantic.warning[100]};
}
`;
case 'info':
return css `
color: ${colors.semantic.info[600]};
&:hover {
background-color: ${colors.semantic.info[100]};
}
`;
default:
return css `
color: ${colors.neutral[600]};
&:hover {
background-color: ${colors.neutral[100]};
}
`;
}
}}
&:focus {
outline: 2px solid ${colors.brand.primary[500]};
outline-offset: 2px;
}
`;
// Ícones para cada variante
const getIcon = (variant) => {
switch (variant) {
case 'success':
return '✓';
case 'error':
return '✕';
case 'warning':
return '⚠';
case 'info':
return 'ℹ';
default:
return 'ℹ';
}
};
export const Alert = ({ variant = 'info', title, children, dismissible = false, onDismiss, className, ...props }) => {
const [isVisible, setIsVisible] = useState(true);
const handleDismiss = () => {
setIsVisible(false);
onDismiss?.();
};
if (!isVisible)
return null;
return (_jsxs(AlertContainer, { variant: variant, className: className, ...props, children: [_jsx(AlertIcon, { variant: variant, children: getIcon(variant) }), _jsxs(AlertContent, { children: [title && _jsx(AlertTitle, { children: title }), _jsx(AlertMessage, { children: children })] }), dismissible && (_jsx(CloseButton, { variant: variant, onClick: handleDismiss, "aria-label": "Fechar alerta", children: "\u00D7" }))] }));
};
Alert.displayName = 'Alert';