defuss-shadcn / Feedback & Status / spinner
SpinnerATM
An animated loading indicator. Pure CSS animation on an SVG element - no JavaScript required.
On this page (4)
§Default
Standard spinner at default size.
§Sizes
The full five-step scale via data-size - the default is 1rem, between sm and md.
§In Button
A loading button is a busy button: aria-busy="true" plus a .spinner child, in any variant - the spinner takes the button's text color and keeps turning. The last one is disabled as well: button.css deliberately freezes a disabled button's spinner (the dimmed button already says 'pending', a wheel spinning on a control you can't use would say 'working').
§CSS view file
Styles for the spinner component. Uses design tokens for colors, spacing, and radius.
@layer components { .spinner { width: 1rem; height: 1rem; animation: spinner-rotate 1s linear infinite; color: var(--muted-foreground); flex-shrink: 0; &[data-size="xs"] { width: 0.625rem; height: 0.625rem; } &[data-size="sm"] { width: 0.875rem; height: 0.875rem; } &[data-size="md"] { width: 1.25rem; height: 1.25rem; } &[data-size="lg"] { width: 1.5rem; height: 1.5rem; } &[data-size="xl"] { width: 2rem; height: 2rem; } } @keyframes spinner-rotate { to { transform: rotate(360deg); } }}/* Accessibility: suppress motion for users who request it (REQUIRED for all components - AGENTS.md "Accessibility CSS"). Near-zero duration instead of `none` keeps transitionend/animationend (and discrete display flips) firing so JS state machines that await them keep working. */@media (prefers-reduced-motion: reduce) { @layer components { .spinner, .spinner *, .spinner::before, .spinner::after, .spinner *::before, .spinner *::after, .spinner::backdrop { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; } }}Comments, ideas or improvements? Edit this page's source on GitHub