diff --git a/.envrc b/.envrc index 8106bf9..117c726 100644 --- a/.envrc +++ b/.envrc @@ -1,13 +1,17 @@ -if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs=" +#!/usr/bin/env bash + +if ! has nix_direnv_version || ! nix_direnv_version 3.1.0; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.1.0/direnvrc" "sha256-yMJ2OVMzrFaDPn7q8nCBZFRYpL/f0RcHzhmw/i6btJM=" fi +export DEVENV_IN_DIRENV_SHELL=true + watch_file flake.nix watch_file flake.lock -DEVENV_ROOT_FILE="$(mktemp)" -printf %s "$PWD" > "$DEVENV_ROOT_FILE" -if ! use flake . --override-input devenv-root "file+file://$DEVENV_ROOT_FILE" -then +mkdir -p "$PWD/.devenv" +DEVENV_ROOT_FILE="$PWD/.devenv/root" +printf %s "$PWD" >"$DEVENV_ROOT_FILE" +if ! use flake . --override-input devenv-root "file+file://$DEVENV_ROOT_FILE"; then echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 fi diff --git a/.gitignore b/.gitignore index d2fcaf2..09d7f9a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,10 @@ node_modules # testing /coverage -# production -/build +# React Router +.react-router/ +build/ + # misc .DS_Store diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..45d6c30 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,25 @@ +// Folder-specific settings +// +// For a full list of overridable settings, and general information on folder-specific settings, +// see the documentation: https://zed.dev/docs/configuring-zed#settings-files +{ + "formatter": { + "language_server": { + "name": "biome" + } + }, + "code_actions_on_format": { + "source.fixAll.biome": true, + "source.organizeImports.biome": true + }, + "format_on_save": "on", + "tab_size": 2, + "languages": { + "TSX": { + "language_servers": ["stylelint-lsp", "..."] + }, + "JSON": { + "language_servers": ["biome", "..."] + } + } +} diff --git a/biome.json b/biome.json index 7cdcf69..1498ed4 100644 --- a/biome.json +++ b/biome.json @@ -1,7 +1,13 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "organizeImports": { - "enabled": true + "$schema": "https://biomejs.dev/schemas/2.3.6/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "includes": ["**", "!**/.react-router"] }, "formatter": { "enabled": true, @@ -20,9 +26,17 @@ } } }, - "vcs": { + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { "enabled": true, - "clientKind": "git", - "useIgnoreFile": true + "actions": { + "source": { + "organizeImports": "on" + } + } } } diff --git a/bun.lockb b/bun.lockb index d0d030b..2709868 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 32d4157..0000000 --- a/flake.lock +++ /dev/null @@ -1,378 +0,0 @@ -{ - "nodes": { - "cachix": { - "inputs": { - "devenv": [ - "devenv" - ], - "flake-compat": [ - "devenv" - ], - "git-hooks": [ - "devenv" - ], - "nixpkgs": "nixpkgs" - }, - "locked": { - "lastModified": 1737621947, - "narHash": "sha256-8HFvG7fvIFbgtaYAY2628Tb89fA55nPm2jSiNs0/Cws=", - "owner": "cachix", - "repo": "cachix", - "rev": "f65a3cd5e339c223471e64c051434616e18cc4f5", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat", - "git-hooks": "git-hooks", - "nix": "nix", - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1743582803, - "narHash": "sha256-7OblE2f4FaH47U9W9cTIy8+TrcLU5xZTBgk+QqKH/uw=", - "owner": "cachix", - "repo": "devenv", - "rev": "3dd684b5df083ca48a8db263d9406bf83fc12b3e", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "devenv-root": { - "flake": false, - "locked": { - "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", - "type": "file", - "url": "file:///dev/null" - }, - "original": { - "type": "file", - "url": "file:///dev/null" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "devenv", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "git-hooks": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1740849354, - "narHash": "sha256-oy33+t09FraucSZ2rZ6qnD1Y1c8azKKmQuCvF2ytUko=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "4a709a8ce9f8c08fa7ddb86761fe488ff7858a07", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "libgit2": { - "flake": false, - "locked": { - "lastModified": 1697646580, - "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", - "owner": "libgit2", - "repo": "libgit2", - "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", - "type": "github" - }, - "original": { - "owner": "libgit2", - "repo": "libgit2", - "type": "github" - } - }, - "mk-shell-bin": { - "locked": { - "lastModified": 1677004959, - "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", - "type": "github" - }, - "original": { - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "type": "github" - } - }, - "nix": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "flake-parts": "flake-parts", - "libgit2": "libgit2", - "nixpkgs": "nixpkgs_2", - "nixpkgs-23-11": [ - "devenv" - ], - "nixpkgs-regression": [ - "devenv" - ], - "pre-commit-hooks": [ - "devenv" - ] - }, - "locked": { - "lastModified": 1741798497, - "narHash": "sha256-E3j+3MoY8Y96mG1dUIiLFm2tZmNbRvSiyN7CrSKuAVg=", - "owner": "domenkozar", - "repo": "nix", - "rev": "f3f44b2baaf6c4c6e179de8cbb1cc6db031083cd", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.24", - "repo": "nix", - "type": "github" - } - }, - "nix2container": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1742501024, - "narHash": "sha256-4G0RaAkRQY8Oty0WjoDfIkEAkX7PckUqUGjAQrxhDiA=", - "owner": "nlewo", - "repo": "nix2container", - "rev": "e6315c8307edf2938ae24df0e28b47ca865121de", - "type": "github" - }, - "original": { - "owner": "nlewo", - "repo": "nix2container", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1733212471, - "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1743296961, - "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1717432640, - "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1733477122, - "narHash": "sha256-qamMCz5mNpQmgBwc8SB5tVMlD5sbwVIToVZtSxMph9s=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1743501102, - "narHash": "sha256-7PCBQ4aGVF8OrzMkzqtYSKyoQuU2jtpPi4lmABpe5X4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "02f2af8c8a8c3b2c05028936a1e84daefa1171d4", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-24.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "devenv-root": "devenv-root", - "flake-parts": "flake-parts_2", - "mk-shell-bin": "mk-shell-bin", - "nix2container": "nix2container", - "nixpkgs": "nixpkgs_4" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix index 8d7fa81..2525c5e 100644 --- a/flake.nix +++ b/flake.nix @@ -6,8 +6,9 @@ url = "file+file:///dev/null"; flake = false; }; + nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling"; flake-parts.url = "github:hercules-ci/flake-parts"; - nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; + flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; devenv.url = "github:cachix/devenv"; nix2container.url = "github:nlewo/nix2container"; nix2container.inputs.nixpkgs.follows = "nixpkgs"; @@ -19,54 +20,40 @@ extra-substituters = "https://devenv.cachix.org"; }; - outputs = inputs @ { - flake-parts, - devenv-root, - ... - }: - flake-parts.lib.mkFlake {inherit inputs;} { + outputs = + inputs@{ flake-parts, devenv-root, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { imports = [ inputs.devenv.flakeModule ]; - systems = ["x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin"]; + systems = [ + "x86_64-linux" + "i686-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; - perSystem = { - #config, - #self', - ##inputs', - pkgs, - #system, - ... - }: let - in { - devenv.shells.default = { - devenv.root = let - devenvRootFileContent = builtins.readFile devenv-root.outPath; - in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; + perSystem = + { + config, + self', + inputs', + pkgs, + system, + ... + }: + { + devenv.shells.default = { + name = "my-project"; + imports = [ ]; - name = "TODO-template-name"; - - packages = [ - pkgs.biome - ]; - - processes = { - #api-dev.exec = "cd packages/api && bun dev"; - #web-dev.exec = "cd packages/web && bun dev"; - }; - - languages.javascript = { - enable = true; - package = pkgs.nodejs_22; - - bun.enable = true; - npm.enable = false; - pnpm.enable = false; + languages.javascript = { + enable = true; + bun.enable = true; + }; }; }; - }; - flake = { - }; + flake = { }; }; } diff --git a/packages/web/app/app.css b/packages/web/app/app.css new file mode 100644 index 0000000..71277f5 --- /dev/null +++ b/packages/web/app/app.css @@ -0,0 +1,4 @@ +html, +body { + background-color: teal; +} diff --git a/packages/web/app/root.tsx b/packages/web/app/root.tsx new file mode 100644 index 0000000..9fc6636 --- /dev/null +++ b/packages/web/app/root.tsx @@ -0,0 +1,75 @@ +import { + isRouteErrorResponse, + Links, + Meta, + Outlet, + Scripts, + ScrollRestoration, +} from "react-router"; + +import type { Route } from "./+types/root"; +import "./app.css"; + +export const links: Route.LinksFunction = () => [ + { rel: "preconnect", href: "https://fonts.googleapis.com" }, + { + rel: "preconnect", + href: "https://fonts.gstatic.com", + crossOrigin: "anonymous", + }, + { + rel: "stylesheet", + href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap", + }, +]; + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + + + + + + {children} + + + + + ); +} + +export default function App() { + return ; +} + +export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { + let message = "Oops!"; + let details = "An unexpected error occurred."; + let stack: string | undefined; + + if (isRouteErrorResponse(error)) { + message = error.status === 404 ? "404" : "Error"; + details = + error.status === 404 + ? "The requested page could not be found." + : error.statusText || details; + } else if (import.meta.env.DEV && error && error instanceof Error) { + details = error.message; + stack = error.stack; + } + + return ( +
+

