diff --git a/content/docs/components/animated-subscribe-button.mdx b/content/docs/components/animated-subscribe-button.mdx index 5f17aa9b9..c40c78740 100644 --- a/content/docs/components/animated-subscribe-button.mdx +++ b/content/docs/components/animated-subscribe-button.mdx @@ -42,13 +42,11 @@ npx shadcn@latest add "https://magicui.design/r/animated-subscribe-button" ## Props -| Prop | Type | Default | Description | -| ----------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `buttonColor` | `string` | `-` | The accent color for the button. This allows you to set a custom color that matches your brand's theme. | -| `buttonTextColor` | `string` | `-` | The color of the button text. This allows you to ensure the text is visible and matches your desired color scheme. | -| `subscribeStatus` | `boolean` | `-` | A boolean flag to check the condition for the button. This property can be used to toggle the button's state, such as subscribed or unsubscribed. | -| `initialText` | `string` | `-` | The initial text displayed on the button. This is useful for setting a default label when the button first appears. | -| `changeText` | `string` | `-` | The final text displayed on the button after an action has been taken. This can be used to indicate a state change, such as from "Subscribe" to "Subscribed". | +| Prop | Type | Default | Description | +| ----------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `subscribeStatus` | `boolean` | `false` | A boolean flag to check the condition for the button. This property can be used to toggle the button's state, such as subscribed or unsubscribed. | +| `children` | `React.ReactNode` | `-` | The content to be displayed inside the button. Should contain two children - first for unsubscribed state and second for subscribed state. | +| `className` | `string` | `-` | Optional class name to be applied to the button for custom styling. | ## Credits diff --git a/public/r/styles/default/animated-subscribe-button.json b/public/r/styles/default/animated-subscribe-button.json index bddefac75..fb26aba15 100644 --- a/public/r/styles/default/animated-subscribe-button.json +++ b/public/r/styles/default/animated-subscribe-button.json @@ -7,7 +7,7 @@ "files": [ { "path": "magicui/animated-subscribe-button.tsx", - "content": "\"use client\";\n\nimport { AnimatePresence, motion } from \"motion/react\";\nimport React, { useState } from \"react\";\n\ninterface AnimatedSubscribeButtonProps {\n buttonColor: string;\n buttonTextColor?: string;\n subscribeStatus: boolean;\n initialText: React.ReactElement | string;\n changeText: React.ReactElement | string;\n}\n\nexport const AnimatedSubscribeButton: React.FC<\n AnimatedSubscribeButtonProps\n> = ({\n buttonColor,\n subscribeStatus,\n buttonTextColor,\n changeText,\n initialText,\n}) => {\n const [isSubscribed, setIsSubscribed] = useState(subscribeStatus);\n\n return (\n \n {isSubscribed ? (\n setIsSubscribed(false)}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n >\n \n {changeText}\n \n \n ) : (\n setIsSubscribed(true)}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n >\n \n {initialText}\n \n \n )}\n \n );\n};\n", + "content": "\"use client\";\n\nimport { HTMLMotionProps } from \"motion/react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport React, { useState } from \"react\";\n\ninterface AnimatedSubscribeButtonProps extends HTMLMotionProps<\"button\"> {\n buttonColor: string;\n buttonTextColor?: string;\n subscribeStatus: boolean;\n initialText: React.ReactElement | string;\n changeText: React.ReactElement | string;\n ref?: React.Ref;\n}\n\nexport const AnimatedSubscribeButton = React.forwardRef<\n HTMLButtonElement,\n AnimatedSubscribeButtonProps\n>(\n (\n {\n buttonColor,\n subscribeStatus,\n buttonTextColor,\n changeText,\n initialText,\n onClick,\n ...props\n },\n ref\n ) => {\n const [isSubscribed, setIsSubscribed] = useState(subscribeStatus);\n\n return (\n \n {isSubscribed ? (\n ) => {\n setIsSubscribed(false);\n onClick?.(e);\n }}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n {...props}\n >\n \n {changeText}\n \n \n ) : (\n {\n setIsSubscribed(true);\n onClick?.(e);\n }}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n {...props}\n >\n \n {initialText}\n \n \n )}\n \n );\n }\n);\n\nAnimatedSubscribeButton.displayName = \"AnimatedSubscribeButton\";\n", "type": "registry:ui", "target": "" } diff --git a/public/r/styles/default/interactive-hover-button.json b/public/r/styles/default/interactive-hover-button.json index 719c8380d..0c488f690 100644 --- a/public/r/styles/default/interactive-hover-button.json +++ b/public/r/styles/default/interactive-hover-button.json @@ -1,9 +1,7 @@ { "name": "interactive-hover-button", "type": "registry:ui", - "dependencies": [ - "lucide-react" - ], + "dependencies": ["lucide-react"], "files": [ { "path": "magicui/interactive-hover-button.tsx", @@ -12,4 +10,4 @@ "target": "" } ] -} \ No newline at end of file +} diff --git a/public/r/styles/default/pulsating-button.json b/public/r/styles/default/pulsating-button.json index 9d9cb9957..79ba9cadc 100644 --- a/public/r/styles/default/pulsating-button.json +++ b/public/r/styles/default/pulsating-button.json @@ -4,7 +4,7 @@ "files": [ { "path": "magicui/pulsating-button.tsx", - "content": "\"use client\";\n\nimport React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface PulsatingButtonProps\n extends React.ButtonHTMLAttributes {\n pulseColor?: string;\n duration?: string;\n}\n\nexport default function PulsatingButton({\n className,\n children,\n pulseColor = \"#0096ff\",\n duration = \"1.5s\",\n ...props\n}: PulsatingButtonProps) {\n return (\n \n
{children}
\n
\n \n );\n}\n", + "content": "\"use client\";\n\nimport React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface PulsatingButtonProps\n extends React.ButtonHTMLAttributes {\n pulseColor?: string;\n duration?: string;\n}\n\nexport const PulsatingButton = React.forwardRef<\n HTMLButtonElement,\n PulsatingButtonProps\n>(\n (\n {\n className,\n children,\n pulseColor = \"#0096ff\",\n duration = \"1.5s\",\n ...props\n },\n ref,\n ) => {\n return (\n \n
{children}
\n
\n \n );\n },\n);\n\nPulsatingButton.displayName = \"PulsatingButton\";\n", "type": "registry:ui", "target": "" } diff --git a/public/r/styles/default/rainbow-button.json b/public/r/styles/default/rainbow-button.json index ff3fe9c49..b117e8b09 100644 --- a/public/r/styles/default/rainbow-button.json +++ b/public/r/styles/default/rainbow-button.json @@ -4,7 +4,7 @@ "files": [ { "path": "magicui/rainbow-button.tsx", - "content": "import React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\ninterface RainbowButtonProps\n extends React.ButtonHTMLAttributes {}\n\nexport function RainbowButton({\n children,\n className,\n ...props\n}: RainbowButtonProps) {\n return (\n \n {children}\n \n );\n}\n", + "content": "\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface RainbowButtonProps\n extends React.ButtonHTMLAttributes {}\n\nexport const RainbowButton = React.forwardRef<\n HTMLButtonElement,\n RainbowButtonProps\n>(({ children, className, ...props }, ref) => {\n return (\n \n {children}\n \n );\n});\n\nRainbowButton.displayName = \"RainbowButton\";\n", "type": "registry:ui", "target": "" } diff --git a/public/r/styles/default/ripple-button.json b/public/r/styles/default/ripple-button.json index c3d396c63..80ec50de7 100644 --- a/public/r/styles/default/ripple-button.json +++ b/public/r/styles/default/ripple-button.json @@ -4,7 +4,7 @@ "files": [ { "path": "magicui/ripple-button.tsx", - "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport React, { MouseEvent, useEffect, useState } from \"react\";\n\ninterface RippleButtonProps\n extends React.ButtonHTMLAttributes {\n rippleColor?: string;\n duration?: string;\n}\n\nconst RippleButton = React.forwardRef(\n (\n {\n className,\n children,\n rippleColor = \"#ffffff\",\n duration = \"600ms\",\n onClick,\n ...props\n },\n ref,\n ) => {\n const [buttonRipples, setButtonRipples] = useState<\n Array<{ x: number; y: number; size: number; key: number }>\n >([]);\n\n const handleClick = (event: MouseEvent) => {\n createRipple(event);\n onClick?.(event);\n };\n\n const createRipple = (event: MouseEvent) => {\n const button = event.currentTarget;\n const rect = button.getBoundingClientRect();\n const size = Math.max(rect.width, rect.height);\n const x = event.clientX - rect.left - size / 2;\n const y = event.clientY - rect.top - size / 2;\n\n const newRipple = { x, y, size, key: Date.now() };\n setButtonRipples((prevRipples) => [...prevRipples, newRipple]);\n };\n\n useEffect(() => {\n if (buttonRipples.length > 0) {\n const lastRipple = buttonRipples[buttonRipples.length - 1];\n const timeout = setTimeout(() => {\n setButtonRipples((prevRipples) =>\n prevRipples.filter((ripple) => ripple.key !== lastRipple.key),\n );\n }, parseInt(duration));\n return () => clearTimeout(timeout);\n }\n }, [buttonRipples, duration]);\n\n return (\n \n
{children}
\n \n {buttonRipples.map((ripple) => (\n \n ))}\n \n \n );\n },\n);\n\nRippleButton.displayName = \"RippleButton\";\n\nexport default RippleButton;\n", + "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport React, { MouseEvent, useEffect, useState } from \"react\";\n\ninterface RippleButtonProps\n extends React.ButtonHTMLAttributes {\n rippleColor?: string;\n duration?: string;\n}\n\nexport const RippleButton = React.forwardRef<\n HTMLButtonElement,\n RippleButtonProps\n>(\n (\n {\n className,\n children,\n rippleColor = \"#ffffff\",\n duration = \"600ms\",\n onClick,\n ...props\n },\n ref,\n ) => {\n const [buttonRipples, setButtonRipples] = useState<\n Array<{ x: number; y: number; size: number; key: number }>\n >([]);\n\n const handleClick = (event: MouseEvent) => {\n createRipple(event);\n onClick?.(event);\n };\n\n const createRipple = (event: MouseEvent) => {\n const button = event.currentTarget;\n const rect = button.getBoundingClientRect();\n const size = Math.max(rect.width, rect.height);\n const x = event.clientX - rect.left - size / 2;\n const y = event.clientY - rect.top - size / 2;\n\n const newRipple = { x, y, size, key: Date.now() };\n setButtonRipples((prevRipples) => [...prevRipples, newRipple]);\n };\n\n useEffect(() => {\n if (buttonRipples.length > 0) {\n const lastRipple = buttonRipples[buttonRipples.length - 1];\n const timeout = setTimeout(() => {\n setButtonRipples((prevRipples) =>\n prevRipples.filter((ripple) => ripple.key !== lastRipple.key),\n );\n }, parseInt(duration));\n return () => clearTimeout(timeout);\n }\n }, [buttonRipples, duration]);\n\n return (\n \n
{children}
\n \n {buttonRipples.map((ripple) => (\n \n ))}\n \n \n );\n },\n);\n\nRippleButton.displayName = \"RippleButton\";\n", "type": "registry:ui", "target": "" } diff --git a/public/r/styles/default/shimmer-button.json b/public/r/styles/default/shimmer-button.json index b90a50b6a..d05fe9e9f 100644 --- a/public/r/styles/default/shimmer-button.json +++ b/public/r/styles/default/shimmer-button.json @@ -4,7 +4,7 @@ "files": [ { "path": "magicui/shimmer-button.tsx", - "content": "import React, { CSSProperties } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface ShimmerButtonProps\n extends React.ButtonHTMLAttributes {\n shimmerColor?: string;\n shimmerSize?: string;\n borderRadius?: string;\n shimmerDuration?: string;\n background?: string;\n className?: string;\n children?: React.ReactNode;\n}\n\nconst ShimmerButton = React.forwardRef(\n (\n {\n shimmerColor = \"#ffffff\",\n shimmerSize = \"0.05em\",\n shimmerDuration = \"3s\",\n borderRadius = \"100px\",\n background = \"rgba(0, 0, 0, 1)\",\n className,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n \n {/* spark container */}\n \n {/* spark */}\n
\n {/* spark before */}\n
\n
\n
\n {children}\n\n {/* Highlight */}\n \n\n {/* backdrop */}\n \n \n );\n },\n);\n\nShimmerButton.displayName = \"ShimmerButton\";\n\nexport default ShimmerButton;\n", + "content": "import React, { CSSProperties } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface ShimmerButtonProps\n extends React.ButtonHTMLAttributes {\n shimmerColor?: string;\n shimmerSize?: string;\n borderRadius?: string;\n shimmerDuration?: string;\n background?: string;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport const ShimmerButton = React.forwardRef<\n HTMLButtonElement,\n ShimmerButtonProps\n>(\n (\n {\n shimmerColor = \"#ffffff\",\n shimmerSize = \"0.05em\",\n shimmerDuration = \"3s\",\n borderRadius = \"100px\",\n background = \"rgba(0, 0, 0, 1)\",\n className,\n children,\n ...props\n },\n ref\n ) => {\n return (\n \n {/* spark container */}\n \n {/* spark */}\n
\n {/* spark before */}\n
\n
\n
\n {children}\n\n {/* Highlight */}\n \n\n {/* backdrop */}\n \n \n );\n }\n);\n\nShimmerButton.displayName = \"ShimmerButton\";\n", "type": "registry:ui", "target": "" } diff --git a/public/r/styles/default/shiny-button.json b/public/r/styles/default/shiny-button.json index 51563e772..1a6fd807c 100644 --- a/public/r/styles/default/shiny-button.json +++ b/public/r/styles/default/shiny-button.json @@ -7,7 +7,7 @@ "files": [ { "path": "magicui/shiny-button.tsx", - "content": "\"use client\";\n\nimport React from \"react\";\nimport {\n motion,\n type AnimationProps,\n type HTMLMotionProps,\n} from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\nconst animationProps = {\n initial: { \"--x\": \"100%\", scale: 0.8 },\n animate: { \"--x\": \"-100%\", scale: 1 },\n whileTap: { scale: 0.95 },\n transition: {\n repeat: Infinity,\n repeatType: \"loop\",\n repeatDelay: 1,\n type: \"spring\",\n stiffness: 20,\n damping: 15,\n mass: 2,\n scale: {\n type: \"spring\",\n stiffness: 200,\n damping: 5,\n mass: 0.5,\n },\n },\n} as AnimationProps;\n\ninterface ShinyButtonProps extends HTMLMotionProps<\"button\"> {\n children: React.ReactNode;\n className?: string;\n ref?: React.Ref;\n}\n\nconst ShinyButton = React.forwardRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n \n {children}\n \n \n \n );\n },\n);\n\nShinyButton.displayName = \"ShinyButton\";\n\nexport default ShinyButton;\n", + "content": "\"use client\";\n\nimport React from \"react\";\nimport {\n motion,\n type AnimationProps,\n type HTMLMotionProps,\n} from \"motion/react\";\nimport { cn } from \"@/lib/utils\";\n\nconst animationProps = {\n initial: { \"--x\": \"100%\", scale: 0.8 },\n animate: { \"--x\": \"-100%\", scale: 1 },\n whileTap: { scale: 0.95 },\n transition: {\n repeat: Infinity,\n repeatType: \"loop\",\n repeatDelay: 1,\n type: \"spring\",\n stiffness: 20,\n damping: 15,\n mass: 2,\n scale: {\n type: \"spring\",\n stiffness: 200,\n damping: 5,\n mass: 0.5,\n },\n },\n} as AnimationProps;\n\ninterface ShinyButtonProps extends HTMLMotionProps<\"button\"> {\n children: React.ReactNode;\n className?: string;\n ref?: React.Ref;\n}\n\nexport const ShinyButton = React.forwardRef<\n HTMLButtonElement,\n ShinyButtonProps\n>(({ children, className, ...props }, ref) => {\n return (\n \n \n {children}\n \n \n \n );\n});\n\nShinyButton.displayName = \"ShinyButton\";\n", "type": "registry:ui", "target": "" } diff --git a/registry/default/example/animated-subscribe-button-demo.tsx b/registry/default/example/animated-subscribe-button-demo.tsx index fd7659d59..de1c01f52 100644 --- a/registry/default/example/animated-subscribe-button-demo.tsx +++ b/registry/default/example/animated-subscribe-button-demo.tsx @@ -1,25 +1,17 @@ import { CheckIcon, ChevronRightIcon } from "lucide-react"; - import { AnimatedSubscribeButton } from "@/registry/default/magicui/animated-subscribe-button"; export default function AnimatedSubscribeButtonDemo() { return ( - - Subscribe{" "} - - - } - changeText={ - - - Subscribed{" "} - - } - /> + + + Follow + + + + + Subscribed + + ); } diff --git a/registry/default/example/interactive-hover-button-demo.tsx b/registry/default/example/interactive-hover-button-demo.tsx index 32b9e6efc..ba214d8f6 100644 --- a/registry/default/example/interactive-hover-button-demo.tsx +++ b/registry/default/example/interactive-hover-button-demo.tsx @@ -1,9 +1,5 @@ -import InteractiveHoverButton from "@/registry/default/magicui/interactive-hover-button"; +import { InteractiveHoverButton } from "@/registry/default/magicui/interactive-hover-button"; export default function InteractiveHoverButtonDemo() { - return ( -
- -
- ); + return Hover Me; } diff --git a/registry/default/example/pulsating-button-demo.tsx b/registry/default/example/pulsating-button-demo.tsx index 5de7a5234..8163d0e3b 100644 --- a/registry/default/example/pulsating-button-demo.tsx +++ b/registry/default/example/pulsating-button-demo.tsx @@ -1,4 +1,4 @@ -import PulsatingButton from "@/registry/default/magicui/pulsating-button"; +import { PulsatingButton } from "@/registry/default/magicui/pulsating-button"; export default function PulsatingButtonDemo() { return Join Affiliate Program; diff --git a/registry/default/example/ripple-button-demo.tsx b/registry/default/example/ripple-button-demo.tsx index ec80d3c8e..a575c4390 100644 --- a/registry/default/example/ripple-button-demo.tsx +++ b/registry/default/example/ripple-button-demo.tsx @@ -1,4 +1,4 @@ -import RippleButton from "@/registry/default/magicui/ripple-button"; +import { RippleButton } from "@/registry/default/magicui/ripple-button"; export default function RippleButtonDemo() { return Click me; diff --git a/registry/default/example/shimmer-button-demo.tsx b/registry/default/example/shimmer-button-demo.tsx index 46de4d809..6f0a2045d 100644 --- a/registry/default/example/shimmer-button-demo.tsx +++ b/registry/default/example/shimmer-button-demo.tsx @@ -1,13 +1,11 @@ -import ShimmerButton from "@/registry/default/magicui/shimmer-button"; +import { ShimmerButton } from "@/registry/default/magicui/shimmer-button"; export default function ShimmerButtonDemo() { return ( -
- - - Shimmer Button - - -
+ + + Shimmer Button + + ); } diff --git a/registry/default/example/shiny-button-demo.tsx b/registry/default/example/shiny-button-demo.tsx index a63f94596..3ce1d8666 100644 --- a/registry/default/example/shiny-button-demo.tsx +++ b/registry/default/example/shiny-button-demo.tsx @@ -1,4 +1,4 @@ -import ShinyButton from "@/registry/default/magicui/shiny-button"; +import { ShinyButton } from "@/registry/default/magicui/shiny-button"; export default function ShinyButtonDemo() { return Shiny Button; diff --git a/registry/default/magicui/animated-subscribe-button.tsx b/registry/default/magicui/animated-subscribe-button.tsx index 4531bb24a..80e15ecfb 100644 --- a/registry/default/magicui/animated-subscribe-button.tsx +++ b/registry/default/magicui/animated-subscribe-button.tsx @@ -1,66 +1,98 @@ "use client"; +import { cn } from "@/lib/utils"; +import { HTMLMotionProps } from "motion/react"; import { AnimatePresence, motion } from "motion/react"; import React, { useState } from "react"; -interface AnimatedSubscribeButtonProps { - buttonColor: string; - buttonTextColor?: string; - subscribeStatus: boolean; - initialText: React.ReactElement | string; - changeText: React.ReactElement | string; +interface AnimatedSubscribeButtonProps + extends Omit, "ref"> { + subscribeStatus?: boolean; + children: React.ReactNode; + className?: string; } -export const AnimatedSubscribeButton: React.FC< +export const AnimatedSubscribeButton = React.forwardRef< + HTMLButtonElement, AnimatedSubscribeButtonProps -> = ({ - buttonColor, - subscribeStatus, - buttonTextColor, - changeText, - initialText, -}) => { - const [isSubscribed, setIsSubscribed] = useState(subscribeStatus); +>( + ( + { subscribeStatus = false, onClick, className, children, ...props }, + ref, + ) => { + const [isSubscribed, setIsSubscribed] = useState(subscribeStatus); - return ( - - {isSubscribed ? ( - setIsSubscribed(false)} - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - exit={{ opacity: 0 }} - > - React.isValidElement(child) && child.type === "span", + ) + ) { + throw new Error( + "AnimatedSubscribeButton expects two children, both of which must be elements.", + ); + } + + const childrenArray = React.Children.toArray(children); + const initialChild = childrenArray[0]; + const changeChild = childrenArray[1]; + + return ( + + {isSubscribed ? ( + ) => { + setIsSubscribed(false); + onClick?.(e); + }} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + exit={{ opacity: 0 }} + {...props} > - {changeText} - - - ) : ( - setIsSubscribed(true)} - initial={{ opacity: 0 }} - animate={{ opacity: 1 }} - exit={{ opacity: 0 }} - > - + {changeChild} {/* Use children for subscribed state */} + + + ) : ( + { + setIsSubscribed(true); + onClick?.(e); + }} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + exit={{ opacity: 0 }} + {...props} > - {initialText} - - - )} - - ); -}; + + {initialChild} {/* Use children for unsubscribed state */} + + + )} + + ); + }, +); + +AnimatedSubscribeButton.displayName = "AnimatedSubscribeButton"; diff --git a/registry/default/magicui/interactive-hover-button.tsx b/registry/default/magicui/interactive-hover-button.tsx index 3d4ead8af..e43ccbbe0 100644 --- a/registry/default/magicui/interactive-hover-button.tsx +++ b/registry/default/magicui/interactive-hover-button.tsx @@ -3,35 +3,33 @@ import { ArrowRight } from "lucide-react"; import { cn } from "@/lib/utils"; interface InteractiveHoverButtonProps - extends React.ButtonHTMLAttributes { - text?: string; -} + extends React.ButtonHTMLAttributes {} -const InteractiveHoverButton = React.forwardRef< +export const InteractiveHoverButton = React.forwardRef< HTMLButtonElement, InteractiveHoverButtonProps ->(({ text = "Button", className, ...props }, ref) => { +>(({ children, className, ...props }, ref) => { return ( ); }); InteractiveHoverButton.displayName = "InteractiveHoverButton"; - -export default InteractiveHoverButton; diff --git a/registry/default/magicui/pulsating-button.tsx b/registry/default/magicui/pulsating-button.tsx index 3a6e0c299..48546f9fd 100644 --- a/registry/default/magicui/pulsating-button.tsx +++ b/registry/default/magicui/pulsating-button.tsx @@ -1,7 +1,4 @@ -"use client"; - import React from "react"; - import { cn } from "@/lib/utils"; interface PulsatingButtonProps @@ -10,29 +7,40 @@ interface PulsatingButtonProps duration?: string; } -export default function PulsatingButton({ - className, - children, - pulseColor = "#0096ff", - duration = "1.5s", - ...props -}: PulsatingButtonProps) { - return ( - - ); -} +export const PulsatingButton = React.forwardRef< + HTMLButtonElement, + PulsatingButtonProps +>( + ( + { + className, + children, + pulseColor = "#0096ff", + duration = "1.5s", + ...props + }, + ref, + ) => { + return ( + + ); + }, +); + +PulsatingButton.displayName = "PulsatingButton"; diff --git a/registry/default/magicui/rainbow-button.tsx b/registry/default/magicui/rainbow-button.tsx index a1f66713f..51926cb3f 100644 --- a/registry/default/magicui/rainbow-button.tsx +++ b/registry/default/magicui/rainbow-button.tsx @@ -1,28 +1,24 @@ import React from "react"; - import { cn } from "@/lib/utils"; + interface RainbowButtonProps extends React.ButtonHTMLAttributes {} -export function RainbowButton({ - children, - className, - ...props -}: RainbowButtonProps) { +export const RainbowButton = React.forwardRef< + HTMLButtonElement, + RainbowButtonProps +>(({ children, className, ...props }, ref) => { return (