UNPKG

eventx-design-system

Version:
238 lines (233 loc) 5.7 kB
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 })] })); };