eventx-design-system
Version:
Design System do EventX
188 lines (182 loc) • 5.21 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef } from 'react';
import styled, { css } from 'styled-components';
import { colors, spacing, borderRadius, transitions } from '../tokens/design-tokens';
// Container do radio
const RadioContainer = styled.label `
display: inline-flex;
align-items: center;
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
user-select: none;
gap: ${spacing[2]};
opacity: ${({ disabled }) => (disabled ? 0.6 : 1)};
`;
// Input nativo (escondido)
const HiddenInput = styled.input `
position: absolute;
opacity: 0;
width: 0;
height: 0;
margin: 0;
padding: 0;
`;
// Radio customizado
const RadioBox = styled.div `
position: relative;
display: flex;
align-items: center;
justify-content: center;
background-color: ${colors.neutral[50]};
border: 2px solid ${colors.neutral[300]};
border-radius: ${borderRadius.full};
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
flex-shrink: 0;
${({ size }) => {
switch (size) {
case 'sm':
return css `
width: 16px;
height: 16px;
`;
case 'lg':
return css `
width: 24px;
height: 24px;
`;
default:
return css `
width: 20px;
height: 20px;
`;
}
}}
${({ checked, variant }) => {
if (checked) {
switch (variant) {
case 'error':
return css `
border-color: ${colors.semantic.error[500]};
`;
case 'success':
return css `
border-color: ${colors.semantic.success[500]};
`;
default:
return css `
border-color: ${colors.brand.primary[950]};
`;
}
}
return css ``;
}}
${({ disabled, checked, variant }) => {
if (!disabled) {
if (checked) {
switch (variant) {
case 'error':
return css `
&:hover {
border-color: ${colors.semantic.error[600]};
}
`;
case 'success':
return css `
&:hover {
border-color: ${colors.semantic.success[600]};
}
`;
default:
return css `
&:hover {
border-color: ${colors.brand.primary[900]};
}
`;
}
}
else {
return css `
&:hover {
border-color: ${colors.neutral[400]};
}
`;
}
}
return css ``;
}}
${({ disabled }) => disabled &&
css `
background-color: ${colors.neutral[100]};
border-color: ${colors.neutral[300]};
cursor: not-allowed;
`}
`;
// Ponto central do radio
const RadioDot = styled.div `
width: ${({ size }) => {
switch (size) {
case 'sm':
return '6px';
case 'lg':
return '10px';
default:
return '8px';
}
}};
height: ${({ size }) => {
switch (size) {
case 'sm':
return '6px';
case 'lg':
return '10px';
default:
return '8px';
}
}};
border-radius: ${borderRadius.full};
background-color: ${({ checked, variant }) => {
if (!checked)
return 'transparent';
switch (variant) {
case 'error':
return colors.semantic.error[500];
case 'success':
return colors.semantic.success[500];
default:
return colors.brand.primary[950];
}
}};
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
transform: ${({ checked }) => (checked ? 'scale(1)' : 'scale(0)')};
`;
// Label do radio
const RadioLabel = styled.span `
font-family: inherit;
color: ${colors.neutral[950]};
line-height: 1.4;
${({ size }) => {
switch (size) {
case 'sm':
return css `
font-size: 14px;
`;
case 'lg':
return css `
font-size: 18px;
`;
default:
return css `
font-size: 16px;
`;
}
}}
`;
export const Radio = forwardRef(({ checked = false, onChange, disabled = false, label, size = 'md', variant = 'default', className, name, id, value, required = false, ...props }, ref) => {
const handleChange = (event) => {
if (!disabled) {
onChange?.(event.target.checked);
}
};
const radioId = id || `radio-${Math.random().toString(36).substr(2, 9)}`;
return (_jsxs(RadioContainer, { disabled: disabled, className: className, children: [_jsx(HiddenInput, { ref: ref, type: "radio", checked: checked, onChange: handleChange, disabled: disabled, name: name, id: radioId, value: value, required: required, ...props }), _jsx(RadioBox, { checked: checked, disabled: disabled, size: size, variant: variant, children: _jsx(RadioDot, { checked: checked, size: size, variant: variant }) }), label && (_jsx(RadioLabel, { size: size, children: label }))] }));
});
Radio.displayName = 'Radio';