Skip to content

Commit

Permalink
♻️ refacto button component
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudbrault committed Jul 6, 2023
1 parent 19d116b commit 9c8e0c3
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 83 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
"@hookform/resolvers": "3.1.1",
"@meronex/icons": "4.0.0",
"@radix-ui/react-separator": "1.0.3",
"@radix-ui/react-slot": "1.0.2",
"@tanstack/match-sorter-utils": "8.7.6",
"@tanstack/react-query": "4.29.7",
"@tanstack/react-query-devtools": "4.29.7",
"@tanstack/react-table": "8.7.9",
"axios": "^1.4.0",
"class-variance-authority": "0.6.1",
"firebase": "9.22.0",
"fuse.js": "6.6.2",
"hamburger-react": "2.5.0",
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 22 additions & 28 deletions src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
@use '@/styles/abstracts' as *;

.back {
.base {
display: flex;
align-items: center;
width: fit-content;
justify-content: center;
padding: 1rem 1.5rem;
font-size: 1.5rem;
font-weight: 600;
background: none;
border-radius: 5px;
transition: 0.3s ease-in-out;
cursor: pointer;
}

.back {
width: fit-content;
gap: 1rem;
background: none;
@include themed {
color: t('text');
border: 1px solid t('text');
Expand All @@ -25,46 +30,35 @@
}
}

%connect {
display: flex;
align-items: center;
justify-content: center;
padding: 0.7rem 1.5rem;
.primary {
border: 1px solid transparent;
border-radius: 5px;
font-size: 1.5rem;
font-weight: 600;
cursor: pointer;
transition: 0.3s ease-in-out;

@include themed {
background-color: t('text');
color: t('bg');
}

&:hover {
background: transparent;

@include themed {
border-color: t('text');
color: t('text');
}
}

@include md {
font-size: 3rem;
}
}

.login {
@extend %connect;
.secondary {
@include themed {
background-color: t('bg');
border-color: t('text');
border: 1px solid t('text');
color: t('text');
}
}

.register {
@extend %connect;

&:hover {
background: transparent;

@include themed {
border-color: t('text');
color: t('text');
}
@include md {
font-size: 3rem;
}
}
42 changes: 23 additions & 19 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
import { FaChevronLeft } from '@meronex/icons/fa';
import Link, { LinkProps } from 'next/link';
import { HTMLProps, Ref, forwardRef } from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import { forwardRef } from 'react';
import styles from './Button.module.scss';

type ILink = {
title: string;
icon?: boolean;
className: string;
ref?: Ref<HTMLAnchorElement>;
} & LinkProps &
HTMLProps<HTMLAnchorElement>;
const button = cva(styles.base, {
variants: {
intent: {
back: styles.back,
primary: styles.primary,
secondary: styles.secondary,
},
},
});

interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof button> {
asChild?: boolean;
}

export const LinkButton = forwardRef<HTMLAnchorElement, ILink>(
({ title, icon, className, ...rest }, ref) => {
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, intent, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : `button`;
return (
<Link className={styles[className]} ref={ref} {...rest}>
{icon && <ButtonIcon />}
{title}
</Link>
<Comp className={button({ intent, className })} ref={ref} {...props} />
);
},
);

const ButtonIcon = () => {
return <FaChevronLeft />;
};
Button.displayName = `Button`;
4 changes: 4 additions & 0 deletions src/contexts/Theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ export const ThemeProvider = ({ children }: Props) => {
if (!!savedThemeLocal) {
setTheme(savedThemeLocal);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
localStorage.setItem(`globalTheme`, theme);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [theme]);

return (
Expand Down
22 changes: 13 additions & 9 deletions src/modules/layout/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useState,
} from 'react';
import styles from './Header.module.scss';
import { LinkButton } from '@/components';
import { Button } from '@/components';

type Props = {
navOpen: boolean;
Expand Down Expand Up @@ -63,17 +63,21 @@ export function Header({ navOpen, setNavOpen }: Props) {
</button>
{user ? (
<div className={styles.connected}>
<button onClick={logout}>Sign Out</button>
<Link href="/profile">Profile</Link>
<Button intent="secondary" onClick={logout}>
Sign Out
</Button>
<Button intent="primary" asChild>
<Link href="/profile">Profile</Link>
</Button>
</div>
) : (
<div className={styles.connect}>
<LinkButton href="/login" className="login" title="Login" />
<LinkButton
href="/register"
className="register"
title="Register"
/>
<Button intent="secondary" asChild>
<Link href="/login">Login</Link>
</Button>
<Button intent="primary" asChild>
<Link href="/register">Register</Link>
</Button>
</div>
)}
{navOpen ? (
Expand Down
2 changes: 2 additions & 0 deletions src/modules/types/type/components/Pokemon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ export function Pokemon({ typeName, pokemon }: Props) {
if (typeName) {
fixCurType(typeName, true);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [typeName]);

return (
Expand Down
16 changes: 9 additions & 7 deletions src/pages/ability/[name].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinkButton, Loader, Separator } from '@/components';
import { Button, Loader, Separator } from '@/components';
import {
Description,
Heading,
Expand All @@ -7,7 +7,9 @@ import {
} from '@/modules/abilities/ability';
import styles from '@/modules/abilities/ability/Ability.module.scss';
import { removeDash } from '@/utils';
import { FaChevronLeft } from '@meronex/icons/fa';
import { GetServerSidePropsContext } from 'next';
import Link from 'next/link';
import toast from 'react-hot-toast';

type Props = {
Expand Down Expand Up @@ -76,12 +78,12 @@ function Ability({ name }: Props) {
</h3>
<Table ability={ability} pokemon={pokemon} />
</section>
<LinkButton
href="/abilities"
className="back"
title="Back to Abilities"
icon
/>
<Button intent="back" asChild>
<Link href="/abilities">
<FaChevronLeft />
Back to Abilities
</Link>
</Button>
</main>
</>
);
Expand Down
16 changes: 9 additions & 7 deletions src/pages/item/[name].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinkButton, Loader } from '@/components';
import { Button, Loader } from '@/components';
import {
Cost,
Description,
Expand All @@ -10,8 +10,10 @@ import {

import styles from '@/modules/items/item/Item.module.scss';
import { removeDash } from '@/utils';
import { FaChevronLeft } from '@meronex/icons/fa';
import { GetServerSidePropsContext } from 'next';
import Image from 'next/image';
import Link from 'next/link';
import toast from 'react-hot-toast';

type Props = {
Expand Down Expand Up @@ -62,12 +64,12 @@ function ItemCard({ name }: Props) {
</div>
</section>
<Description item={item} />
<LinkButton
href="/items"
className="back"
title="Back to Items"
icon
/>
<Button intent="back" asChild>
<Link href="/items">
<FaChevronLeft />
Back to Items
</Link>
</Button>
</main>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions src/pages/location/[name].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LinkButton, Loader, Nav } from '@/components';
import { Button, Loader, Nav } from '@/components';
import { useTableParams } from '@/hooks';
import styles from '@/modules/locations/Locations.module.scss';
import { Area, Heading, useSwitchGame } from '@/modules/locations/location';
Expand Down Expand Up @@ -222,7 +222,7 @@ function LocationCard({ name }: Props) {
</table>
</div>
</section>
<LinkButton
<Button
href="/locations"

Check failure on line 226 in src/pages/location/[name].tsx

View workflow job for this annotation

GitHub Actions / Run Type Check & Linters

Type '{ href: string; className: string; title: string; icon: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps & RefAttributes<HTMLButtonElement>'.
className="back"
title="Back to Locations"
Expand Down
16 changes: 9 additions & 7 deletions src/pages/move/[name].tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { LinkButton, Loader, Separator } from '@/components';
import { Button, Loader, Separator } from '@/components';
import { Data, Heading, List, Nav, useFetchMove } from '@/modules/moves/move';
import styles from '@/modules/moves/move/Move.module.scss';
import { removeDash } from '@/utils';
import { FaChevronLeft } from '@meronex/icons/fa';
import { GetServerSidePropsContext } from 'next';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { useState } from 'react';
import toast from 'react-hot-toast';

Expand Down Expand Up @@ -72,12 +74,12 @@ function MoveCard({ name }: Props) {
version={version}
/>

<LinkButton
href="/moves"
className="back"
title="Back to Moves"
icon
/>
<Button intent="back" asChild>
<Link href="/moves">
<FaChevronLeft />
Back to Moves
</Link>
</Button>
</main>
)}
</>
Expand Down
Loading

0 comments on commit 9c8e0c3

Please sign in to comment.