Skip to content

Commit 8ea4829

Browse files
authored
feat: enhance github stars button to be better looking and more compact (#7464)
* feat: enhance github stars button to be better looking and more compact to make mobile compatibility easier in the future * feat: introduce a new Button component
1 parent c5d23dc commit 8ea4829

File tree

13 files changed

+1168
-25
lines changed

13 files changed

+1168
-25
lines changed

frontend/components.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package-lock.json

Lines changed: 90 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"use client";
2+
3+
import type { VariantProps } from "class-variance-authority";
4+
5+
import { cva } from "class-variance-authority";
6+
import * as React from "react";
7+
8+
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
9+
10+
import {
11+
Button as ButtonPrimitive,
12+
13+
} from "@/components/animate-ui/primitives/buttons/button";
14+
import { cn } from "@/lib/utils";
15+
16+
const buttonVariants = cva(
17+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
18+
{
19+
variants: {
20+
variant: {
21+
default:
22+
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
23+
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
24+
destructive:
25+
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
26+
outline:
27+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
28+
secondary:
29+
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
30+
ghost:
31+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
32+
link: "text-primary underline-offset-4 hover:underline",
33+
},
34+
size: {
35+
"default": "h-9 px-4 py-2 has-[>svg]:px-3",
36+
"sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
37+
"lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
38+
"icon": "size-9",
39+
"icon-sm": "size-8 rounded-md",
40+
"icon-lg": "size-10 rounded-md",
41+
},
42+
},
43+
defaultVariants: {
44+
variant: "default",
45+
size: "default",
46+
},
47+
},
48+
);
49+
50+
type ButtonProps = ButtonPrimitiveProps & VariantProps<typeof buttonVariants>;
51+
52+
function Button({ className, variant, size, ...props }: ButtonProps) {
53+
return (
54+
<ButtonPrimitive
55+
className={cn(buttonVariants({ variant, size, className }))}
56+
{...props}
57+
/>
58+
);
59+
}
60+
61+
export { Button, type ButtonProps, buttonVariants };
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import type { VariantProps } from "class-variance-authority";
2+
3+
import { cva } from "class-variance-authority";
4+
import { StarIcon } from "lucide-react";
5+
6+
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
7+
import type { GithubStarsProps } from "@/components/animate-ui/primitives/animate/github-stars";
8+
9+
import {
10+
GithubStars,
11+
GithubStarsIcon,
12+
GithubStarsLogo,
13+
GithubStarsNumber,
14+
GithubStarsParticles,
15+
} from "@/components/animate-ui/primitives/animate/github-stars";
16+
import { Button as ButtonPrimitive } from "@/components/animate-ui/primitives/buttons/button";
17+
import { cn } from "@/lib/utils";
18+
19+
const buttonVariants = cva(
20+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
21+
{
22+
variants: {
23+
variant: {
24+
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
25+
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
26+
outline:
27+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
28+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
29+
},
30+
size: {
31+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
32+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
33+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
34+
},
35+
},
36+
defaultVariants: {
37+
variant: "default",
38+
size: "default",
39+
},
40+
},
41+
);
42+
43+
const buttonStarVariants = cva("", {
44+
variants: {
45+
variant: {
46+
default: "fill-neutral-700 stroke-neutral-700 dark:fill-neutral-300 dark:stroke-neutral-300",
47+
accent: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
48+
outline: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
49+
ghost: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
50+
},
51+
},
52+
defaultVariants: {
53+
variant: "default",
54+
},
55+
});
56+
57+
type GitHubStarsButtonProps = Omit<ButtonPrimitiveProps & GithubStarsProps, "asChild" | "children">
58+
& VariantProps<typeof buttonVariants>;
59+
60+
function GitHubStarsButton({
61+
className,
62+
username,
63+
repo,
64+
value,
65+
delay,
66+
inView,
67+
inViewMargin,
68+
inViewOnce,
69+
variant,
70+
size,
71+
...props
72+
}: GitHubStarsButtonProps) {
73+
return (
74+
<GithubStars
75+
asChild
76+
username={username}
77+
repo={repo}
78+
value={value}
79+
delay={delay}
80+
inView={inView}
81+
inViewMargin={inViewMargin}
82+
inViewOnce={inViewOnce}
83+
>
84+
<ButtonPrimitive className={cn(buttonVariants({ variant, size, className }))} {...props}>
85+
<GithubStarsLogo />
86+
<GithubStarsNumber />
87+
<GithubStarsParticles className="text-yellow-500">
88+
<GithubStarsIcon
89+
icon={StarIcon}
90+
data-variant={variant}
91+
className={cn(buttonStarVariants({ variant }))}
92+
activeClassName="text-yellow-500"
93+
size={18}
94+
/>
95+
</GithubStarsParticles>
96+
</ButtonPrimitive>
97+
</GithubStars>
98+
);
99+
}
100+
101+
export { GitHubStarsButton, type GitHubStarsButtonProps };

0 commit comments

Comments
 (0)