67 / Scenes
Aurora Field
A drifting gradient backdrop for a hero or an empty state, built from the colours already in your theme rather than from a palette it brought with it.
Now in beta
Ship the interface you actually sketched
The colours come from your theme, so this panel looks like the rest of your application.
"use client"
import { AuroraField } from "mischief-ui/aurora-field"
export function AuroraFieldDemo() {
return (
<AuroraField className="border-border w-full max-w-xl rounded-[var(--radius)] border">
<div className="px-8 py-16 text-center">
<p className="text-muted-foreground text-xs font-semibold tracking-widest uppercase">
Now in beta
</p>
<h3 className="mt-3 text-3xl font-semibold text-balance">
Ship the interface you actually sketched
</h3>
<p className="text-muted-foreground mx-auto mt-3 max-w-sm text-sm">
The colours come from your theme, so this panel looks like the rest of
your application.
</p>
</div>
</AuroraField>
)
}Installation
Copy the source into your project, or keep it behind a package.
npx shadcn@latest add Tinkerers-Labs/mischief-ui/aurora-fieldimport { AuroraField } from "mischief-ui/aurora-field"Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.
"use client" import * as React from "react"import { RenderSurface, useThemeColors, type SurfaceColor,} from "@/registry/default/render-surface/render-surface"import { cn } from "@/lib/utils" export type AuroraFieldProps = React.HTMLAttributes<HTMLDivElement> & { /** * Theme custom properties or plain CSS colours. Fewer entries than blobs is * the usual case: the rest are derived by rotating the hue of these.Usage
export function Hero() {
return (
<AuroraField className="rounded-xl">
<div className="px-8 py-16 text-center">
<h1>Ship the interface you sketched</h1>
</div>
</AuroraField>
)
}Why one colour is the default
Most gradient backdrops ship with a palette, which means they look like the library they came from rather than like your application. This one takes --primary and derives the rest by rotating its hue, so a blue product gets a blue aurora and an orange one gets an orange aurora without being configured.
Pass more colours when you want them. Any entry that is not a custom property is used as a plain CSS colour, and if there are fewer colours than shapes the remainder are derived from the ones you gave.
<AuroraField colors={["--primary", "--ring"]} blobs={6} />What it costs to run
The field is drawn at a single device pixel per CSS pixel and then blurred by CSS. Blurring in the compositor is far cheaper than blurring in the canvas, and since the result is soft in every direction there is nothing for the extra resolution to show.
It also stops drawing as soon as it scrolls off screen, so a field behind a hero costs nothing once the reader has moved past it.
API
colorsstring[]Theme custom properties or CSS colours. Defaults to ["--primary"].blobsnumberHow many drifting shapes to draw. Defaults to 5.speednumberMultiplies the drift. Defaults to 1.spreadnumberHow much of the box each shape covers, as a fraction of the longest edge. Defaults to 0.55.opacitynumberStrength of each shape. Defaults to 0.85.pausedbooleanHolds the field still.childrenReactNodeRendered above the field. The field itself sits behind on its own layer and ignores the pointer.Accessibility
The field is decoration and is hidden from assistive technology. Children are ordinary markup above it, so a heading inside one is read exactly as it would be anywhere else. Under reduced motion the shapes are painted once and stop, which keeps the colour without the drift.