eventx-design-system
Version:
Design System do EventX
238 lines (233 loc) • 5.7 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import styled, { keyframes } from 'styled-components';
import { colors, spacing, typography } from '../tokens/design-tokens';
// Animações
const spin = keyframes `
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
`;
const pulse = keyframes `
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
`;
const dots = keyframes `
0%, 80%, 100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
`;
// Container do loading
const LoadingContainer = styled.div `
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: ${spacing[3]};
${({ fullScreen }) => fullScreen &&
`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.9);
z-index: 9999;
`}
`;
// Spinner
const Spinner = styled.div `
border: 2px solid ${colors.neutral[200]};
border-top: 2px solid ${({ color }) => {
switch (color) {
case 'secondary':
return colors.brand.secondary[950];
case 'white':
return colors.neutral[50];
default:
return colors.brand.primary[950];
}
}};
border-radius: 50%;
animation: ${spin} 1s linear infinite;
${({ size }) => {
switch (size) {
case 'sm':
return `
width: 16px;
height: 16px;
`;
case 'lg':
return `
width: 32px;
height: 32px;
`;
case 'xl':
return `
width: 48px;
height: 48px;
`;
default:
return `
width: 24px;
height: 24px;
`;
}
}}
`;
// Dots
const DotsContainer = styled.div `
display: flex;
gap: ${spacing[1]};
align-items: center;
justify-content: center;
${({ size }) => {
switch (size) {
case 'sm':
return `
gap: 2px;
`;
case 'lg':
return `
gap: 4px;
`;
case 'xl':
return `
gap: 6px;
`;
default:
return `
gap: 3px;
`;
}
}}
`;
const Dot = styled.div `
width: ${({ size }) => {
switch (size) {
case 'sm':
return '4px';
case 'lg':
return '8px';
case 'xl':
return '12px';
default:
return '6px';
}
}};
height: ${({ size }) => {
switch (size) {
case 'sm':
return '4px';
case 'lg':
return '8px';
case 'xl':
return '12px';
default:
return '6px';
}
}};
border-radius: 50%;
background-color: ${({ color }) => {
switch (color) {
case 'secondary':
return colors.brand.secondary[950];
case 'white':
return colors.neutral[50];
default:
return colors.brand.primary[950];
}
}};
animation: ${dots} 1.4s ease-in-out infinite both;
animation-delay: ${({ delay }) => delay}s;
`;
// Pulse
const Pulse = styled.div `
width: ${({ size }) => {
switch (size) {
case 'sm':
return '16px';
case 'lg':
return '32px';
case 'xl':
return '48px';
default:
return '24px';
}
}};
height: ${({ size }) => {
switch (size) {
case 'sm':
return '16px';
case 'lg':
return '32px';
case 'xl':
return '48px';
default:
return '24px';
}
}};
border-radius: 50%;
background-color: ${({ color }) => {
switch (color) {
case 'secondary':
return colors.brand.secondary[950];
case 'white':
return colors.neutral[50];
default:
return colors.brand.primary[950];
}
}};
animation: ${pulse} 1.5s ease-in-out infinite;
`;
// Texto do loading
const LoadingText = styled.span `
font-family: ${typography.fontFamily.primary};
font-weight: ${typography.fontWeight.medium};
color: ${({ color }) => {
switch (color) {
case 'secondary':
return colors.brand.secondary[950];
case 'white':
return colors.neutral[50];
default:
return colors.brand.primary[950];
}
}};
${({ size }) => {
switch (size) {
case 'sm':
return `
font-size: ${typography.fontSize.sm};
`;
case 'lg':
return `
font-size: ${typography.fontSize.lg};
`;
case 'xl':
return `
font-size: ${typography.fontSize.xl};
`;
default:
return `
font-size: ${typography.fontSize.base};
`;
}
}}
`;
export const Loading = ({ size = 'md', variant = 'spinner', color = 'primary', text, fullScreen = false, className, ...props }) => {
const renderVariant = () => {
switch (variant) {
case 'dots':
return (_jsxs(DotsContainer, { size: size, color: color, children: [_jsx(Dot, { size: size, color: color, delay: 0 }), _jsx(Dot, { size: size, color: color, delay: 0.2 }), _jsx(Dot, { size: size, color: color, delay: 0.4 })] }));
case 'pulse':
return _jsx(Pulse, { size: size, color: color });
default:
return _jsx(Spinner, { size: size, color: color });
}
};
return (_jsxs(LoadingContainer, { fullScreen: fullScreen, className: className, ...props, children: [renderVariant(), text && _jsx(LoadingText, { size: size, color: color, children: text })] }));
};