Primitives
Spinner
Ring, dots, wave; five sizes; takes the text colour unless tone="brand". Keeps turning, slowly, under reduced motion.
ring
LoadingLoadingLoadingLoadingLoadingLoadingdots
LoadingLoadingLoadingLoadingLoadingLoadingwave
LoadingLoadingLoadingLoadingLoadingLoadingspinner.tsx
"use client";
import { Button, Spinner } from "@waveinno/ui";
export default function SpinnerDemo() {
return (
<div className="space-y-6">
{(["ring", "dots", "wave"] as const).map((variant) => (
<div key={variant} className="flex flex-wrap items-center gap-6">
<p className="w-12 text-[12px] text-muted">{variant}</p>
{(["xs", "sm", "md", "lg", "xl"] as const).map((size) => (
<Spinner key={size} variant={variant} size={size} tone="brand" />
))}
<span className="text-muted">
<Spinner variant={variant} size="md" />
</span>
</div>
))}
<div className="flex flex-wrap items-center gap-3">
<Button disabled>
<Spinner size="sm" /> Saving
</Button>
<Button variant="secondary" disabled>
<Spinner size="sm" variant="dots" /> Connecting to gate
</Button>
</div>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
your-component.tsx
import { Button, Spinner } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<Spinner>
src/components/ui/spinner.tsx| Prop | Type | Default | Description |
|---|---|---|---|
variant | "ring" | "dots" | "wave" | "ring" | |
size | keyof typeof SIZE | "md" | |
tone | "current" | "brand" | "current" | `current` follows the text colour; `brand` uses the primary (the gradient, for ring). |
label | string | "Loading" | |
className | string | — |
<Button>
src/components/ui/button.tsx| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | |
loading | boolean | — |
Also takes ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>.
Install#
If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.
$ npm install @waveinno/ui