Skip to content

[FIX] Adjustments on Shiny and Rainbow Buttons #671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions __registry__/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4348,6 +4348,29 @@ export const Index: Record<string, any> = {
}),
meta: undefined,
},
"rainbow-button-demo-2": {
name: "rainbow-button-demo-2",
description: "Example showing an animated button with rainbow effect.",
type: "registry:example",
registryDependencies: ["https://magicui.design/r/rainbow-button"],
files: [
{
path: "registry/example/rainbow-button-demo-2.tsx",
type: "registry:example",
target: "components/rainbow-button-demo-2.tsx",
},
],
component: React.lazy(async () => {
const mod = await import("@/registry/example/rainbow-button-demo-2.tsx");
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === "function" || typeof mod[key] === "object",
) || item.name;
return { default: mod.default || mod[exportName] };
}),
meta: undefined,
},
"interactive-hover-button-demo": {
name: "interactive-hover-button-demo",
description: "Example showing an interactive button with hover effects.",
Expand Down
16 changes: 12 additions & 4 deletions content/docs/components/rainbow-button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Add the following animations to your global CSS file.

</Tabs>

## Examples

### Outline Variant

<ComponentPreview name="rainbow-button-demo-2" />

## Usage

```tsx
Expand All @@ -85,7 +91,9 @@ import { RainbowButton } from "@/components/magicui/rainbow-button";

## Props

| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | --------------------------------------------------- |
| `children` | `React.ReactNode` | `-` | The content to be displayed inside the button. |
| `className` | `string` | `-` | Additional CSS classes to be applied to the button. |
| Prop | Type | Default | Description |
| ----------- | ------------------------------------- | ----------- | --------------------------------------------------- |
| `children` | `React.ReactNode` | `-` | The content to be displayed inside the button. |
| `className` | `string` | `-` | Additional CSS classes to be applied to the button. |
| `variant` | `"default" \| "outline"` | `"default"` | The variant of the button. |
| `size` | `"default" \| "sm" \| "lg" \| "icon"` | `"default"` | The size of the button. |
18 changes: 18 additions & 0 deletions public/r/rainbow-button-demo-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "rainbow-button-demo-2",
"type": "registry:example",
"title": "Rainbow Button Demo 2",
"description": "Example showing an animated button with rainbow effect.",
"registryDependencies": [
"https://magicui.design/r/rainbow-button"
],
"files": [
{
"path": "registry/example/rainbow-button-demo-2.tsx",
"content": "import { RainbowButton } from \"@/registry/magicui/rainbow-button\";\n\nexport default function RainbowButtonDemo() {\n return <RainbowButton variant=\"outline\">Get Unlimited Access</RainbowButton>;\n}\n",
"type": "registry:example",
"target": "components/rainbow-button-demo-2.tsx"
}
]
}
2 changes: 1 addition & 1 deletion public/r/rainbow-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"files": [
{
"path": "registry/magicui/rainbow-button.tsx",
"content": "import { cn } from \"@/lib/utils\";\nimport React from \"react\";\n\ninterface RainbowButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nexport const RainbowButton = React.forwardRef<\n HTMLButtonElement,\n RainbowButtonProps\n>(({ children, className, ...props }, ref) => {\n return (\n <button\n ref={ref}\n className={cn(\n \"group relative inline-flex h-11 animate-rainbow cursor-pointer items-center justify-center rounded-xl border-0 bg-[length:200%] px-8 py-2 font-medium text-primary-foreground transition-colors [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.08*1rem)_solid_transparent] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\",\n // before styles\n \"before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:[filter:blur(calc(0.8*1rem))]\",\n // light mode colors\n \"bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]\",\n // dark mode colors\n \"dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n});\n\nRainbowButton.displayName = \"RainbowButton\";\n",
"content": "import { cn } from \"@/lib/utils\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, VariantProps } from \"class-variance-authority\";\nimport React from \"react\";\n\ninterface RainbowButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nconst rainbowButtonVariants = cva(\n \"relative cursor-pointer transition-all inline-flex items-center justify-center gap-2 shrink-0 text-sm font-medium whitespace-nowrap rounded-sm outline-none focus-visible:ring-[3px] aria-invalid:border-destructive disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"group relative animate-rainbow cursor-pointer border-0 bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] bg-[length:200%] text-primary-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.08*1rem)_solid_transparent] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] before:[filter:blur(calc(0.8*1rem))] dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))]\",\n outline:\n \"group relative animate-rainbow cursor-pointer border-0 border-input\",\n // default:\n // \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n // \"bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] bg-[length:200%] text-primary-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.08*1rem)_solid_transparent] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] before:[filter:blur(calc(0.8*1rem))] dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))]\",\n // outline:\n // \"border shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n // \"border-input bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] bg-[length:200%] px-4 text-foreground shadow-sm [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.08*1rem)_solid_transparent] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] before:[filter:blur(calc(0.8*1rem))] dark:bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))]\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n sm: \"h-8 rounded-xl px-3 text-xs\",\n lg: \"h-11 rounded-xl px-8\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\ninterface RainbowButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof rainbowButtonVariants> {\n asChild?: boolean;\n}\n\nconst RainbowButton = React.forwardRef<HTMLButtonElement, RainbowButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n className={cn(rainbowButtonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n }\n);\n\nRainbowButton.displayName = \"RainbowButton\";\n\nexport { RainbowButton, rainbowButtonVariants, type RainbowButtonProps };\n",
"type": "registry:ui",
"target": "components/magicui/rainbow-button.tsx"
}
Expand Down
16 changes: 16 additions & 0 deletions public/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -3189,6 +3189,22 @@
}
]
},
{
"name": "rainbow-button-demo-2",
"type": "registry:example",
"title": "Rainbow Button Demo 2",
"description": "Example showing an animated button with rainbow effect.",
"registryDependencies": [
"https://magicui.design/r/rainbow-button"
],
"files": [
{
"path": "registry/example/rainbow-button-demo-2.tsx",
"type": "registry:example",
"target": "components/rainbow-button-demo-2.tsx"
}
]
},
{
"name": "interactive-hover-button-demo",
"type": "registry:example",
Expand Down
16 changes: 16 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -3189,6 +3189,22 @@
}
]
},
{
"name": "rainbow-button-demo-2",
"type": "registry:example",
"title": "Rainbow Button Demo 2",
"description": "Example showing an animated button with rainbow effect.",
"registryDependencies": [
"https://magicui.design/r/rainbow-button"
],
"files": [
{
"path": "registry/example/rainbow-button-demo-2.tsx",
"type": "registry:example",
"target": "components/rainbow-button-demo-2.tsx"
}
]
},
{
"name": "interactive-hover-button-demo",
"type": "registry:example",
Expand Down
5 changes: 5 additions & 0 deletions registry/example/rainbow-button-demo-2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { RainbowButton } from "@/registry/magicui/rainbow-button";

export default function RainbowButtonDemo() {
return <RainbowButton variant="outline">Get Unlimited Access</RainbowButton>;
}
77 changes: 54 additions & 23 deletions registry/magicui/rainbow-button.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,62 @@
import { cn } from "@/lib/utils";
import { Slot } from "@radix-ui/react-slot";
import { cva, VariantProps } from "class-variance-authority";
import React from "react";

interface RainbowButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}

export const RainbowButton = React.forwardRef<
HTMLButtonElement,
RainbowButtonProps
>(({ children, className, ...props }, ref) => {
return (
<button
ref={ref}
className={cn(
"group relative inline-flex h-11 animate-rainbow cursor-pointer items-center justify-center rounded-xl border-0 bg-[length:200%] px-8 py-2 font-medium text-primary-foreground transition-colors [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.08*1rem)_solid_transparent] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
// before styles
"before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:[filter:blur(calc(0.8*1rem))]",
// light mode colors
"bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]",
// dark mode colors
"dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))]",
className,
)}
{...props}
>
{children}
</button>
);
});
const rainbowButtonVariants = cva(
cn(
"relative cursor-pointer group transition-all animate-rainbow",
"inline-flex items-center justify-center gap-2 shrink-0",
"rounded-sm outline-none focus-visible:ring-[3px] aria-invalid:border-destructive",
"text-sm font-medium whitespace-nowrap",
"disabled:pointer-events-none disabled:opacity-50",
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
),
{
variants: {
variant: {
default:
"border-0 bg-[linear-gradient(#121213,#121213),linear-gradient(#121213_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] bg-[length:200%] text-primary-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] [border:calc(0.125rem)_solid_transparent] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] before:[filter:blur(0.75rem)] dark:bg-[linear-gradient(#fff,#fff),linear-gradient(#fff_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))]",
outline:
"border border-input border-b-transparent bg-[linear-gradient(#ffffff,#ffffff),linear-gradient(#ffffff_50%,rgba(18,18,19,0.6)_80%,rgba(18,18,19,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] bg-[length:200%] text-accent-foreground [background-clip:padding-box,border-box,border-box] [background-origin:border-box] before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-1/5 before:w-3/5 before:-translate-x-1/2 before:animate-rainbow before:bg-[linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))] before:[filter:blur(0.75rem)] dark:bg-[linear-gradient(#0a0a0a,#0a0a0a),linear-gradient(#0a0a0a_50%,rgba(255,255,255,0.6)_80%,rgba(0,0,0,0)),linear-gradient(90deg,hsl(var(--color-1)),hsl(var(--color-5)),hsl(var(--color-3)),hsl(var(--color-4)),hsl(var(--color-2)))]",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-xl px-3 text-xs",
lg: "h-11 rounded-xl px-8",
icon: "size-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);

interface RainbowButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof rainbowButtonVariants> {
asChild?: boolean;
}

const RainbowButton = React.forwardRef<HTMLButtonElement, RainbowButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
data-slot="button"
className={cn(rainbowButtonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);

RainbowButton.displayName = "RainbowButton";

export { RainbowButton, rainbowButtonVariants, type RainbowButtonProps };
4 changes: 2 additions & 2 deletions registry/magicui/shiny-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const ShinyButton = React.forwardRef<
<motion.button
ref={ref}
className={cn(
"relative rounded-lg px-6 py-2 font-medium backdrop-blur-xl transition-shadow duration-300 ease-in-out hover:shadow dark:bg-[radial-gradient(circle_at_50%_0%,var(--primary)/10%_0%,transparent_60%)] dark:hover:shadow-[0_0_20px_var(--primary)/10%]",
"relative cursor-pointer rounded-lg px-6 py-2 font-medium backdrop-blur-xl border transition-shadow duration-300 ease-in-out hover:shadow dark:bg-[radial-gradient(circle_at_50%_0%,var(--primary)/10%_0%,transparent_60%)] dark:hover:shadow-[0_0_20px_var(--primary)/10%]",
className,
)}
{...animationProps}
Expand All @@ -64,7 +64,7 @@ export const ShinyButton = React.forwardRef<
"linear-gradient(-75deg,var(--primary)/10% calc(var(--x)+20%),var(--primary)/50% calc(var(--x)+25%),var(--primary)/10% calc(var(--x)+100%))",
}}
className="absolute inset-0 z-10 block rounded-[inherit] p-px"
></span>
/>
</motion.button>
);
});
Expand Down
14 changes: 14 additions & 0 deletions registry/registry-examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,20 @@ export const examples: Registry["items"] = [
},
],
},
{
name: "rainbow-button-demo-2",
type: "registry:example",
title: "Rainbow Button Demo 2",
description: "Example showing an animated button with rainbow effect.",
registryDependencies: ["https://magicui.design/r/rainbow-button"],
files: [
{
path: "registry/example/rainbow-button-demo-2.tsx",
type: "registry:example",
target: "components/rainbow-button-demo-2.tsx",
},
],
},
{
name: "interactive-hover-button-demo",
type: "registry:example",
Expand Down