Skip to content
edmi-ui

Spinner

Shows that something is loading. Inherits color and sizes with the surrounding text.

StackBlitz ↗StackBlitz ↗StackBlitz ↗
Rebalancing
Rebalancing
Rebalancing
Terminal window
npx shadcn@latest add @edmi-ui/spinner
Terminal window
pnpm dlx shadcn@latest add @edmi-ui/spinner
Terminal window
yarn dlx shadcn@latest add @edmi-ui/spinner
Terminal window
bunx shadcn@latest add @edmi-ui/spinner

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-vue@latest add @edmi-ui/spinner
Terminal window
pnpm dlx shadcn-vue@latest add @edmi-ui/spinner
Terminal window
yarn dlx shadcn-vue@latest add @edmi-ui/spinner
Terminal window
bunx shadcn-vue@latest add @edmi-ui/spinner

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/spinner.json
Terminal window
pnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/spinner.json
Terminal window
yarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/spinner.json
Terminal window
bunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/spinner.json

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
<div className="flex flex-wrap items-center gap-4">
<Spinner />
<Spinner className="size-6" />
<Button disabled variant="secondary">
<Spinner />
Deploying vault
</Button>
<Badge variant="brand">
<Spinner />
Rebalancing
</Badge>
</div>
<script setup lang="ts">
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
</script>
<template>
<div class="flex flex-wrap items-center gap-4">
<Spinner />
<Spinner class="size-6" />
<Button disabled variant="secondary">
<Spinner />
Deploying vault
</Button>
<Badge variant="brand">
<Spinner />
Rebalancing
</Badge>
</div>
</template>
<script lang="ts">
import { Badge } from "$lib/components/ui/badge";
import { Button } from "$lib/components/ui/button";
import { Spinner } from "$lib/components/ui/spinner";
</script>
<div class="flex flex-wrap items-center gap-4">
<Spinner />
<Spinner class="size-6" />
<Button disabled variant="secondary">
<Spinner />
Deploying vault
</Button>
<Badge variant="brand">
<Spinner />
Rebalancing
</Badge>
</div>
registry/ui/spinner.tsx
import { cn } from "cn";
import type * as React from "react";
import { SpinnerIcon } from "@phosphor-icons/react";
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
return (
<SpinnerIcon
data-slot="spinner"
role="status"
aria-label="Loading"
className={cn("size-4 animate-spin", className)}
{...props}
/>
);
}
export { Spinner };
registry/ui/spinner/Spinner.vue
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { Loader2Icon } from '@lucide/vue'
import { cn } from '@/registry/edmi/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<Loader2Icon
data-slot="spinner"
role="status"
aria-label="Loading"
:class="cn('size-4 animate-spin', props.class)"
/>
</template>
registry/ui/spinner/index.ts
export { default as Spinner } from "./Spinner.vue";
src/lib/registry/ui/spinner/spinner.svelte
<script lang="ts">
import SpinnerIcon from "phosphor-svelte/lib/Spinner";
import { cn } from "$lib/utils.js";
import type { SVGAttributes } from "svelte/elements";
let {
class: className,
role = "status",
// we add name, color, and stroke for compatibility with different icon libraries props.
// only forward them when set, otherwise `stroke: undefined` overrides the icon's `currentColor`
name,
color,
stroke,
className: legacyClassName,
"aria-label": ariaLabel = "Loading",
...restProps
}: SVGAttributes<SVGSVGElement> = $props();
</script>
<SpinnerIcon
data-slot="spinner"
{role}
{...name != null ? { name } : {}}
{...color != null ? { color } : {}}
{...stroke != null ? { stroke } : {}}
{...legacyClassName != null ? { className: legacyClassName } : {}}
aria-label={ariaLabel}
class={cn("size-4 animate-spin", className)}
{...restProps}
/>
src/lib/registry/ui/spinner/index.ts
export { default as Spinner } from "./spinner.svelte";
Prop Type Default
className string size-4 (use size-* to resize)

Renders a lucide Loader2Icon with role="status" and aria-label="Loading".

  • None; same anatomy as shadcn. Place inside Button/Badge and the icon sizing is picked up.