Created
November 13, 2025 17:09
-
-
Save samselikoff/9fb5de58847381a9687de122d205b9c3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { ReactNode, useLayoutEffect, useRef } from 'react'; | |
| const keyframes = ` | |
| @keyframes spinner { | |
| 0% { opacity: 1; } | |
| 100% { opacity: 0; } | |
| } | |
| `; | |
| export default function Spinner({ | |
| loading = true, | |
| children, | |
| className, | |
| }: { | |
| loading?: boolean; | |
| children?: ReactNode; | |
| className?: string; | |
| }) { | |
| if (!loading) return children; | |
| const spinner = ( | |
| <span className={`relative inline-flex ${className ?? 'size-4'}`}> | |
| <style>{keyframes}</style> | |
| {Array.from(Array(8).keys()).map((i) => ( | |
| <Segment index={i} key={i} /> | |
| ))} | |
| </span> | |
| ); | |
| if (!children) return spinner; | |
| return ( | |
| <span className="relative flex items-center justify-center"> | |
| <span className="invisible">{children}</span> | |
| <span className="absolute inset-0 flex items-center justify-center"> | |
| {spinner} | |
| </span> | |
| </span> | |
| ); | |
| } | |
| const DURATION = 800; | |
| function Segment({ index }: { index: number }) { | |
| const ref = useRef<HTMLSpanElement>(null); | |
| useLayoutEffect(() => { | |
| const el = ref.current; | |
| if (!el) return; | |
| const original = (-(8 - index) / 8) * DURATION; | |
| const offset = -(Date.now() % DURATION); | |
| el.style.animationDelay = `${original + offset}ms`; | |
| }, [index]); | |
| return ( | |
| <span | |
| ref={ref} | |
| className="absolute top-0 left-[calc(50%-12.5%/2)] h-full w-[12.5%] before:block before:h-[30%] before:w-full before:rounded-full before:bg-current" | |
| style={{ | |
| transform: `rotate(${45 * index}deg)`, | |
| animation: `spinner ${DURATION}ms linear infinite`, | |
| }} | |
| /> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment