All components

Aura Blob

Default product-style background with two spring-animated radial blobs that smoothly follow the pointer. When the cursor leaves, the blobs stay in their last position instead of snapping back, and re-entry is softly blended.

Default
Full-surface purple / cyan glow; move the mouse to steer.

Props

Adjust the AuraBlob props without placing controls over the preview.

1"use client";
2
3import { useState } from "react";
4import { Input } from "@/components/ui/input";
5import { Label } from "@/components/ui/label";
6import { Slider } from "@/components/ui/slider";
7import { Switch } from "@/components/ui/switch";
8import { AuraBlob } from "@/registry/ui";
9
10type AuraBlobDemoProps = {
11 color: string;
12 secondaryColor: string;
13 intensity: number;
14 blur: string;
15 stiffness: number;
16 damping: number;
17 primarySize: string;
18 secondarySize: string;
19 secondaryLag: number;
20 returnToCenter: boolean;
21};
22
23const DEFAULT_PROPS: AuraBlobDemoProps = {
24 color: "oklch(0.62 0.22 285 / 0.5)",
25 secondaryColor: "oklch(0.68 0.18 200 / 0.38)",
26 intensity: 0.9,
27 blur: "72px",
28 stiffness: 110,
29 damping: 20,
30 primarySize: "min(88vw, 760px)",
31 secondarySize: "min(72vw, 560px)",
32 secondaryLag: 0.7,
33 returnToCenter: true,
34};
35
36function NumberControl({
37 label,
38 value,
39 min,
40 max,
41 step,
42 onChange,
43}: {
44 label: string;
45 value: number;
46 min: number;
47 max: number;
48 step: number;
49 onChange: (value: number) => void;
50}) {
51 return (
52 <div className="flex flex-col gap-2">
53 <Label className="flex items-center justify-between gap-3">
54 <span>{label}</span>
55 <span className="font-mono text-xs text-muted-foreground">{value}</span>
56 </Label>
57 <Slider
58 value={[value]}
59 min={min}
60 max={max}
61 step={step}
62 onValueChange={(next) => onChange(next[0] ?? value)}
63 />
64 </div>
65 );
66}
67
68function TextControl({
69 label,
70 value,
71 onChange,
72}: {
73 label: string;
74 value: string;
75 onChange: (value: string) => void;
76}) {
77 return (
78 <div className="flex flex-col gap-2">
79 <Label>{label}</Label>
80 <Input value={value} onChange={(event) => onChange(event.target.value)} />
81 </div>
82 );
83}
84
85export function AuraBlobDefaultExample() {
86 const [props, setProps] = useState<AuraBlobDemoProps>(DEFAULT_PROPS);
87
88 const updateProp = <Key extends keyof AuraBlobDemoProps>(
89 key: Key,
90 value: AuraBlobDemoProps[Key],
91 ) => {
92 setProps((current) => ({ ...current, [key]: value }));
93 };
94
95 return (
96 <div className="flex w-full min-w-0 flex-col gap-6">
97 <AuraBlob
98 {...props}
99 className="h-[80dvh] min-h-[420px] w-full rounded-xl border border-border/60 bg-muted/20"
100 />
101
102 <div className="rounded-xl border bg-card p-5">
103 <div className="mb-5 flex flex-col gap-1">
104 <h3 className="text-sm font-semibold">Props</h3>
105 <p className="text-sm text-muted-foreground">
106 Adjust the AuraBlob props without placing controls over the preview.
107 </p>
108 </div>
109
110 <div className="grid gap-5 md:grid-cols-2">
111 <TextControl
112 label="color"
113 value={props.color}
114 onChange={(value) => updateProp("color", value)}
115 />
116 <TextControl
117 label="secondaryColor"
118 value={props.secondaryColor}
119 onChange={(value) => updateProp("secondaryColor", value)}
120 />
121 <TextControl
122 label="blur"
123 value={props.blur}
124 onChange={(value) => updateProp("blur", value)}
125 />
126 <TextControl
127 label="primarySize"
128 value={props.primarySize}
129 onChange={(value) => updateProp("primarySize", value)}
130 />
131 <TextControl
132 label="secondarySize"
133 value={props.secondarySize}
134 onChange={(value) => updateProp("secondarySize", value)}
135 />
136 <NumberControl
137 label="intensity"
138 value={props.intensity}
139 min={0}
140 max={1}
141 step={0.1}
142 onChange={(value) => updateProp("intensity", value)}
143 />
144 <NumberControl
145 label="stiffness"
146 value={props.stiffness}
147 min={0}
148 max={1000}
149 step={1}
150 onChange={(value) => updateProp("stiffness", value)}
151 />
152 <NumberControl
153 label="damping"
154 value={props.damping}
155 min={0}
156 max={100}
157 step={1}
158 onChange={(value) => updateProp("damping", value)}
159 />
160 <NumberControl
161 label="secondaryLag"
162 value={props.secondaryLag}
163 min={0}
164 max={1}
165 step={0.1}
166 onChange={(value) => updateProp("secondaryLag", value)}
167 />
168 <div className="flex items-center justify-between gap-4 rounded-lg border bg-muted/20 px-4 py-3">
169 <Label htmlFor="aura-return-to-center">returnToCenter</Label>
170 <Switch
171 id="aura-return-to-center"
172 checked={props.returnToCenter}
173 onCheckedChange={(value) => updateProp("returnToCenter", value)}
174 />
175 </div>
176 </div>
177 </div>
178 </div>
179 );
180}

Installation & source

Install via the shadcn CLI or copy the registry files manually.

bash
npx shadcn@latest add @tt-ui/aura-blob

Props

NameTypeDefaultDescription
color / secondaryColorstringoklch purple / cyan tintsCSS colors for each radial gradient stop
intensitynumber0.90–1: how far blobs move toward the cursor from center
blurstring72pxBackdrop blur on the decorative stack
stiffness / dampingnumber110 / 20Motion spring tuning for the primary blob (secondary uses scaled values)
primarySize / secondarySizestringmin(88vw,760px) / min(72vw,560px)Blob diameters (any CSS length)
secondaryLagnumber0.7Secondary blob follow strength as a fraction of intensity
childrenReactNodeundefinedForeground content (z-10); glow stays pointer-events-none