Browse Source

refactor: update Tailwind to v4

C4illin 5 months ago
parent
commit
e595014fcd
9 changed files with 138 additions and 133 deletions
  1. BIN
      bun.lockb
  2. 5 3
      package.json
  3. 4 7
      postcss.config.js
  4. 40 40
      src/components/base.tsx
  5. 1 1
      src/components/header.tsx
  6. 2 2
      src/helpers/tailwind.ts
  7. 14 14
      src/index.tsx
  8. 72 39
      src/main.css
  9. 0 27
      tailwind.config.js

BIN
bun.lockb


+ 5 - 3
package.json

@@ -5,7 +5,7 @@
     "dev": "bun run --watch src/index.tsx",
     "hot": "bun run --hot src/index.tsx",
     "format": "eslint --fix .",
-    "build": "postcss ./src/main.css -o ./public/generated.css",
+    "build": "bunx @tailwindcss/cli -i ./src/main.css -o ./public/generated.css",
     "lint": "run-p 'lint:*'",
     "lint:tsc": "tsc --noEmit",
     "lint:knip": "knip",
@@ -29,6 +29,8 @@
     "@eslint/js": "^9.18.0",
     "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
     "@kitajs/ts-html-plugin": "^4.1.1",
+    "@tailwindcss/cli": "^4.0.3",
+    "@tailwindcss/postcss": "^4.0.3",
     "@total-typescript/ts-reset": "^0.6.1",
     "@types/bun": "^1.2.0",
     "@types/eslint-plugin-tailwindcss": "^3.17.0",
@@ -47,8 +49,8 @@
     "postcss": "^8.5.1",
     "postcss-cli": "^11.0.0",
     "prettier": "^3.4.2",
-    "tailwind-scrollbar": "^3.1.0",
-    "tailwindcss": "^3.4.17",
+    "tailwind-scrollbar": "^4.0.0",
+    "tailwindcss": "^4.0.0",
     "typescript": "^5.7.3",
     "typescript-eslint": "^8.21.0"
   }

+ 4 - 7
postcss.config.js

@@ -1,8 +1,5 @@
-import autoprefixer from "autoprefixer";
-import cssnano from "cssnano";
-import tailwind from "tailwindcss";
-import tailwindConfig from "./tailwind.config.js";
-
 export default {
-  plugins: [autoprefixer, tailwind(tailwindConfig), cssnano],
-};
+  plugins: {
+    "@tailwindcss/postcss": {},
+  },
+};

+ 40 - 40
src/components/base.tsx

@@ -1,40 +1,40 @@
-import { Html } from "@elysiajs/html";
-
-export const BaseHtml = ({
-  children,
-  title = "ConvertX",
-  webroot = "",
-}: {
-  children: JSX.Element;
-  title?: string;
-  webroot?: string;
-}) => (
-  <html lang="en">
-    <head>
-      <meta charset="UTF-8" />
-      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-      <meta name="webroot" content={webroot} />
-      <title safe>{title}</title>
-      <link rel="stylesheet" href={`${webroot}/generated.css`} />
-      <link
-        rel="apple-touch-icon"
-        sizes="180x180"
-        href={`${webroot}/apple-touch-icon.png`}
-      />
-      <link
-        rel="icon"
-        type="image/png"
-        sizes="32x32"
-        href={`${webroot}/favicon-32x32.png`}
-      />
-      <link
-        rel="icon"
-        type="image/png"
-        sizes="16x16"
-        href={`${webroot}/favicon-16x16.png`}
-      />
-      <link rel="manifest" href={`${webroot}/site.webmanifest`} />
-    </head>
-    <body class="w-full bg-neutral-900 text-neutral-200">{children}</body>
-  </html>
-);
+import { Html } from "@elysiajs/html";
+
+export const BaseHtml = ({
+  children,
+  title = "ConvertX",
+  webroot = "",
+}: {
+  children: JSX.Element;
+  title?: string;
+  webroot?: string;
+}) => (
+  <html lang="en">
+    <head>
+      <meta charset="UTF-8" />
+      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+      <meta name="webroot" content={webroot} />
+      <title safe>{title}</title>
+      <link rel="stylesheet" href={`${webroot}/generated.css`} />
+      <link
+        rel="apple-touch-icon"
+        sizes="180x180"
+        href={`${webroot}/apple-touch-icon.png`}
+      />
+      <link
+        rel="icon"
+        type="image/png"
+        sizes="32x32"
+        href={`${webroot}/favicon-32x32.png`}
+      />
+      <link
+        rel="icon"
+        type="image/png"
+        sizes="16x16"
+        href={`${webroot}/favicon-16x16.png`}
+      />
+      <link rel="manifest" href={`${webroot}/site.webmanifest`} />
+    </head>
+    <body class="w-full bg-neutral-900 text-neutral-200">{children}</body>
+  </html>
+);

