Buttons
PrismButton
A band of rainbow light runs across a glass button and follows the pointer, like light through a prism.
Download
- React
- Tailwind CSS v4
- motion
components/ui/prism-button.tsx
"use client";
import type { CSSProperties, ReactNode } from "react";
import { useReducedMotion } from "motion/react";
type PrismButtonProps = {
children: ReactNode;
className?: string;
onClick?: () => void;
/** Spectrum colours, left to right. */
colors?: string[];
};
/* PrismButton: a band of rainbow light runs across the glass, following the pointer like light through a prism. */
export function PrismButton({
children,
className = "rounded-xl border border-white/15 bg-white/5 px-9 py-4 text-[15px] font-medium text-white",
onClick,
colors = ["#ff6b8b", "#ffb86b", "#fff36b", "#6bffb0", "#6bd5ff", "#a78bfa"],
}: PrismButtonProps) {
const reduce = useReducedMotion();
const stops = colors.map((c, i) => `${c} calc(var(--px) + ${-25 + (50 * i) / (colors.length - 1)}%)`).join(", ");
return (
<button
type="button"
onClick={onClick}
onPointerMove={(e) => {
if (reduce) return;
const b = e.currentTarget.getBoundingClientRect();
e.currentTarget.style.setProperty("--px", `${((e.clientX - b.left) / b.width) * 100}%`);
}}
className={`group relative isolate overflow-hidden ${className}`}
style={{ "--px": "50%" } as CSSProperties}
>
<span
aria-hidden
className="pointer-events-none absolute inset-0 -z-10 opacity-30 mix-blend-screen blur-md transition-opacity duration-300 group-hover:opacity-90 group-focus-visible:opacity-90"
style={{ background: `linear-gradient(105deg, transparent calc(var(--px) - 40%), ${stops}, transparent calc(var(--px) + 40%))` }}
/>
<span className="relative">{children}</span>
</button>
);
}
1. Install the dependency.
npm i motion2. Paste the Code tab into
components/ui/prism-button.tsx. The styles are Tailwind CSS v4 classes.3. Use it. This is the preview above:
app/prism-button-demo.tsx
import { PrismButton } from "@/components/ui/prism-button"; export default function PrismButtonExample() { return ( <div className="grid h-full place-items-center bg-[radial-gradient(circle_at_50%_60%,#1d1a33,#0d0c14_70%)]"> <PrismButton>See the spectrum</PrismButton> </div> ); }
Props
| Name | Type | Default | What it does |
|---|---|---|---|
| children | ReactNode | — | Button label. |
| onClick | () => void | — | Click handler. |
| colors | string[] | 6 spectrum colours | Spectrum colours, left to right. |
| className | string | glass block | Replaces the default look. |