knot-ui
componentflip-buttonsource: ok · hit
Flip Button
A button that flips between a light front face and dark back face in 3D on hover.
npx shadcn add "https://knot-ui.trupal.me/r/flip-button.json"free
Visual style
3ddark-futuristic
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Files1 · source cached 10/8/2026, 5:46:33 PM
components/library/flip-button.tsx
import React from "react";
interface FlipButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children?: React.ReactNode;
frontClassName?: string;
backClassName?: string;
}
export const FlipButton = ({
children = "Button",
className = "",
frontClassName = "",
backClassName = "",
disabled = false,
type = "button",
onClick,
...rest
}: FlipButtonProps) => {
return (
<button
type={type}
disabled={disabled}
onClick={onClick}
className={`relative group [perspective:1000px] [transform-style:preserve-3d] rounded-md disabled:opacity-50 disabled:pointer-events-none ${className}`}
{...rest}
>
{/* ghost sizer — invisible, just drives button dimensions */}
<span className="invisible text-xl font-bold px-5 py-2 block">{children}</span>
{/* front face */}
<span className={`absolute inset-0 bg-neutral-100 text-black text-xl font-bold rounded-md flex items-center justify-center scale-100 group-hover:scale-50 [transform:rotateX(0deg)] group-hover:[transform:rotateX(90deg)] group-hover:opacity-0 origin-top transition-all duration-300 ${frontClassName}`}>
{children}
</span>
{/* back face */}
<span className={`absolute inset-0 bg-neutral-950 text-white text-xl font-bold rounded-md flex items-center justify-center [transform:rotateX(-90deg)] opacity-0 group-hover:[transform:rotateX(0deg)] group-hover:opacity-100 origin-bottom transition-all duration-300 group-hover:scale-100 scale-75 ${backClassName}`}>
{children}
</span>
</button>
);
};
FlipButton.displayName = "FlipButton";