Feature/brutalism overhaul #10
@@ -12,6 +12,7 @@ import { Link } from './Link';
|
||||
|
||||
const PRIMARY = 'underline underline-offset-2 hover:opacity-60 transition-opacity';
|
||||
const SECONDARY = 'no-underline opacity-60 hover:opacity-100 sm:brutal-border-bottom transition-opacity';
|
||||
const TERTIARY = 'no-underline opacity-100 hover:opacity-60 sm:brutal-border-bottom transition-opacity';
|
||||
|
||||
describe('internal link', () => {
|
||||
it('renders an anchor element', () => {
|
||||
@@ -92,6 +93,18 @@ describe('variant', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('tertiary applies reversed-hover classes', () => {
|
||||
render(
|
||||
<Link href="/about" variant="tertiary">
|
||||
About
|
||||
</Link>,
|
||||
);
|
||||
const link = screen.getByRole('link', { name: 'About' });
|
||||
for (const cls of TERTIARY.split(' ')) {
|
||||
expect(link).toHaveClass(cls);
|
||||
}
|
||||
});
|
||||
|
||||
it('secondary does not apply underline', () => {
|
||||
render(
|
||||
<Link href="/about" variant="secondary">
|
||||
|
||||
@@ -2,7 +2,7 @@ import NextLink from 'next/link';
|
||||
import type { ReactNode } from 'react';
|
||||
import { cn } from '$shared/lib';
|
||||
|
||||
export type LinkVariant = 'primary' | 'secondary';
|
||||
export type LinkVariant = 'primary' | 'secondary' | 'tertiary';
|
||||
|
||||
/**
|
||||
* Props for Link.
|
||||
@@ -24,6 +24,7 @@ interface Props {
|
||||
* Visual variant.
|
||||
* primary — text-decoration underline.
|
||||
* secondary — border-bottom at sm+, no underline on mobile (for icon+label links).
|
||||
* tertiary — like secondary but reversed: bright by default, dims on hover.
|
||||
* @default 'primary'
|
||||
*/
|
||||
variant?: LinkVariant;
|
||||
@@ -37,6 +38,7 @@ interface Props {
|
||||
const VARIANTS = {
|
||||
primary: 'underline underline-offset-2 hover:opacity-60 transition-opacity',
|
||||
secondary: 'no-underline opacity-60 hover:opacity-100 sm:brutal-border-bottom transition-opacity',
|
||||
tertiary: 'no-underline opacity-100 hover:opacity-60 sm:brutal-border-bottom transition-opacity',
|
||||
} as const satisfies Record<LinkVariant, string>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function Footer() {
|
||||
<div className="w-full flex flex-row justify-between gap-4">
|
||||
<div className="flex flex-wrap items-center gap-6 sm:gap-4">
|
||||
{email && (
|
||||
<Link href={email.url} external variant="secondary" className="flex items-center gap-1.5 text-sm">
|
||||
<Link href={email.url} external variant="tertiary" className="flex items-center gap-1.5 text-sm">
|
||||
{email.icon && <InlineSvg svg={email.icon} className="inline-flex w-8 h-8 sm:hidden" />}
|
||||
<span className="hidden sm:block">{email.label}</span>
|
||||
</Link>
|
||||
@@ -33,7 +33,7 @@ export async function Footer() {
|
||||
key={social.id}
|
||||
href={social.url}
|
||||
external
|
||||
variant="secondary"
|
||||
variant="tertiary"
|
||||
className="flex items-center gap-1.5 text-sm"
|
||||
>
|
||||
{social.icon && <InlineSvg svg={social.icon} className="inline-flex w-8 h-8 sm:hidden" />}
|
||||
|
||||
Reference in New Issue
Block a user