From 903a70b650f64661f262a88bab5949c389d41b49 Mon Sep 17 00:00:00 2001 From: Adriskk <65545676+Adriskk@users.noreply.github.com> Date: Fri, 13 Dec 2024 17:36:29 +0100 Subject: [PATCH 1/6] create animated gradient button --- package-lock.json | 10 ++++++ package.json | 2 +- src/app/globals.css | 3 ++ src/components/ui/button.tsx | 60 ++++++++++++++++++++++++++++++++---- tailwind.config.ts | 14 +++++++++ 5 files changed, 82 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0997d3c..2a60087 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@tanstack/react-query": "^5.60.5", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "date-fns": "^4.1.0", "lucide-react": "^0.460.0", "next": "^15.0.3", "prettier": "^3.4.0", @@ -1852,6 +1853,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", diff --git a/package.json b/package.json index cd29a46..99f50a1 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "@tanstack/react-query": "^5.60.5", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", - "lucide-react": "^0.460.0", "date-fns": "^4.1.0", + "lucide-react": "^0.460.0", "next": "^15.0.3", "prettier": "^3.4.0", "react": "^18.3.1", diff --git a/src/app/globals.css b/src/app/globals.css index f3c56e2..2afea10 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -34,6 +34,9 @@ body { --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; --radius: 0.5rem; + + --gradient-green: #58C473; + --gradient-blue: #049BAD; } .dark { --background: 20 14.3% 4.1%; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 36496a2..28f02f6 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,15 +1,18 @@ +'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" +import {ArrowRight} from "lucide-react"; const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "relative cursor-pointer overflow-hidden inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border text-[16px] md:text-[18px] font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", { - variants: { + variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", + default: "text-foreground", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: @@ -20,7 +23,7 @@ const buttonVariants = cva( link: "text-primary underline-offset-4 hover:underline", }, size: { - default: "h-10 px-4 py-2", + default: "px-6 py-3 md:px-8 md:py-4", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10", @@ -50,7 +53,52 @@ const Button = React.forwardRef( /> ) } -) +); Button.displayName = "Button" -export { Button, buttonVariants } +interface GradientButtonProps extends ButtonProps { + children: React.ReactNode; + asChild?: boolean; + colorType?: 'black' | 'white'; +} + +const GradientButton = React.forwardRef( + ({children, colorType = 'black', asChild = false, ...props }, ref) => { + + return ( + + ); + } +); +GradientButton.displayName = "CustomButton"; + + +export { GradientButton, Button, buttonVariants } diff --git a/tailwind.config.ts b/tailwind.config.ts index f860d8e..c040a01 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -9,6 +9,9 @@ export default { ], theme: { extend: { + backgroundImage: { + 'gradient-green-blue': 'radial-gradient(94.87% 94.87% at 90% 70%, var(--gradient-blue) 0%, var(--gradient-green) 100%)' + }, fontFamily: { sans: ["var(--font-montserrat)", "sans-serif"], }, @@ -59,6 +62,17 @@ export default { md: "calc(var(--radius) - 2px)", sm: "calc(var(--radius) - 4px)", }, + keyframes: { + 'bouncy-arrow-reveal': { + '0%': { transform: 'scale(0) rotate(30deg)' }, + '25%': { transform: 'scale(0.3) rotate(45deg)' }, + '75%': { transform: 'scale(1) rotate(-4deg)' }, + '100%': { transform: 'scale(1) rotate(0deg)' }, + } + }, + animation: { + 'reveal-arrow': 'bouncy-arrow-reveal 200ms cubic-bezier(0,-0.01,0,.98) forwards' + } }, }, plugins: [require("tailwindcss-animate")], From ae670baf8263c900233a96936336cf1744c8060e Mon Sep 17 00:00:00 2001 From: Adriskk <65545676+Adriskk@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:55:29 +0100 Subject: [PATCH 2/6] create gradient on hover --- src/components/ui/button.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 28f02f6..ab1db31 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -8,7 +8,7 @@ import { cn } from "@/lib/utils" import {ArrowRight} from "lucide-react"; const buttonVariants = cva( - "relative cursor-pointer overflow-hidden inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border text-[16px] md:text-[18px] font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "relative overflow-hidden inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border text-[16px] md:text-[18px] font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", { variants: { variant: { @@ -70,16 +70,16 @@ const GradientButton = React.forwardRef( ref={ref} asChild={asChild} size="default" - className={cn("cursor-pointer group before:content-[''] before:absolute before:bg-gradient-green-blue " + - "before:w-[115%] before:h-[200%] before:z-[-1] isolate before:top-full before:rounded-[50%] " + - "before:transition-all before:duration-[250ms] before:ease-out hover:before:-top-1/2 " + + className={cn("group before:pointer-events-auto before:content-[''] before:absolute before:bg-gradient-green-blue " + + "before:w-[110%] before:h-[200%] before:z-[-1] isolate before:top-full before:rounded-[50%] " + + "before:transition-all before:duration-[200ms] before:ease-out hover:before:-top-1/2 " + "hover:before:ease-in hover:before:origin-top", { 'border-black': colorType === 'black', 'border-white': colorType === 'white' })} {...props} > -
+
Date: Tue, 17 Dec 2024 20:56:13 +0100 Subject: [PATCH 3/6] create other variants of button, update other components that use button component --- src/app/animations.css | 24 ++++ src/app/globals.css | 8 +- src/components/ui/NoDataInfo.tsx | 8 +- src/components/ui/button.tsx | 158 +++++++++++++++----------- src/components/ui/horizontal-rule.tsx | 2 +- tailwind.config.ts | 18 +-- 6 files changed, 129 insertions(+), 89 deletions(-) create mode 100644 src/app/animations.css diff --git a/src/app/animations.css b/src/app/animations.css new file mode 100644 index 0000000..f10fc5e --- /dev/null +++ b/src/app/animations.css @@ -0,0 +1,24 @@ +.underscore-anim { + position: relative; +} + +.underscore-anim::after { + content: ""; + position: absolute; + left: 0; + bottom: -0.1rem; + height: 2px; + width: 100%; + display: block; + box-sizing: border-box; + border-radius: 100px; + @apply bg-black; + transition: 200ms transform, 0ms transform-origin ease-in; + transform: scaleX(0); + transform-origin: bottom right; +} + +.underscore-anim:hover::after { + transform: scaleX(1); + transform-origin: bottom left; +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index 10824df..033697a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,3 +1,5 @@ +@import "./animations.css"; + @tailwind base; @tailwind components; @tailwind utilities; @@ -8,7 +10,7 @@ body { @layer base { :root { - --font-montserrat: 'Montserrat', sans-serif; + --font-montserrat: "Montserrat", sans-serif; --background: 0 0% 100%; --foreground: 20 14.3% 4.1%; --card: 0 0% 100%; @@ -35,8 +37,8 @@ body { --chart-5: 27 87% 67%; --radius: 0.5rem; - --gradient-green: #58C473; - --gradient-blue: #049BAD; + --gradient-green: #58c473; + --gradient-blue: #049bad; } .dark { --background: 20 14.3% 4.1%; diff --git a/src/components/ui/NoDataInfo.tsx b/src/components/ui/NoDataInfo.tsx index 35548f9..184a9e8 100644 --- a/src/components/ui/NoDataInfo.tsx +++ b/src/components/ui/NoDataInfo.tsx @@ -12,13 +12,7 @@ const NoDataInfo = ({ errorTitle, errorMessage }: NoDataInfoProps) => {

{errorTitle}

{errorMessage}

- +
); }; diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index ab1db31..b338250 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,104 +1,124 @@ -'use client'; +"use client"; -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +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" -import {ArrowRight} from "lucide-react"; +import { cn } from "@/lib/utils"; +import { ArrowRight } from "lucide-react"; const buttonVariants = cva( - "relative overflow-hidden inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border text-[16px] md:text-[18px] font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + "relative overflow-hidden inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full border text-[14px] md:text-[16px] font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", { - variants: { + variants: { variant: { default: "text-foreground", + secondary: "", + gradient: "", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", + ghost: + "border-0 bg-slate-500/0 transition-colors hover:bg-slate-500/10", + link: "border-0 !py-1 !px-2", + }, + color: { + default: "border-black", + black: "border-black", + white: "!border-white", }, size: { - default: "px-6 py-3 md:px-8 md:py-4", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", + default: "px-6 py-3 md:px-8 md:py-3", + sm: "px-5 py-1 !text-[14px]", + lg: "px-12 py-5", + icon: "h-12 w-12", }, }, defaultVariants: { variant: "default", size: "default", + color: "default", }, - } -) + }, +); export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { - asChild?: boolean -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button" - return ( - - ) - } -); -Button.displayName = "Button" - -interface GradientButtonProps extends ButtonProps { - children: React.ReactNode; asChild?: boolean; - colorType?: 'black' | 'white'; } -const GradientButton = React.forwardRef( - ({children, colorType = 'black', asChild = false, ...props }, ref) => { +const Button = React.forwardRef( + ( + { + children, + className, + variant = "default", + size, + color = "black", + asChild = false, + ...props + }, + ref, + ) => { + const Comp = asChild ? Slot : "button"; return ( - + ); - } + }, ); -GradientButton.displayName = "CustomButton"; - +Button.displayName = "Button"; -export { GradientButton, Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/src/components/ui/horizontal-rule.tsx b/src/components/ui/horizontal-rule.tsx index f396feb..b31547b 100644 --- a/src/components/ui/horizontal-rule.tsx +++ b/src/components/ui/horizontal-rule.tsx @@ -1,3 +1,3 @@ export function HorizontalRule() { - return
; + return
; } diff --git a/tailwind.config.ts b/tailwind.config.ts index c040a01..f8eff80 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -10,7 +10,8 @@ export default { theme: { extend: { backgroundImage: { - 'gradient-green-blue': 'radial-gradient(94.87% 94.87% at 90% 70%, var(--gradient-blue) 0%, var(--gradient-green) 100%)' + "gradient-green-blue": + "radial-gradient(94.87% 94.87% at 90% 70%, var(--gradient-blue) 0%, var(--gradient-green) 100%)", }, fontFamily: { sans: ["var(--font-montserrat)", "sans-serif"], @@ -63,16 +64,15 @@ export default { sm: "calc(var(--radius) - 4px)", }, keyframes: { - 'bouncy-arrow-reveal': { - '0%': { transform: 'scale(0) rotate(30deg)' }, - '25%': { transform: 'scale(0.3) rotate(45deg)' }, - '75%': { transform: 'scale(1) rotate(-4deg)' }, - '100%': { transform: 'scale(1) rotate(0deg)' }, - } + "bouncy-arrow-reveal": { + "0%": { transform: "scale3d(0, 0, 1) rotate(45deg)" }, + "100%": { transform: "scaleX(1) rotate(0deg)" }, + }, }, animation: { - 'reveal-arrow': 'bouncy-arrow-reveal 200ms cubic-bezier(0,-0.01,0,.98) forwards' - } + "reveal-arrow": + "bouncy-arrow-reveal 0.2s cubic-bezier(.2, 1.2, .3, 1.4) forwards", + }, }, }, plugins: [require("tailwindcss-animate")], From bf06ff6593dd00be4a372a500bffae8a7cd7b70f Mon Sep 17 00:00:00 2001 From: Adriskk <65545676+Adriskk@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:13:16 +0100 Subject: [PATCH 4/6] fix tailwind config error --- tailwind.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tailwind.config.ts b/tailwind.config.ts index f8eff80..c9a5081 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -11,7 +11,7 @@ export default { extend: { backgroundImage: { "gradient-green-blue": - "radial-gradient(94.87% 94.87% at 90% 70%, var(--gradient-blue) 0%, var(--gradient-green) 100%)", + "radial-gradient(94.87% 94.87% at 90% 70%, hsl(var(--primary)) 0%, hsl(var(--secondary)) 100%)", }, fontFamily: { sans: ["var(--font-montserrat)", "sans-serif"], @@ -65,13 +65,13 @@ export default { }, keyframes: { "bouncy-arrow-reveal": { - "0%": { transform: "scale3d(0, 0, 1) rotate(45deg)" }, + "0%": { transform: "scale3d(0,0,1) rotate(45deg)" }, "100%": { transform: "scaleX(1) rotate(0deg)" }, }, }, animation: { "reveal-arrow": - "bouncy-arrow-reveal 0.2s cubic-bezier(.2, 1.2, .3, 1.4) forwards", + "bouncy-arrow-reveal 0.17s cubic-bezier(.2, 1.2, .3, 1.4) forwards", }, }, }, From a2ffa03eaa1ad9094c1d31e3413c85479031f15a Mon Sep 17 00:00:00 2001 From: Adriskk <65545676+Adriskk@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:19:05 +0100 Subject: [PATCH 5/6] update button in post preview component --- src/components/latest-news/post-preview.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/latest-news/post-preview.tsx b/src/components/latest-news/post-preview.tsx index b93e212..3d458a9 100644 --- a/src/components/latest-news/post-preview.tsx +++ b/src/components/latest-news/post-preview.tsx @@ -41,11 +41,7 @@ export function PostPreview({ post }: { post: FacebookPost }) {

} -
From 9057d4196da6f202c29190eab25d758d83c1240b Mon Sep 17 00:00:00 2001 From: Adriskk <65545676+Adriskk@users.noreply.github.com> Date: Wed, 18 Dec 2024 21:09:40 +0100 Subject: [PATCH 6/6] fix: transition class and format check --- src/components/button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/button.tsx b/src/components/button.tsx index 8b17fb4..0c3a0a1 100644 --- a/src/components/button.tsx +++ b/src/components/button.tsx @@ -68,7 +68,7 @@ const Button = React.forwardRef( buttonVariants({ variant, size, className, color }), "group before:pointer-events-auto before:absolute before:bg-transparent before:content-['']" + " isolate before:top-full before:z-[-1] before:h-[200%] before:w-[110%] before:rounded-[50%]" + - " before:duration-[200ms] before:ease-[cubic-bezier(.23,1,.32,1)] before:transition-all hover:before:-top-1/2" + + " before:ease-[cubic-bezier(.23,1,.32,1)] before:transition-all before:duration-200 hover:before:-top-1/2" + " hover:before:origin-top hover:before:ease-in", { "before:bg-gradient-green-blue": variant === "gradient",