GitHub

Wave

A wave of bars for audio, sync, or progress-adjacent loading.

Loading
import { Wave } from "@/components/loading-ui/wave";

export function WaveDemo() {

Installation

pnpm dlx shadcn@latest add @loading-ui/wave

Usage

import { Wave } from "@/components/loading-ui/wave";
<Wave className="h-12 w-24" />

Customization

Wave uses five fixed bars with different heights, so it reads like audio, voice, or stream activity instead of a generic progress meter. It inherits currentColor, and the animation can be tuned with --duration and --delay.

Size

Set both height and width. The internal bars use percentages, so the component stays balanced at compact and larger sizes.

LoadingLoadingLoading
import { Wave } from "@/components/loading-ui/wave";

export function WaveSize() {

Color

The bars use currentColor, which makes direct text utilities and inherited foreground colors enough for most layouts.

LoadingLoadingLoading
import { Wave } from "@/components/loading-ui/wave";

export function WaveColor() {

Duration

Set --duration to make the wave feel quick and responsive or calm and ambient.

LoadingLoadingLoading
import { Wave } from "@/components/loading-ui/wave";

export function WaveDuration() {

Stagger

Set --delay to tighten or loosen the offset between bars.

LoadingLoadingLoading
import { Wave } from "@/components/loading-ui/wave";

export function WaveStagger() {

Examples

These examples use Wave for live audio and stream-like states where the shape adds meaning without needing extra text.

Button

Inside buttons, the wave works well when the action is listening, capturing, or processing a live stream.

import { Button } from "@/components/ui/button";
import { Wave } from "@/components/loading-ui/wave";

Badge

Badges can show live or listening states without taking much space.

LoadingLiveLoadingListeningLoadingMixing
import { Badge } from "@/components/ui/badge";
import { Wave } from "@/components/loading-ui/wave";

Input Group

Input groups keep voice capture status attached to the field that receives the result.

LoadingListening
import {
  InputGroup,
  InputGroupAddon,