refactor: add link variant to Button component and enhance CallToAction and HomeDesign styling

- Added 'link' variant to Button with baseStyles and variantStyles for cyan, white, and dark colors
- Updated Button type definitions to include link variant with proper color options
- Refactored default variant/color logic to use explicit conditionals for type safety
- Changed outline variant border from single to border-2 and added font-semibold
- Updated outline variant hover states to include text
This commit is contained in:
2025-11-19 13:09:29 +01:00
parent e5ed88b676
commit c1ca5e35f0
3 changed files with 44 additions and 17 deletions

View File

@@ -5,7 +5,9 @@ const baseStyles = {
solid: solid:
'inline-flex justify-center rounded-full py-2 px-5 text-sm md:text-base font-semibold transition-colors', 'inline-flex justify-center rounded-full py-2 px-5 text-sm md:text-base font-semibold transition-colors',
outline: outline:
'inline-flex justify-center bg-transparent rounded-full border py-[calc(--spacing(2)-1px)] px-[calc(--spacing(5)-1px)] text-sm md:text-base transition-colors', 'inline-flex justify-center bg-transparent font-semibold rounded-full border border-2 py-[calc(--spacing(2)-1px)] px-[calc(--spacing(5)-1px)] text-sm md:text-base transition-colors',
link:
'inline-flex items-center text-sm md:text-base font-semibold transition-colors',
} }
const variantStyles = { const variantStyles = {
@@ -18,8 +20,13 @@ const variantStyles = {
}, },
outline: { outline: {
cyan: 'border-cyan-500 text-cyan-500', cyan: 'border-cyan-500 text-cyan-500',
gray: 'border-gray-300 text-gray-700 hover:border-cyan-500 active:border-cyan-500', gray: 'border-gray-300 text-gray-600 hover:text-cyan-500 hover:border-cyan-500 active:border-cyan-500',
white: 'border-gray-300 text-white hover:border-cyan-500 active:border-cyan-500', white: 'border-gray-300 text-white hover:text-cyan-500 hover:border-cyan-500 active:border-cyan-500',
},
link: {
cyan: 'text-cyan-400 underline hover:text-cyan-300',
white: 'text-white underline hover:text-cyan-300',
dark: 'text-gray-900 underline hover:text-cyan-500',
}, },
} }
@@ -30,7 +37,11 @@ type ButtonProps = (
} }
| { | {
variant: 'outline' variant: 'outline'
color?: (keyof typeof variantStyles.outline) | 'cyan' color?: keyof typeof variantStyles.outline
}
| {
variant: 'link'
color?: keyof typeof variantStyles.link
} }
) & ) &
( (
@@ -43,16 +54,33 @@ type ButtonProps = (
) )
export function Button({ className, as, ...props }: ButtonProps) { export function Button({ className, as, ...props }: ButtonProps) {
props.variant ??= 'solid' // Set safe defaults per variant so color always matches a valid palette key
props.color ??= 'gray' if (!props.variant) {
props.variant = 'solid'
}
if (!props.color) {
if (props.variant === 'solid') {
props.color = 'gray'
} else if (props.variant === 'outline') {
props.color = 'gray'
} else if (props.variant === 'link') {
props.color = 'cyan'
}
}
const variant = props.variant
const color = props.color as string
className = clsx( className = clsx(
baseStyles[props.variant], baseStyles[variant],
props.variant === 'outline' variant === 'outline'
? variantStyles.outline[props.color] ? variantStyles.outline[color as keyof typeof variantStyles.outline]
: props.variant === 'solid' : variant === 'solid'
? variantStyles.solid[props.color] ? variantStyles.solid[color as keyof typeof variantStyles.solid]
: undefined, : variant === 'link'
? variantStyles.link[color as keyof typeof variantStyles.link]
: undefined,
className, className,
) )

View File

@@ -1,4 +1,3 @@
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container' import { Container } from '@/components/Container'
import { Button } from '@/components/Button' import { Button } from '@/components/Button'
import { H3, P } from '@/components/Texts' import { H3, P } from '@/components/Texts'
@@ -27,7 +26,7 @@ export function CallToAction() {
cx={512} cx={512}
cy={512} cy={512}
fill="url(#mycelium-cyan-glow)" fill="url(#mycelium-cyan-glow)"
fillOpacity="0.2" fillOpacity="0.4"
/> />
<defs> <defs>
<radialGradient id="mycelium-cyan-glow"> <radialGradient id="mycelium-cyan-glow">
@@ -67,9 +66,9 @@ export function CallToAction() {
Deploy in Cloud Deploy in Cloud
</Button> </Button>
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors"> <Button to="/nodes" variant="link" color="cyan">
Host a Node &rarr; Host a Node &rarr;
</Link> </Button>
</div> </div>
</div> </div>
</Container> </Container>

View File

@@ -54,7 +54,7 @@ export function HomeDesign() {
{benefits.map((item) => ( {benefits.map((item) => (
<div <div
key={item.id} key={item.id}
className="mt-8 group flex items-start gap-2 bg-white px-8 py-12 border border-gray-200 lg:border-t lg:border-b border-l-0.5 border-r-0.5" className="mt-8 group flex items-start gap-2 bg-white px-8 py-12 border border-gray-200 lg:border-t lg:border-b border-l-0.5 border-r-0.5 transition-all duration-300 ease-in-out hover:scale-[1.02] hover:border-cyan-500 hover:shadow-lg hover:shadow-cyan-500/20"
> >
{/* Image on the LEFT */} {/* Image on the LEFT */}
<img <img