11import { clsx } from "@lib/utils/clsx" ;
2+ import { WithRequired } from "@lib/utils/typeUtils/WithRequired" ;
23import { HTMLMotionProps , motion } from "framer-motion" ;
34import { forwardRef } from "react" ;
45
56type ButtonStyleProps = {
6- variant ?: "solid" | "outline" ;
7+ variant ?: "solid" | "outline" | "link" ;
78 color ?: "primary" ;
89} ;
910type ButtonProps = HTMLMotionProps < "button" > & ButtonStyleProps ;
10- type ButtonLinkProps = HTMLMotionProps < "a" > & ButtonStyleProps ;
11+ type LinkProps = WithRequired < HTMLMotionProps < "a" > , "href "> & ButtonStyleProps ;
1112
12- function colors ( { variant = "solid" , color = "primary" } : ButtonStyleProps ) {
13+ function variantClasses ( {
14+ variant = "solid" ,
15+ color = "primary" ,
16+ } : ButtonStyleProps ) {
1317 if ( variant === "outline" ) {
1418 const borderColor = ( ( ) => {
1519 switch ( color ) {
1620 case "primary" :
17- return "border-primary text-text " ;
21+ return "border-primary text-primary rounded flex flex-row justify-center items-center gap-2 px py-1 " ;
1822 }
1923 } ) ( ) ;
2024 return clsx ( borderColor , "border-thick" ) ;
2125 }
26+ if ( variant === "link" ) {
27+ return clsx ( "text-primary inline" ) ;
28+ }
2229
2330 switch ( color ) {
2431 case "primary" :
25- return "bg-primary text-primary-contrast" ;
32+ return "bg-primary text-primary-contrast shadow-sm rounded flex flex-row justify-center items-center gap-2 px py-1 " ;
2633 }
2734}
2835
2936function commonProps < Type extends "a" | "button" > ( {
3037 className,
3138 ...props
32- } : Type extends "a" ? ButtonLinkProps : ButtonProps ) : Type extends "a"
33- ? ButtonLinkProps
34- : ButtonProps {
39+ } : Type extends "a" ? LinkProps : ButtonProps ) : ( Type extends "a"
40+ ? LinkProps
41+ : ButtonProps ) & { className : string } {
42+ // @ts -expect-error These types do match, but TypeScript doesn't seem to like it
3543 return {
36- className : clsx (
37- "rounded shadow-sm flex flex-row justify-center items-center gap-2 px py-1" ,
38- colors ( props ) ,
39- className ,
40- ) ,
44+ className : clsx ( variantClasses ( props ) , className , "cursor-pointer" ) ,
4145 ...props ,
4246 } ;
4347}
@@ -53,7 +57,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
5357) ;
5458Button . displayName = "Button" ;
5559
56- export const ButtonLink = forwardRef < HTMLAnchorElement , ButtonLinkProps > (
60+ export const ButtonLink = forwardRef < HTMLAnchorElement , LinkProps > (
5761 ( { children, ...props } , ref ) => {
5862 return (
5963 < motion . a ref = { ref } { ...commonProps < "a" > ( props ) } >
@@ -63,3 +67,14 @@ export const ButtonLink = forwardRef<HTMLAnchorElement, ButtonLinkProps>(
6367 } ,
6468) ;
6569ButtonLink . displayName = "ButtonLink" ;
70+
71+ export const Link = forwardRef < HTMLAnchorElement , Omit < LinkProps , "variant" > > (
72+ ( { children, ...props } , ref ) => {
73+ return (
74+ < motion . a ref = { ref } { ...commonProps < "a" > ( { variant : "link" , ...props } ) } >
75+ { children }
76+ </ motion . a >
77+ ) ;
78+ } ,
79+ ) ;
80+ Link . displayName = "Link" ;
0 commit comments