1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2024-11-05 04:51:30 +01:00

chore: usage of eslint-plugin-tailwindcss

This commit is contained in:
Théo LUDWIG 2024-01-28 03:21:11 +01:00
parent b8ceefb2f6
commit f5020cad19
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
30 changed files with 320 additions and 352 deletions

View File

@ -1,9 +1,23 @@
{ {
"extends": ["conventions", "next/core-web-vitals", "prettier"], "root": true,
"extends": [
"conventions",
"next/core-web-vitals",
"plugin:tailwindcss/recommended",
"prettier"
],
"plugins": ["prettier"], "plugins": ["prettier"],
"parserOptions": { "parserOptions": {
"project": "./tsconfig.json" "project": "./tsconfig.json"
}, },
"settings": {
"tailwindcss": {
"callees": ["classNames"]
},
"react": {
"version": "detect"
}
},
"rules": { "rules": {
"prettier/prettier": "error", "prettier/prettier": "error",
"react/self-closing-comp": [ "react/self-closing-comp": [

View File

@ -1,4 +1,3 @@
#!/bin/sh #!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"
npm run lint:commit -- --edit npm run lint:commit -- --edit

View File

@ -1,4 +1,3 @@
#!/bin/sh #!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"
npm run lint:staged npm run lint:staged

View File

@ -1,3 +1,4 @@
{ {
"semi": false "semi": false,
"plugins": ["prettier-plugin-tailwindcss"]
} }

View File

@ -2,7 +2,7 @@ import { Loader } from "@/components/design/Loader"
const Loading = (): JSX.Element => { const Loading = (): JSX.Element => {
return ( return (
<main className="flex flex-col flex-1 items-center justify-center"> <main className="flex flex-1 flex-col items-center justify-center">
<Loader /> <Loader />
</main> </main>
) )

View File

@ -2,7 +2,7 @@ import { Loader } from "@/components/design/Loader"
const Loading = (): JSX.Element => { const Loading = (): JSX.Element => {
return ( return (
<main className="flex flex-col flex-1 items-center justify-center"> <main className="flex flex-1 flex-col items-center justify-center">
<Loader /> <Loader />
</main> </main>
) )

View File

@ -14,7 +14,7 @@ const ErrorHandling = (props: ErrorHandlingProps): JSX.Element => {
}, [error]) }, [error])
return ( return (
<main className="flex flex-col flex-1 items-center justify-center"> <main className="flex flex-1 flex-col items-center justify-center">
<h1 className="my-6 text-4xl font-semibold"> <h1 className="my-6 text-4xl font-semibold">
Error{" "} Error{" "}
<span <span

View File

@ -29,7 +29,7 @@
.prose a, .prose a,
.prose strong { .prose strong {
@apply text-yellow dark:text-yellow-dark font-semibold; @apply font-semibold text-yellow dark:text-yellow-dark;
} }
strong, strong,

View File

@ -65,7 +65,7 @@ const RootLayout = (props: RootLayoutProps): JSX.Element => {
colorScheme: theme, colorScheme: theme,
}} }}
> >
<body className="bg-white font-headline text-black dark:bg-black dark:text-white flex flex-col min-h-screen"> <body className="flex min-h-screen flex-col bg-white font-headline text-black dark:bg-black dark:text-white">
<Header /> <Header />
{children} {children}
<Footer /> <Footer />

View File

@ -2,7 +2,7 @@ import { Loader } from "@/components/design/Loader"
const Loading = (): JSX.Element => { const Loading = (): JSX.Element => {
return ( return (
<main className="flex flex-col flex-1 items-center justify-center"> <main className="flex flex-1 flex-col items-center justify-center">
<Loader /> <Loader />
</main> </main>
) )

View File

@ -6,7 +6,7 @@ const NotFound = (): JSX.Element => {
const i18n = getI18n() const i18n = getI18n()
return ( return (
<main className="flex flex-col flex-1 items-center justify-center"> <main className="flex flex-1 flex-col items-center justify-center">
<h1 className="my-6 text-4xl font-semibold"> <h1 className="my-6 text-4xl font-semibold">
{i18n.translate("errors.error")}{" "} {i18n.translate("errors.error")}{" "}
<span <span

View File

@ -31,7 +31,7 @@ const Heading = (
href={`#${id}`} href={`#${id}`}
className="invisible !text-black group-hover:visible dark:!text-white" className="invisible !text-black group-hover:visible dark:!text-white"
> >
<FontAwesomeIcon className="mr-2 inline h-4 w-4" icon={faLink} /> <FontAwesomeIcon className="mr-2 inline size-4" icon={faLink} />
</Link> </Link>
{children} {children}
</h2> </h2>
@ -90,7 +90,7 @@ export const BlogPostContent = async (
alt={alt} alt={alt}
width={1000} width={1000}
height={1000} height={1000}
className="h-auto w-auto" className="size-auto"
/> />
</span> </span>
) )

View File

@ -9,7 +9,7 @@ export const FooterText = (): JSX.Element => {
<p> <p>
<Link <Link
href="/" href="/"
className="text-yellow hover:underline dark:text-yellow-dark font-semibold" className="font-semibold text-yellow hover:underline dark:text-yellow-dark"
> >
Théo LUDWIG Théo LUDWIG
</Link>{" "} </Link>{" "}

View File

@ -16,7 +16,7 @@ export const FooterVersion = (props: FooterVersionProps): JSX.Element => {
Version{" "} Version{" "}
<a <a
data-cy="version-link" data-cy="version-link"
className="text-yellow hover:underline dark:text-yellow-dark font-semibold" className="font-semibold text-yellow hover:underline dark:text-yellow-dark"
href={versionLink} href={versionLink}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"

View File

@ -82,7 +82,7 @@ export const Locales = (props: LocalesProps): JSX.Element => {
return ( return (
<li <li
key={locale} key={locale}
className="flex h-12 w-full items-center justify-center hover:bg-[#4f545c] hover:bg-opacity-20" className="flex h-12 w-full items-center justify-center hover:bg-[#4f545c]/20"
onClick={async () => { onClick={async () => {
return await handleLocale(locale) return await handleLocale(locale)
}} }}

View File

@ -30,35 +30,35 @@ export const SwitchTheme = (props: SwitchThemeProps): JSX.Element => {
<div <div
data-cy="switch-theme-dark" data-cy="switch-theme-dark"
className={classNames( className={classNames(
"absolute bottom-0 left-[8px] top-0 mb-auto mt-auto h-[10px] w-[14px] leading-[0] transition-opacity duration-[250ms] ease-in-out", "absolute inset-y-0 left-[8px] my-auto h-[10px] w-[14px] leading-[0] transition-opacity duration-[250ms] ease-in-out",
{ {
"opacity-100": theme === "dark", "opacity-100": theme === "dark",
"opacity-0": theme === "light", "opacity-0": theme === "light",
}, },
)} )}
> >
<span className="relative flex h-[10px] w-[10px] items-center justify-center"> <span className="relative flex size-[10px] items-center justify-center">
🌜 🌜
</span> </span>
</div> </div>
<div <div
data-cy="switch-theme-light" data-cy="switch-theme-light"
className={classNames( className={classNames(
"absolute bottom-0 right-[10px] top-0 mb-auto mt-auto h-[10px] w-[10px] leading-[0]", "absolute inset-y-0 right-[10px] my-auto size-[10px] leading-[0]",
{ {
"opacity-100": theme === "light", "opacity-100": theme === "light",
"opacity-0": theme === "dark", "opacity-0": theme === "dark",
}, },
)} )}
> >
<span className="relative flex h-[10px] w-[10px] items-center justify-center"> <span className="relative flex size-[10px] items-center justify-center">
🌞 🌞
</span> </span>
</div> </div>
</div> </div>
<div <div
className={classNames( className={classNames(
"absolute top-[1px] box-border h-[22px] w-[22px] rounded-[50%] bg-[#fafafa] text-white transition-all duration-[250ms] ease-in-out", "absolute top-[1px] box-border size-[22px] rounded-[50%] bg-[#fafafa] text-white transition-all duration-[250ms] ease-in-out",
{ {
"left-[27px]": theme === "dark", "left-[27px]": theme === "dark",
"left-0": theme === "light", "left-0": theme === "light",
@ -70,7 +70,7 @@ export const SwitchTheme = (props: SwitchThemeProps): JSX.Element => {
data-cy="switch-theme-input" data-cy="switch-theme-input"
type="checkbox" type="checkbox"
aria-label="Dark mode toggle" aria-label="Dark mode toggle"
className="absolute m-[-1px] h-[1px] w-[1px] overflow-hidden border-0 p-0 hidden" className="absolute m-[-1px] hidden size-[1px] overflow-hidden border-0 p-0"
defaultChecked defaultChecked
/> />
</div> </div>

View File

@ -18,7 +18,7 @@ export const Header = (): JSX.Element => {
<div className="flex items-center justify-center"> <div className="flex items-center justify-center">
<Image <Image
quality={100} quality={100}
className="w-16 h-16" className="size-16"
src={Logo} src={Logo}
alt="Théo LUDWIG" alt="Théo LUDWIG"
priority priority

View File

@ -10,9 +10,9 @@ export const InterestItem = (props: InterestItemProps): JSX.Element => {
const { fontAwesomeIcon, title } = props const { fontAwesomeIcon, title } = props
return ( return (
<li className="interest-item mx-2 my-2 h-8 w-8" title={title}> <li className="m-2 size-8" title={title}>
<FontAwesomeIcon <FontAwesomeIcon
className="block h-full w-full text-yellow dark:text-yellow-dark" className="block size-full text-yellow dark:text-yellow-dark"
icon={fontAwesomeIcon} icon={fontAwesomeIcon}
/> />
</li> </li>

View File

@ -15,7 +15,7 @@ export const Repository = (props: RepositoryProps): JSX.Element => {
<a href={href} target="_blank" rel="noopener noreferrer"> <a href={href} target="_blank" rel="noopener noreferrer">
<div className="flex"> <div className="flex">
<GitHubIcon className="mr-2 h-6" /> <GitHubIcon className="mr-2 h-6" />
<span className="text-yellow dark:text-yellow-dark font-semibold"> <span className="font-semibold text-yellow dark:text-yellow-dark">
{name} {name}
</span> </span>
</div> </div>

View File

@ -24,7 +24,7 @@ export const PortfolioItem = (props: PortfolioItemProps): JSX.Element => {
<div className="flex justify-center"> <div className="flex justify-center">
<Image <Image
quality={100} quality={100}
className="h-auto w-auto transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5" className="size-auto transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5"
width={300} width={300}
height={300} height={300}
src={image} src={image}
@ -35,7 +35,7 @@ export const PortfolioItem = (props: PortfolioItemProps): JSX.Element => {
<h3 className="my-6 text-2xl font-semibold text-yellow dark:text-yellow-dark"> <h3 className="my-6 text-2xl font-semibold text-yellow dark:text-yellow-dark">
{title} {title}
</h3> </h3>
<p className="my-6 mx-4 font-semibold">{description}</p> <p className="mx-4 my-6 font-semibold">{description}</p>
</div> </div>
</a> </a>
</ShadowContainer> </ShadowContainer>

View File

@ -6,13 +6,13 @@ export const ProfileDescriptionBottom = (): JSX.Element => {
const i18n = getI18n() const i18n = getI18n()
return ( return (
<div className="my-6 text-gray dark:text-gray-dark text-center max-w-md text-base"> <div className="my-6 max-w-md text-center text-base text-gray dark:text-gray-dark">
<p>{htmlParser(i18n.translate("home.about.description-bottom"))}</p> <p>{htmlParser(i18n.translate("home.about.description-bottom"))}</p>
<br /> <br />
<a <a
href="/curriculum-vitae/index.html" href="/curriculum-vitae/index.html"
className="text-yellow hover:underline dark:text-yellow-dark font-semibold" className="font-semibold text-yellow hover:underline dark:text-yellow-dark"
> >
Curriculum vitæ ({i18n.translate("common.fr-FR")}) Curriculum vitæ ({i18n.translate("common.fr-FR")})
</a> </a>

View File

@ -8,7 +8,7 @@ export const Icon = (props: React.SVGProps<SVGSVGElement>): JSX.Element => {
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
className={classNames( className={classNames(
"h-8 w-8 fill-current text-black dark:text-white", "size-8 fill-current text-black dark:text-white",
className, className,
)} )}
{...rest} {...rest}

View File

@ -9,7 +9,7 @@ import { NPMIcon } from "./SocialMediaIcons/NPMIcon"
export const SocialMediaList = (): JSX.Element => { export const SocialMediaList = (): JSX.Element => {
return ( return (
<ul className="social-media-list m-0 mt-2 list-none py-4 text-center"> <ul className="m-0 mt-2 list-none py-4 text-center">
<SocialMediaItem link="https://github.com/theoludwig" ariaLabel="GitHub"> <SocialMediaItem link="https://github.com/theoludwig" ariaLabel="GitHub">
<GitHubIcon /> <GitHubIcon />
</SocialMediaItem> </SocialMediaItem>

View File

@ -35,7 +35,7 @@ export const SkillComponent = (props: SkillComponentProps): JSX.Element => {
> >
<div className="text-center"> <div className="text-center">
<Image <Image
className="inline h-16 w-16" className="inline size-16"
quality={100} quality={100}
width={64} width={64}
height={64} height={64}

View File

@ -13,7 +13,7 @@ export const SkillsSection = (props: SkillsSectionProps): JSX.Element => {
<div className="mx-auto w-full px-4"> <div className="mx-auto w-full px-4">
<div className="flex flex-wrap px-4 py-6"> <div className="flex flex-wrap px-4 py-6">
<div className="flex-1"> <div className="flex-1">
<div className="mb-8 border-b border-gray-600 dark:border-white dark:border-opacity-10"> <div className="mb-8 border-b border-gray-600 dark:border-white/10">
<h3 className="my-3 text-xl font-semibold text-yellow dark:text-yellow-dark"> <h3 className="my-3 text-xl font-semibold text-yellow dark:text-yellow-dark">
{title} {title}
</h3> </h3>

View File

@ -16,7 +16,7 @@ export const Loader = (props: LoaderProps): JSX.Element => {
height, height,
}} }}
className={classNames( className={classNames(
"animate-spin inline-block border-[3px] border-current border-t-transparent text-yellow dark:text-yellow-dark rounded-full", "inline-block animate-spin rounded-full border-[3px] border-current border-t-transparent text-yellow dark:text-yellow-dark",
className, className,
)} )}
role="status" role="status"

View File

@ -12,7 +12,7 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.11.5", "@types/node": "20.11.8",
"date-and-time": "3.1.1", "date-and-time": "3.1.1",
"vite": "5.0.12", "vite": "5.0.12",
"vite-plugin-html": "3.2.2" "vite-plugin-html": "3.2.2"
@ -668,9 +668,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.11.5", "version": "20.11.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.8.tgz",
"integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", "integrity": "sha512-i7omyekpPTNdv4Jb/Rgqg0RU8YqLcNsI12quKSDkRXNfx7Wxdm6HhK1awT3xTgEkgxPn3bvnSpiEAc7a7Lpyow==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
@ -941,9 +941,9 @@
} }
}, },
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.4.0", "version": "16.4.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.0.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz",
"integrity": "sha512-WvImr5kpN5NGNn7KaDjJnLTh5rDVLZiDf/YLA8T1ZEZEBZNEDOE+mnkS0PVjPax8ZxBP5zC5SLMB3/9VV5de9g==", "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
@ -1046,9 +1046,9 @@
} }
}, },
"node_modules/fastq": { "node_modules/fastq": {
"version": "1.16.0", "version": "1.17.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz",
"integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"reusify": "^1.0.4" "reusify": "^1.0.4"

View File

@ -13,7 +13,7 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.11.5", "@types/node": "20.11.8",
"date-and-time": "3.1.1", "date-and-time": "3.1.1",
"vite": "5.0.12", "vite": "5.0.12",
"vite-plugin-html": "3.2.2" "vite-plugin-html": "3.2.2"

550
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@
"test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"", "test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"",
"curriculum-vitae:build": "node ./curriculum-vitae/build.js", "curriculum-vitae:build": "node ./curriculum-vitae/build.js",
"release": "semantic-release", "release": "semantic-release",
"postinstall": "husky install" "postinstall": "husky"
}, },
"dependencies": { "dependencies": {
"@fontsource/montserrat": "5.0.16", "@fontsource/montserrat": "5.0.16",
@ -57,18 +57,18 @@
"shiki": "0.14.7", "shiki": "0.14.7",
"unified": "10.1.2", "unified": "10.1.2",
"unist-util-visit": "5.0.0", "unist-util-visit": "5.0.0",
"universal-cookie": "7.0.1" "universal-cookie": "7.0.2"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "18.5.0", "@commitlint/cli": "18.6.0",
"@commitlint/config-conventional": "18.5.0", "@commitlint/config-conventional": "18.6.0",
"@saithodev/semantic-release-backmerge": "4.0.1", "@saithodev/semantic-release-backmerge": "4.0.1",
"@semantic-release/git": "10.0.1", "@semantic-release/git": "10.0.1",
"@tailwindcss/typography": "0.5.10", "@tailwindcss/typography": "0.5.10",
"@total-typescript/ts-reset": "0.5.1", "@total-typescript/ts-reset": "0.5.1",
"@tsconfig/strictest": "2.0.2", "@tsconfig/strictest": "2.0.2",
"@types/negotiator": "0.6.3", "@types/negotiator": "0.6.3",
"@types/node": "20.11.5", "@types/node": "20.11.8",
"@types/react": "18.2.48", "@types/react": "18.2.48",
"@types/unist": "3.0.2", "@types/unist": "3.0.2",
"@typescript-eslint/eslint-plugin": "6.19.1", "@typescript-eslint/eslint-plugin": "6.19.1",
@ -84,9 +84,10 @@
"eslint-plugin-import": "2.29.1", "eslint-plugin-import": "2.29.1",
"eslint-plugin-prettier": "5.1.3", "eslint-plugin-prettier": "5.1.3",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-tailwindcss": "3.14.1",
"eslint-plugin-unicorn": "50.0.1", "eslint-plugin-unicorn": "50.0.1",
"html-w3c-validator": "1.5.1", "html-w3c-validator": "1.5.1",
"husky": "8.0.3", "husky": "9.0.6",
"lint-staged": "15.2.0", "lint-staged": "15.2.0",
"markdownlint-cli2": "0.12.1", "markdownlint-cli2": "0.12.1",
"markdownlint-rule-relative-links": "2.2.0", "markdownlint-rule-relative-links": "2.2.0",