<script lang="ts">
  type SpinnerType = "dots" | "circle" | "pulse" | "stars" | "orbit";

  let { type = "dots", speed = 100, classes = "" } = $props<{
    type?: SpinnerType;
    speed?: number;
    classes?: string;
  }>();

  const sequences = {
    dots: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
    circle: ["◴", "◷", "◶", "◵"],
    pulse: ["◉", "◎", "○", "◎"],
    stars: ["·", "✢", "✳", "✶", "✻", "✽"],
    orbit: ["⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"],
  };

  let frame = $state(0);
  let chars = $derived(sequences[type as SpinnerType] ?? sequences.dots);

  $effect(() => {
    frame = 0;
    const interval = setInterval(() => {
      frame = (frame + 1) % chars.length;
    }, speed);
    return () => clearInterval(interval);
  });
</script>

<span class="inline-block {classes}" aria-hidden="true">{chars[frame]}</span>