+ 1 - 1
src/components/header.tsx

@@ -74,7 +74,7 @@ export const Header = ({
 
   return (
     <header class="w-full p-4">
-      <nav class="mx-auto flex max-w-4xl justify-between rounded bg-neutral-900 p-4">
+      <nav class="mx-auto flex max-w-4xl justify-between rounded-sm bg-neutral-900 p-4">
         <ul>
           <li>
             <strong>

+ 2 - 2
src/helpers/tailwind.ts

@@ -1,4 +1,4 @@
-import tw from "tailwindcss";
+import tailwind from "@tailwindcss/postcss";
 import postcss from "postcss";
 
 export const generateTailwind = async () => {
@@ -7,7 +7,7 @@ export const generateTailwind = async () => {
     .then((sourceText) => {
       const config = "./tailwind.config.js";
 
-      return postcss([tw(config)]).process(sourceText, {
+      return postcss([tailwind]).process(sourceText, {
         from: "./src/main.css",
         to: "./public/generated.css",
       });

+ 14 - 14
src/index.tsx

@@ -166,7 +166,7 @@ const app = new Elysia({
                   <input
                     type="email"
                     name="email"
-                    class="rounded bg-neutral-800 p-3"
+                    class="rounded-sm bg-neutral-800 p-3"
                     placeholder="Email"
                     autocomplete="email"
                     required
@@ -177,7 +177,7 @@ const app = new Elysia({
                   <input
                     type="password"
                     name="password"
-                    class="rounded bg-neutral-800 p-3"
+                    class="rounded-sm bg-neutral-800 p-3"
                     placeholder="Password"
                     autocomplete="current-password"
                     required
@@ -226,7 +226,7 @@ const app = new Elysia({
                     <input
                       type="email"
                       name="email"
-                      class="rounded bg-neutral-800 p-3"
+                      class="rounded-sm bg-neutral-800 p-3"
                       placeholder="Email"
                       autocomplete="email"
                       required
@@ -237,7 +237,7 @@ const app = new Elysia({
                     <input
                       type="password"
                       name="password"
-                      class="rounded bg-neutral-800 p-3"
+                      class="rounded-sm bg-neutral-800 p-3"
                       placeholder="Password"
                       autocomplete="current-password"
                       required
@@ -352,7 +352,7 @@ const app = new Elysia({
                     <input
                       type="email"
                       name="email"
-                      class="rounded bg-neutral-800 p-3"
+                      class="rounded-sm bg-neutral-800 p-3"
                       placeholder="Email"
                       autocomplete="email"
                       required
@@ -363,7 +363,7 @@ const app = new Elysia({
                     <input
                       type="password"
                       name="password"
-                      class="rounded bg-neutral-800 p-3"
+                      class="rounded-sm bg-neutral-800 p-3"
                       placeholder="Password"
                       autocomplete="current-password"
                       required
@@ -565,7 +565,7 @@ const app = new Elysia({
                   class={`
                     w-full table-auto rounded bg-neutral-900
                     [&_td]:p-4
-                    [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
+                    [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
                   `}
                 />
               </div>
@@ -601,12 +601,12 @@ const app = new Elysia({
                   name="convert_to_search"
                   placeholder="Search for conversions"
                   autocomplete="off"
-                  class="w-full rounded bg-neutral-800 p-4"
+                  class="w-full rounded-sm bg-neutral-800 p-4"
                 />
                 <div class="select_container relative">
                   <article
                     class={`
-                      convert_to_popup absolute z-[2] m-0 hidden h-[30vh] max-h-[50vh] w-full
+                      convert_to_popup absolute z-2 m-0 hidden h-[30vh] max-h-[50vh] w-full
                       flex-col overflow-y-auto overflow-x-hidden rounded bg-neutral-800
                       sm:h-[30vh]
                     `}
@@ -693,7 +693,7 @@ const app = new Elysia({
         <>
           <article
             class={`
-              convert_to_popup absolute z-[2] m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col
+              convert_to_popup absolute z-2 m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col
               overflow-y-auto overflow-x-hidden rounded bg-neutral-800
               sm:h-[30vh]
             `}
@@ -971,7 +971,7 @@ const app = new Elysia({
                 class={`
                   w-full table-auto rounded bg-neutral-900 text-left
                   [&_td]:p-4
-                  [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
+                  [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
                 `}
               >
                 <thead>
@@ -1090,7 +1090,7 @@ const app = new Elysia({
                   class={`
                     w-full table-auto rounded bg-neutral-900 text-left
                     [&_td]:p-4
-                    [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
+                    [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
                   `}
                 >
                   <thead>
@@ -1212,7 +1212,7 @@ const app = new Elysia({
             class={`
               w-full table-auto rounded bg-neutral-900 text-left
               [&_td]:p-4
-              [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
+              [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
             `}
           >
             <thead>
@@ -1312,7 +1312,7 @@ const app = new Elysia({
                 class={`
                   w-full table-auto rounded bg-neutral-900 text-left
                   [&_td]:p-4
-                  [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
+                  [&_tr]:rounded-sm [&_tr]:border-b [&_tr]:border-neutral-800
                   [&_ul]:list-inside [&_ul]:list-disc
                 `}
               >

+ 72 - 39
src/main.css

@@ -1,45 +1,78 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
+@import 'tailwindcss';
 
-@layer components {
-  .article {
-    @apply p-4 mb-4 bg-neutral-800/40 w-full mx-auto max-w-4xl rounded;
-  }
-  .btn-primary {
-    @apply bg-accent-500 text-contrast rounded p-4 hover:bg-accent-400 cursor-pointer transition-colors;
-  }
+@plugin 'tailwind-scrollbar';
+
+@theme {
+  --color-contrast: rgba(var(--contrast));
+  --color-neutral-900: rgba(var(--neutral-900));
+  --color-neutral-800: rgba(var(--neutral-800));
+  --color-neutral-700: rgba(var(--neutral-700));
+  --color-neutral-600: rgba(var(--neutral-600));
+  --color-neutral-500: rgba(var(--neutral-500));
+  --color-neutral-400: rgba(var(--neutral-400));
+  --color-neutral-300: rgba(var(--neutral-300));
+  --color-neutral-200: rgba(var(--neutral-200));
+  --color-neutral-100: rgba(var(--neutral-100));
+  --color-accent-600: rgba(var(--accent-600));
+  --color-accent-500: rgba(var(--accent-500));
+  --color-accent-400: rgba(var(--accent-400));
 }
 
-:root {
-    --contrast: 255, 255, 255;
-    --neutral-900: 243, 244, 246;
-    --neutral-800: 229, 231, 235;
-    --neutral-700: 209, 213, 219;
-    --neutral-600: 156, 163, 175;
-    --neutral-500: 180, 180, 180;
-    --neutral-400: 75, 85, 99;
-    --neutral-300: 55, 65, 81;
-    --neutral-200: 31, 41, 55;
-    --neutral-100: 17, 24, 39;
-    --accent-400: 132, 204, 22;
-    --accent-500: 101, 163, 13;
-    --accent-600: 77, 124, 15;
-  }
+/*
+  The default border color has changed to `currentColor` in Tailwind CSS v4,
+  so we've added these compatibility styles to make sure everything still
+  looks the same as it did with Tailwind CSS v3.
 
-@media (prefers-color-scheme: dark) {
-  :root {
-    --contrast: 0, 0, 0;
-    --neutral-900: 17, 24, 39;
-    --neutral-800: 31, 41, 55;
-    --neutral-700: 55, 65, 81;
-    --neutral-600: 75, 85, 99;
-    --neutral-500: 107, 114, 128;
-    --neutral-300: 209, 213, 219;
-    --neutral-400: 156, 163, 175;
-    --neutral-200: 229, 231, 235;
-    --accent-600: 101, 163, 13;
-    --accent-500: 132, 204, 22;
-    --accent-400: 163, 230, 53;
+  If we ever want to remove these styles, we need to add an explicit border
+  color utility to any element that depends on these defaults.
+*/
+@layer base {
+  *,
+  ::after,
+  ::before,
+  ::backdrop,
+  ::file-selector-button {
+    border-color: var(--color-gray-200, currentColor);
   }
 }
+
+@utility article {
+  @apply p-4 mb-4 bg-neutral-800/40 w-full mx-auto max-w-4xl rounded-sm;
+}
+
+@utility btn-primary {
+  @apply bg-accent-500 text-contrast rounded-sm p-4 hover:bg-accent-400 cursor-pointer transition-colors;
+}
+
+:root {
+    --contrast: 255, 255, 255;
+    --neutral-900: 243, 244, 246;
+    --neutral-800: 229, 231, 235;
+    --neutral-700: 209, 213, 219;
+    --neutral-600: 156, 163, 175;
+    --neutral-500: 180, 180, 180;
+    --neutral-400: 75, 85, 99;
+    --neutral-300: 55, 65, 81;
+    --neutral-200: 31, 41, 55;
+    --neutral-100: 17, 24, 39;
+    --accent-400: 132, 204, 22;
+    --accent-500: 101, 163, 13;
+    --accent-600: 77, 124, 15;
+  }
+
+@media (prefers-color-scheme: dark) {
+  :root {
+    --contrast: 0, 0, 0;
+    --neutral-900: 17, 24, 39;
+    --neutral-800: 31, 41, 55;
+    --neutral-700: 55, 65, 81;
+    --neutral-600: 75, 85, 99;
+    --neutral-500: 107, 114, 128;
+    --neutral-300: 209, 213, 219;
+    --neutral-400: 156, 163, 175;
+    --neutral-200: 229, 231, 235;
+    --accent-600: 101, 163, 13;
+    --accent-500: 132, 204, 22;
+    --accent-400: 163, 230, 53;
+  }
+}

+ 0 - 27
tailwind.config.js

@@ -1,27 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-
-import tailwindScrollbar from "tailwind-scrollbar";
-
-export default {
-  content: ["./src/**/*.{html,js,tsx,jsx,cjs,mjs}"],
-  theme: {
-    extend: {
-      colors: {
-        contrast: "rgba(var(--contrast))",
-        "neutral-900": "rgba(var(--neutral-900))",
-        "neutral-800": "rgba(var(--neutral-800))",
-        "neutral-700": "rgba(var(--neutral-700))",
-        "neutral-600": "rgba(var(--neutral-600))",
-        "neutral-500": "rgba(var(--neutral-500))",
-        "neutral-400": "rgba(var(--neutral-400))",
-        "neutral-300": "rgba(var(--neutral-300))",
-        "neutral-200": "rgba(var(--neutral-200))",
-        "neutral-100": "rgba(var(--neutral-100))",
-        "accent-600": "rgba(var(--accent-600))",
-        "accent-500": "rgba(var(--accent-500))",
-        "accent-400": "rgba(var(--accent-400))",
-      },
-    },
-  },
-  plugins: [tailwindScrollbar],
-};