From a69eedc63882256c0a5e36546cc5573bc2504660 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Thu, 8 Jan 2026 11:29:56 +0100 Subject: [PATCH] feat: enhance styling and animations for search - Added rainbow animation to global styles. - Introduced new color variables for consistent theming. - Updated AddToSearchBarButton to use the new RainbowButton component. - Adjusted dialog content size for better layout. - Removed deprecated RainbowButton component from magicui registry. --- web/src/app/globals.css | 42 ++++++++++++- .../components/add-to-search-bar-button.tsx | 9 ++- web/src/components/icon-search.tsx | 2 +- web/src/components/ui/modal.tsx | 2 + web/src/components/ui/rainbow-button.tsx | 61 +++++++++++++++++++ web/src/registry/magicui/rainbow-button.tsx | 58 ------------------ 6 files changed, 109 insertions(+), 65 deletions(-) create mode 100644 web/src/components/ui/rainbow-button.tsx delete mode 100644 web/src/registry/magicui/rainbow-button.tsx diff --git a/web/src/app/globals.css b/web/src/app/globals.css index 07ed78a8..88350038 100644 --- a/web/src/app/globals.css +++ b/web/src/app/globals.css @@ -152,6 +152,26 @@ --shadow-opacity: var(--shadow-opacity); --color-shadow-color: var(--shadow-color); + + --animate-rainbow: rainbow var(--speed, 2s) infinite linear; + + --color-color-5: var(--color-5); + + --color-color-4: var(--color-4); + + --color-color-3: var(--color-3); + + --color-color-2: var(--color-2); + + --color-color-1: var(--color-1); + @keyframes rainbow { + 0% { + background-position: 0%; + } + 100% { + background-position: 200%; + } + } } :root { @@ -223,6 +243,16 @@ --spacing: 0.25rem; --tracking-normal: 0em; + + --color-1: oklch(66.2% 0.225 25.9); + + --color-2: oklch(60.4% 0.26 302); + + --color-3: oklch(69.6% 0.165 251); + + --color-4: oklch(80.2% 0.134 225); + + --color-5: oklch(90.7% 0.231 133); } .dark { @@ -284,6 +314,16 @@ --shadow-offset-x: 0px; --shadow-offset-y: 2px; + + --color-1: oklch(66.2% 0.225 25.9); + + --color-2: oklch(60.4% 0.26 302); + + --color-3: oklch(69.6% 0.165 251); + + --color-4: oklch(80.2% 0.134 225); + + --color-5: oklch(90.7% 0.231 133); } @layer base { @@ -340,4 +380,4 @@ input.error:focus { @apply ring-2 ring-destructive ring-offset-2 ring-offset-background; } -} +} \ No newline at end of file diff --git a/web/src/components/add-to-search-bar-button.tsx b/web/src/components/add-to-search-bar-button.tsx index 4888da35..bd96d415 100644 --- a/web/src/components/add-to-search-bar-button.tsx +++ b/web/src/components/add-to-search-bar-button.tsx @@ -2,7 +2,7 @@ import { useState } from "react" import { Check, Copy, Globe2, Search, Sparkles } from "lucide-react" -import { RainbowButton } from "@/registry/magicui/rainbow-button" +import { RainbowButton } from "@/components/ui/rainbow-button" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" @@ -80,18 +80,17 @@ export function AddToSearchBarButton({ variant="outline" size={size} className={cn( - "shadow-md px-5 hover:shadow-primary/30 active:scale-[0.99]", + "shadow-sm", className, )} > - Add to browser search + Add to browser search Add to search - - + diff --git a/web/src/components/icon-search.tsx b/web/src/components/icon-search.tsx index 2f22e7f5..978b90a3 100644 --- a/web/src/components/icon-search.tsx +++ b/web/src/components/icon-search.tsx @@ -325,7 +325,7 @@ export function IconSearch({ icons }: IconSearchProps) { - + {/* Clear all button */} {(searchQuery || selectedCategories.length > 0 || sortOption !== "relevance") && ( diff --git a/web/src/components/ui/modal.tsx b/web/src/components/ui/modal.tsx index af755bbd..5cd69ce1 100644 --- a/web/src/components/ui/modal.tsx +++ b/web/src/components/ui/modal.tsx @@ -164,3 +164,5 @@ export { ModalTrigger, } + + diff --git a/web/src/components/ui/rainbow-button.tsx b/web/src/components/ui/rainbow-button.tsx new file mode 100644 index 00000000..2584812a --- /dev/null +++ b/web/src/components/ui/rainbow-button.tsx @@ -0,0 +1,61 @@ +import React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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,var(--color-1),var(--color-5),var(--color-3),var(--color-4),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, + VariantProps { + asChild?: boolean +} + +const RainbowButton = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) + +RainbowButton.displayName = "RainbowButton" + +export { RainbowButton, rainbowButtonVariants, type RainbowButtonProps } diff --git a/web/src/registry/magicui/rainbow-button.tsx b/web/src/registry/magicui/rainbow-button.tsx deleted file mode 100644 index 949694fc..00000000 --- a/web/src/registry/magicui/rainbow-button.tsx +++ /dev/null @@ -1,58 +0,0 @@ -"use client"; - -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" -import { cn } from "@/lib/utils" - -const rainbowButtonVariants = cva( - "relative inline-flex items-center justify-center overflow-hidden rounded-full font-semibold transition-all duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background", - { - variants: { - variant: { - default: "text-white shadow-lg", - outline: "text-foreground border border-border bg-background/80 backdrop-blur-sm", - }, - size: { - sm: "h-9 px-4 text-sm", - default: "h-10 px-6 text-sm", - lg: "h-12 px-8 text-base", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - }, -) - -export interface RainbowButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean -} - -const RainbowButton = React.forwardRef( - ({ className, variant, size, asChild = false, children, ...props }, ref) => { - const Comp = asChild ? Slot : "button" - - return ( - - - - {children} - - ) - }, -) - -RainbowButton.displayName = "RainbowButton" - -export { RainbowButton, rainbowButtonVariants }