diff --git a/web/src/app/globals.css b/web/src/app/globals.css index 9ff21031..644b57e6 100644 --- a/web/src/app/globals.css +++ b/web/src/app/globals.css @@ -1,7 +1,7 @@ @import "tailwindcss"; @import "tw-animate-css"; - @plugin "tailwindcss-motion"; + @custom-variant dark (&:is(.dark *)); @theme inline { @@ -62,7 +62,20 @@ height: 0; } } -} + + --animate-marquee: marquee var(--duration) infinite linear; + --animate-marquee-vertical: marquee-vertical var(--duration) linear infinite; + + @keyframes marquee { + from { + transform: translateX(0);} + to { + transform: translateX(calc(-100% - var(--gap)));}} + @keyframes marquee-vertical { + from { + transform: translateY(0);} + to { + transform: translateY(calc(-100% - var(--gap)));}}} :root { --radius: 0.75rem; @@ -158,4 +171,4 @@ .glass-effect { @apply backdrop-blur-sm; } -} +} \ No newline at end of file diff --git a/web/src/components/magicui/marquee.tsx b/web/src/components/magicui/marquee.tsx new file mode 100644 index 00000000..fa9c129b --- /dev/null +++ b/web/src/components/magicui/marquee.tsx @@ -0,0 +1,73 @@ +import { cn } from "@/lib/utils"; +import { ComponentPropsWithoutRef } from "react"; + +interface MarqueeProps extends ComponentPropsWithoutRef<"div"> { + /** + * Optional CSS class name to apply custom styles + */ + className?: string; + /** + * Whether to reverse the animation direction + * @default false + */ + reverse?: boolean; + /** + * Whether to pause the animation on hover + * @default false + */ + pauseOnHover?: boolean; + /** + * Content to be displayed in the marquee + */ + children: React.ReactNode; + /** + * Whether to animate vertically instead of horizontally + * @default false + */ + vertical?: boolean; + /** + * Number of times to repeat the content + * @default 4 + */ + repeat?: number; +} + +export function Marquee({ + className, + reverse = false, + pauseOnHover = false, + children, + vertical = false, + repeat = 4, + ...props +}: MarqueeProps) { + return ( +