import type { Component } from 'solid-js' import { createSignal, onCleanup } from 'solid-js' export interface HourglassSpinnerProps { class?: string } const statesNormal = [ 'i-ph:hourglass-duotone', 'i-ph:hourglass-high-duotone', 'i-ph:hourglass-medium-duotone', 'i-ph:hourglass-low-duotone', ] const statesFlipped = [ 'i-ph:hourglass-duotone', 'i-ph:hourglass-low-duotone', 'i-ph:hourglass-medium-duotone', 'i-ph:hourglass-high-duotone', ] const HourglassSpinner: Component = (props) => { const [frame, setFrame] = createSignal(0) const [flipCount, setFlipCount] = createSignal(0) let spinnerRef: HTMLDivElement | undefined const currentIcon = () => { const isFlipped = flipCount() % 2 === 1 const states = isFlipped ? statesFlipped : statesNormal return states[frame()] } const rotation = () => flipCount() * 180 const syncSpinnerEl = () => { if (!spinnerRef) return spinnerRef.className = `${currentIcon()} ${props.class ?? ''}` spinnerRef.style.transform = `rotate(${rotation()}deg)` } const interval = setInterval(() => { setFrame((prev) => { const next = (prev + 1) % statesNormal.length if (next === 0) setFlipCount(f => f + 1) return next }) syncSpinnerEl() }, 300) onCleanup(() => clearInterval(interval)) return (
(spinnerRef = el)} class={`${currentIcon()} ${props.class ?? ''}`} style={{ transform: `rotate(${rotation()}deg)`, transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)', }} /> ) } export default HourglassSpinner