UNPKG

@buun_group/brutalist-ui

Version:
254 lines (213 loc) 4.67 kB
/* RadioGroup styles */ .group { display: flex; gap: var(--brutal-space-4); } .vertical { flex-direction: column; } .horizontal { flex-direction: row; flex-wrap: wrap; } /* Radio container */ .container { display: inline-flex; align-items: center; gap: var(--brutal-space-3); position: relative; user-select: none; } .radioWrapper { position: relative; display: inline-block; } /* Hide native radio but keep it clickable */ .input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; padding: 0; z-index: 1; cursor: pointer; } /* Custom radio */ .radio { display: flex; align-items: center; justify-content: center; background-color: var(--brutal-white); border: var(--brutal-border-width) var(--brutal-border-style) var(--brutal-black); cursor: pointer; transition: all var(--brutal-transition-base); position: relative; overflow: hidden; } .radio.withShadow { box-shadow: var(--brutal-shadow-sm); } /* Size variants */ .sm .radio { width: 16px; height: 16px; } .md .radio { width: 20px; height: 20px; } .lg .radio { width: 24px; height: 24px; } /* Square indicator (X mark) */ .indicator { position: absolute; width: 100%; height: 100%; opacity: 0; transition: all var(--brutal-transition-base); } .indicator::before, .indicator::after { content: ''; position: absolute; background-color: var(--brutal-black); transition: all var(--brutal-transition-base); } /* X mark design */ .indicator::before { width: 70%; height: var(--brutal-border-width); top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(45deg); } .indicator::after { width: 70%; height: var(--brutal-border-width); top: 50%; left: 50%; transform: translate(-50%, -50%) rotate(-45deg); } /* Alternative: Square indicator (comment out X mark above and uncomment this) */ /* .indicator { width: 60%; height: 60%; background-color: var(--brutal-black); opacity: 0; transition: all var(--brutal-transition-base); } */ /* Label */ .label { font-family: var(--brutal-font-sans); font-weight: var(--brutal-font-medium); color: var(--brutal-black); cursor: pointer; transition: color var(--brutal-transition-base); } .sm .label { font-size: var(--brutal-text-sm); } .md .label { font-size: var(--brutal-text-base); } .lg .label { font-size: var(--brutal-text-lg); } /* States */ /* Checked state */ .input:checked + .radio .indicator { opacity: 1; } /* Hover state */ .container:not(.disabled):hover .radio { background-color: var(--brutal-gray-100); transform: translate(-1px, -1px); } .container:not(.disabled):hover .radio.withShadow { box-shadow: 5px 5px 0px var(--brutal-black); } .container:not(.disabled):hover .label { color: var(--brutal-gray-700); } /* Focus state */ .input:focus-visible + .radio { outline: var(--brutal-border-width) var(--brutal-border-style) var(--brutal-accent); outline-offset: 2px; background-color: var(--brutal-gray-100); } /* Active state */ .container:not(.disabled):active .radio { transform: translate(2px, 2px); } .container:not(.disabled):active .radio.withShadow { box-shadow: 2px 2px 0px var(--brutal-black); } /* Disabled state */ .disabled { cursor: not-allowed; opacity: 0.5; } .disabled .radio { cursor: not-allowed; background-color: var(--brutal-gray-300); } .disabled .label { cursor: not-allowed; color: var(--brutal-gray-500); } /* Error state */ .error .radio { border-color: var(--brutal-error); } .error .radio.withShadow { box-shadow: 4px 4px 0px var(--brutal-error); } .error:not(.disabled):hover .radio.withShadow { box-shadow: 5px 5px 0px var(--brutal-error); } .error .input:focus-visible + .radio { outline-color: var(--brutal-error); } .error .indicator::before, .error .indicator::after { background-color: var(--brutal-error); } /* Alternative: Square indicator error state */ /* .error .indicator { background-color: var(--brutal-error); } */ /* Keyboard navigation enhancement */ .input:focus-visible + .radio { transform: translate(-1px, -1px); } .input:focus-visible + .radio.withShadow { box-shadow: 5px 5px 0px var(--brutal-black); } /* Animation for selection */ @keyframes selectAnimation { 0% { transform: scale(0.8) rotate(-5deg); opacity: 0; } 50% { transform: scale(1.1) rotate(5deg); } 100% { transform: scale(1) rotate(0); opacity: 1; } } .input:checked + .radio .indicator { animation: selectAnimation var(--brutal-transition-base); } /* Checked state styling enhancement */ .checked .radio { border-width: var(--brutal-border-width-thick); }