{message}

+

{details}

+ {stack && ( +
+          {stack}
+        
+ )} +
+ ); +} diff --git a/packages/web/app/routes.ts b/packages/web/app/routes.ts new file mode 100644 index 0000000..38f1a4d --- /dev/null +++ b/packages/web/app/routes.ts @@ -0,0 +1,3 @@ +import { index, type RouteConfig } from "@react-router/dev/routes"; + +export default [index("routes/home.tsx")] satisfies RouteConfig; diff --git a/packages/web/app/routes/home.tsx b/packages/web/app/routes/home.tsx new file mode 100644 index 0000000..cc4d73f --- /dev/null +++ b/packages/web/app/routes/home.tsx @@ -0,0 +1,13 @@ +import { Welcome } from "../welcome/welcome"; +import type { Route } from "./+types/home"; + +export function meta(_args: Route.MetaArgs) { + return [ + { title: "New React Router App" }, + { name: "description", content: "Welcome to React Router!" }, + ]; +} + +export default function Home() { + return ; +} diff --git a/packages/web/app/vite-env.d.ts b/packages/web/app/vite-env.d.ts new file mode 100644 index 0000000..ee9857a --- /dev/null +++ b/packages/web/app/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/packages/web/app/welcome/logo-dark.svg b/packages/web/app/welcome/logo-dark.svg new file mode 100644 index 0000000..dd82028 --- /dev/null +++ b/packages/web/app/welcome/logo-dark.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/web/app/welcome/logo-light.svg b/packages/web/app/welcome/logo-light.svg new file mode 100644 index 0000000..7328492 --- /dev/null +++ b/packages/web/app/welcome/logo-light.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/web/app/welcome/welcome.module.css b/packages/web/app/welcome/welcome.module.css new file mode 100644 index 0000000..960d595 --- /dev/null +++ b/packages/web/app/welcome/welcome.module.css @@ -0,0 +1,31 @@ +.welcome { + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + + header { + display: flex; + flex-direction: column; + align-items: center; + width: 500px; + max-width: 100vw; + padding: 4px; + + img { + width: 100%; + } + } +} + +.links { + max-width: 300px; + width: 100%; + padding: 0 4px; + + nav { + border-radius: 48px; + border: 1px solid gray; + padding: 6px; + } +} diff --git a/packages/web/app/welcome/welcome.tsx b/packages/web/app/welcome/welcome.tsx new file mode 100644 index 0000000..cfb28b0 --- /dev/null +++ b/packages/web/app/welcome/welcome.tsx @@ -0,0 +1,88 @@ +import logoDark from "./logo-dark.svg"; +import logoLight from "./logo-light.svg"; +import styles from "./welcome.module.css"; + +export function Welcome() { + return ( +
+
+ React Router + React Router +
+
+ +
+
+ ); +} + +const resources = [ + { + href: "https://reactrouter.com/docs", + text: "React Router Docs", + icon: ( + + Welcome + + + ), + }, + { + href: "https://rmx.as/discord", + text: "Join Discord", + icon: ( + + Welcome + + + ), + }, +]; diff --git a/packages/web/index.html b/packages/web/index.html deleted file mode 100644 index 2ce0cce..0000000 --- a/packages/web/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - Template - - -
- - - diff --git a/packages/web/package.json b/packages/web/package.json index c5bdd78..7b54c5e 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -4,33 +4,37 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "bunx --bun vite", - "build": "tsc -b && vite build", - "lint": "biome lint . && stylelint **/*.css", - "preview": "vite preview", + "build": "react-router build", + "dev": "react-router dev", + "start": "react-router-serve ./build/server/index.js", + "typecheck": "react-router typegen && tsc -p tsconfig.cssmodulehack.json", "test": "vitest" }, "dependencies": { - "effect": "=3.14.5", - "react": "=19.1.0", - "react-dom": "=19.1.0", + "@react-router/node": "7.10.1", + "@react-router/serve": "7.10.1", + "isbot": "^5.1.31", + "react": "^19.2.3", + "react-dom": "^19.2.3", + "react-router": "7.10.1", "react-hook-form": "7.55.0", - "react-router-dom": "7.4.1", "vite-plugin-top-level-await": "1.5.0" }, "devDependencies": { - "@biomejs/biome": "1.9.4", - "@types/lodash": "4.17.16", - "@types/react": "19.1.0", - "@types/react-dom": "19.1.1", - "@vitejs/plugin-react": "4.3.4", - "meow": "13.2.0", - "stylelint": "16.17.0", - "stylelint-config-standard": "37.0.0", - "typescript": "5.8.2", - "typescript-eslint": "8.29.0", - "vite": "6.2.4", - "vite-plugin-checker": "0.9.1", - "vitest": "3.1.1" + "@biomejs/biome": "2.3.6", + "@react-router/dev": "7.10.1", + "@tailwindcss/vite": "^4.1.13", + "@types/node": "^22", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", + "stylelint": "16.26.1", + "stylelint-config-standard": "39.0.1", + "tailwindcss": "^4.1.13", + "typescript": "^5.9.2", + "typescript-plugin-css-modules": "5.2.0", + "vite": "^7.1.7", + "vite-plugin-checker": "0.12.0", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "4.0.16" } } diff --git a/packages/web/public/favicon.ico b/packages/web/public/favicon.ico index a11777c..5dbdfcd 100644 Binary files a/packages/web/public/favicon.ico and b/packages/web/public/favicon.ico differ diff --git a/packages/web/public/logo192.png b/packages/web/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/packages/web/public/logo192.png and /dev/null differ diff --git a/packages/web/public/logo512.png b/packages/web/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/packages/web/public/logo512.png and /dev/null differ diff --git a/packages/web/public/manifest.json b/packages/web/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/packages/web/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/packages/web/public/robots.txt b/packages/web/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/packages/web/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/packages/web/react-router.config.ts b/packages/web/react-router.config.ts new file mode 100644 index 0000000..6ff16f9 --- /dev/null +++ b/packages/web/react-router.config.ts @@ -0,0 +1,7 @@ +import type { Config } from "@react-router/dev/config"; + +export default { + // Config options... + // Server-side render by default, to enable SPA mode set this to `false` + ssr: true, +} satisfies Config; diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx deleted file mode 100644 index 4ed09e9..0000000 --- a/packages/web/src/App.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { - createBrowserRouter, - Navigate, - Outlet, - RouterProvider, -} from "react-router-dom"; - -const router = createBrowserRouter([ - { - path: "/", - element: , - children: [ - { - path: "/", - element: , - }, - { - path: "test", - element:

Test

, - }, - ], - }, -]); - -function App() { - return ; -} - -export default App; diff --git a/packages/web/src/index.css b/packages/web/src/index.css deleted file mode 100644 index be4b9d3..0000000 --- a/packages/web/src/index.css +++ /dev/null @@ -1,5 +0,0 @@ -html, -body { - margin: 0; - padding: 0; -} diff --git a/packages/web/src/main.tsx b/packages/web/src/main.tsx deleted file mode 100644 index bb311b2..0000000 --- a/packages/web/src/main.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { StrictMode } from "react"; -import { createRoot } from "react-dom/client"; -import App from "./App.tsx"; -import "./index.css"; - -const root = document.getElementById("root"); - -if (root != null) { - createRoot(root).render( - - - , - ); -} else { - console.error("No #root element found"); -} diff --git a/packages/web/src/requireContext.ts b/packages/web/src/requireContext.ts deleted file mode 100644 index e471762..0000000 --- a/packages/web/src/requireContext.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useContext } from "react"; - -export function useRequiredContext( - c: React.Context, - error: string, -): T { - const ctx = useContext(c); - if (ctx == null) { - throw new Error(error); - } - return ctx; -} diff --git a/packages/web/tsconfig.cssmodulehack.json b/packages/web/tsconfig.cssmodulehack.json new file mode 100644 index 0000000..c00a32a --- /dev/null +++ b/packages/web/tsconfig.cssmodulehack.json @@ -0,0 +1,11 @@ +{ + "files": [], + "extends": "./tsconfig.json", + "compilerOptions": { + // the typescript-plugin-css-modules only works when typescript is used as a LSP and not when "tsc" is invoked. + // Therefore when tsc is invoked, we need to disable the noPropertyAccessFromIndexSignature option. + // This is good, because its more of a lint anyways - the heavy lifting is done by the + // noUncheckedIndexedAccess rule + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 1673d04..be26c19 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -1,5 +1,26 @@ { "files": [], "extends": "../../tsconfig.base.json", - "include": ["src"] + "include": [ + "app/**/*", + "*.ts", + "**/.server/**/*", + "**/.client/**/*", + ".react-router/types/**/*" + ], + "compilerOptions": { + "plugins": [ + { + "name": "typescript-plugin-css-modules", + "options": { + "classnameTransform": "camelCaseOnly" + } + } + ], + "rootDirs": [".", "./.react-router/types"], + "baseUrl": ".", + "paths": { + "~/*": ["./app/*"] + } + } } diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 707457b..568cb33 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -1,17 +1,26 @@ +import { reactRouter } from "@react-router/dev/vite"; import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; import checker from "vite-plugin-checker"; +import tsconfigPaths from "vite-tsconfig-paths"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [ checker({ biome: { command: "check", dev: { command: "lint" } }, - typescript: true, - stylelint: { lintCommand: "stylelint ./src/**/*.css" }, + typescript: { + tsconfigPath: "./tsconfig.cssmodulehack.json", + }, + stylelint: { lintCommand: "stylelint ./app/**/*.css" }, }), - react(), + reactRouter(), + tsconfigPaths(), ], + css: { + modules: { + localsConvention: "camelCaseOnly", + }, + }, server: { fs: { deny: [".devenv/", ".direnv/"], diff --git a/tsconfig.base.json b/tsconfig.base.json index daa6b3a..9869b40 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -3,7 +3,7 @@ "target": "ES2022", "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"], - "types": ["vitest/importMeta"], + "types": ["node", "vite/client", "vitest/importMeta"], "module": "ESNext", "skipLibCheck": true, @@ -16,6 +16,7 @@ "strict": true, + "esModuleInterop": true, "allowUnusedLabels": false, "allowUnreachableCode": false, "exactOptionalPropertyTypes": true, @@ -26,8 +27,10 @@ "noUncheckedIndexedAccess": true, "noUnusedLocals": false, "noUnusedParameters": false, + "resolveJsonModule": true, "checkJs": true, + "verbatimModuleSyntax": true, "forceConsistentCasingInFileNames": true }