refactor: Consolidate global styling with Tailwind and HeroUI theme variables and refactor devtools integration.

This commit is contained in:
Jrodenas
2026-03-04 20:23:03 +01:00
parent 841f43285e
commit b4a6555e5e
16 changed files with 3702 additions and 1102 deletions

View File

@@ -1,112 +1,111 @@
import { Link } from '@tanstack/react-router'
import { Link } from "@tanstack/react-router"
import { Globe, Home, Languages, Menu, Network, X } from "lucide-react"
import ParaglideLocaleSwitcher from './LocaleSwitcher.tsx'
import { useState } from 'react'
import { Globe, Home, Languages, Menu, Network, X } from 'lucide-react'
import { useState } from "react"
import ParaglideLocaleSwitcher from "./LocaleSwitcher.tsx"
export default function Header() {
const [isOpen, setIsOpen] = useState(false)
const [isOpen, setIsOpen] = useState(false)
return (
<>
<header className="p-4 flex items-center bg-gray-800 text-white shadow-lg">
<button
onClick={() => setIsOpen(true)}
className="p-2 hover:bg-gray-700 rounded-lg transition-colors"
aria-label="Open menu"
>
<Menu size={24} />
</button>
<h1 className="ml-4 text-xl font-semibold">
<Link to="/">
<img
src="/tanstack-word-logo-white.svg"
alt="TanStack Logo"
className="h-10"
/>
</Link>
</h1>
</header>
return (
<>
<header className="p-4 flex items-center bg-gray-800 text-white shadow-lg">
<button
onClick={() => setIsOpen(true)}
className="p-2 hover:bg-gray-700 rounded-lg transition-colors"
aria-label="Open menu"
>
<Menu size={24} />
</button>
<h1 className="ml-4 text-xl font-semibold">
<Link to="/">
<img
src="/tanstack-word-logo-white.svg"
alt="TanStack Logo"
className="h-10"
/>
</Link>
</h1>
</header>
<aside
className={`fixed top-0 left-0 h-full w-80 bg-gray-900 text-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out flex flex-col ${
isOpen ? 'translate-x-0' : '-translate-x-full'
}`}
>
<div className="flex items-center justify-between p-4 border-b border-gray-700">
<h2 className="text-xl font-bold">Navigation</h2>
<button
onClick={() => setIsOpen(false)}
className="p-2 hover:bg-gray-800 rounded-lg transition-colors"
aria-label="Close menu"
>
<X size={24} />
</button>
</div>
<aside
className={`fixed top-0 left-0 h-full w-80 bg-gray-900 text-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out flex flex-col ${
isOpen ? "translate-x-0" : "-translate-x-full"
}`}
>
<div className="flex items-center justify-between p-4 border-b border-gray-700">
<h2 className="text-xl font-bold">Navigation</h2>
<button
onClick={() => setIsOpen(false)}
className="p-2 hover:bg-gray-800 rounded-lg transition-colors"
aria-label="Close menu"
>
<X size={24} />
</button>
</div>
<nav className="flex-1 p-4 overflow-y-auto">
<Link
to="/"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
}}
>
<Home size={20} />
<span className="font-medium">Home</span>
</Link>
<nav className="flex-1 p-4 overflow-y-auto">
<Link
to="/"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Home size={20} />
<span className="font-medium">Home</span>
</Link>
{/* Demo Links Start */}
{/* Demo Links Start */}
<Link
to="/demo/tanstack-query"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
}}
>
<Network size={20} />
<span className="font-medium">TanStack Query</span>
</Link>
<Link
to="/demo/tanstack-query"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Network size={20} />
<span className="font-medium">TanStack Query</span>
</Link>
<Link
to="/demo/sentry/testing"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
}}
>
<Globe size={20} />
<span className="font-medium">Sentry</span>
</Link>
<Link
to="/demo/sentry/testing"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Globe size={20} />
<span className="font-medium">Sentry</span>
</Link>
<Link
to="/demo/i18n"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
'flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2',
}}
>
<Languages size={20} />
<span className="font-medium">I18n example</span>
</Link>
<Link
to="/demo/i18n"
onClick={() => setIsOpen(false)}
className="flex items-center gap-3 p-3 rounded-lg hover:bg-gray-800 transition-colors mb-2"
activeProps={{
className:
"flex items-center gap-3 p-3 rounded-lg bg-cyan-600 hover:bg-cyan-700 transition-colors mb-2"
}}
>
<Languages size={20} />
<span className="font-medium">I18n example</span>
</Link>
{/* Demo Links End */}
</nav>
{/* Demo Links End */}
</nav>
<div className="p-4 border-t border-gray-700 bg-gray-800 flex flex-col gap-2">
<ParaglideLocaleSwitcher />
</div>
</aside>
</>
)
<div className="p-4 border-t border-gray-700 bg-gray-800 flex flex-col gap-2">
<ParaglideLocaleSwitcher />
</div>
</aside>
</>
)
}

View File

@@ -0,0 +1,14 @@
import { TanStackDevtools } from "@tanstack/react-devtools"
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"
export const Devtools = () => {
return (
<TanStackDevtools
plugins={[
{ name: "TanStack Router", render: <TanStackRouterDevtools /> },
{ name: "TanStack Query", render: <ReactQueryDevtools /> }
]}
/>
)
}

View File

@@ -1,6 +1,6 @@
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
import { ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools"
export default {
name: 'Tanstack Query',
render: <ReactQueryDevtoolsPanel />,
name: "Tanstack Query",
render: <ReactQueryDevtoolsPanel />
}

View File

@@ -1,34 +0,0 @@
import type { ReactNode } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
let context:
| {
queryClient: QueryClient
}
| undefined
export function getContext() {
if (context) {
return context
}
const queryClient = new QueryClient()
context = {
queryClient,
}
return context
}
export default function TanStackQueryProvider({
children,
}: {
children: ReactNode
}) {
const { queryClient } = getContext()
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
)
}

View File

@@ -1,7 +0,0 @@
import type { ClassValue } from 'clsx'
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@@ -1,24 +1,30 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import { getContext } from './integrations/tanstack-query/root-provider'
import { QueryClient } from "@tanstack/react-query"
import { createRouter as createTanStackRouter } from "@tanstack/react-router"
import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query"
import { routeTree } from "./routeTree.gen"
export function getRouter() {
const router = createTanStackRouter({
routeTree,
const queryClient = new QueryClient()
const router = createTanStackRouter({
routeTree,
context: {
queryClient
},
scrollRestoration: true,
defaultPreload: "intent",
defaultPreloadStaleTime: 0
})
context: getContext(),
setupRouterSsrQueryIntegration({
router,
queryClient
})
scrollRestoration: true,
defaultPreload: 'intent',
defaultPreloadStaleTime: 0,
})
return router
return router
}
declare module '@tanstack/react-router' {
interface Register {
router: ReturnType<typeof getRouter>
}
declare module "@tanstack/react-router" {
interface Register {
router: ReturnType<typeof getRouter>
}
}

View File

@@ -1,19 +1,16 @@
import { TanStackDevtools } from "@tanstack/react-devtools";
import type { QueryClient } from "@tanstack/react-query";
import type { QueryClient } from "@tanstack/react-query"
import {
createRootRouteWithContext,
HeadContent,
Scripts,
} from "@tanstack/react-router";
import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools";
import { getLocale } from "@/paraglide/runtime";
import Header from "../components/Header";
import TanStackQueryDevtools from "../integrations/tanstack-query/devtools";
import TanStackQueryProvider from "../integrations/tanstack-query/root-provider";
import appCss from "../styles.css?url";
Scripts
} from "@tanstack/react-router"
import { Devtools } from "@/integrations/devtools"
import { getLocale } from "@/paraglide/runtime"
import appCss from "@/styles/globals.css?url"
import Header from "../components/Header"
interface MyRouterContext {
queryClient: QueryClient;
queryClient: QueryClient
}
export const Route = createRootRouteWithContext<MyRouterContext>()({
@@ -21,32 +18,32 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
// Other redirect strategies are possible; see
// https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#offline-redirect
if (typeof document !== "undefined") {
document.documentElement.setAttribute("lang", getLocale());
document.documentElement.setAttribute("lang", getLocale())
}
},
head: () => ({
meta: [
{
charSet: "utf-8",
charSet: "utf-8"
},
{
name: "viewport",
content: "width=device-width, initial-scale=1",
content: "width=device-width, initial-scale=1"
},
{
title: "TanStack Start Starter",
},
title: "TanStack Start Starter"
}
],
links: [
{
rel: "stylesheet",
href: appCss,
},
],
href: appCss
}
]
}),
shellComponent: RootDocument,
});
shellComponent: RootDocument
})
function RootDocument({ children }: { children: React.ReactNode }) {
return (
@@ -55,24 +52,11 @@ function RootDocument({ children }: { children: React.ReactNode }) {
<HeadContent />
</head>
<body>
<TanStackQueryProvider>
<Header />
{children}
<TanStackDevtools
config={{
position: "bottom-right",
}}
plugins={[
{
name: "Tanstack Router",
render: <TanStackRouterDevtoolsPanel />,
},
TanStackQueryDevtools,
]}
/>
</TanStackQueryProvider>
<Header />
{children}
<Devtools />
<Scripts />
</body>
</html>
);
)
}

View File

@@ -1,10 +1,10 @@
import { createFileRoute } from "@tanstack/react-router";
import { m } from "@/paraglide/messages";
import LocaleSwitcher from "../components/LocaleSwitcher";
import { createFileRoute } from "@tanstack/react-router"
import { m } from "@/paraglide/messages"
import LocaleSwitcher from "../components/LocaleSwitcher"
export const Route = createFileRoute("/demo/i18n")({
component: App,
});
component: App
})
function App() {
return (
@@ -24,5 +24,5 @@ function App() {
</div>
</header>
</div>
);
)
}

View File

@@ -6,7 +6,7 @@ import {
Shield,
Sparkles,
Waves,
Zap,
Zap
} from "lucide-react"
export const Route = createFileRoute("/")({ component: App })
@@ -17,45 +17,45 @@ function App() {
icon: <Zap className="w-12 h-12 text-cyan-400" />,
title: "Powerful Server Functions",
description:
"Write server-side code that seamlessly integrates with your client components. Type-safe, secure, and simple.",
"Write server-side code that seamlessly integrates with your client components. Type-safe, secure, and simple."
},
{
icon: <Server className="w-12 h-12 text-cyan-400" />,
title: "Flexible Server Side Rendering",
description:
"Full-document SSR, streaming, and progressive enhancement out of the box. Control exactly what renders where.",
"Full-document SSR, streaming, and progressive enhancement out of the box. Control exactly what renders where."
},
{
icon: <RouteIcon className="w-12 h-12 text-cyan-400" />,
title: "API Routes",
description:
"Build type-safe API endpoints alongside your application. No separate backend needed.",
"Build type-safe API endpoints alongside your application. No separate backend needed."
},
{
icon: <Shield className="w-12 h-12 text-cyan-400" />,
title: "Strongly Typed Everything",
description:
"End-to-end type safety from server to client. Catch errors before they reach production.",
"End-to-end type safety from server to client. Catch errors before they reach production."
},
{
icon: <Waves className="w-12 h-12 text-cyan-400" />,
title: "Full Streaming Support",
description:
"Stream data from server to client progressively. Perfect for AI applications and real-time updates.",
"Stream data from server to client progressively. Perfect for AI applications and real-time updates."
},
{
icon: <Sparkles className="w-12 h-12 text-cyan-400" />,
title: "Next Generation Ready",
description:
"Built from the ground up for modern web applications. Deploy anywhere JavaScript runs.",
},
"Built from the ground up for modern web applications. Deploy anywhere JavaScript runs."
}
]
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-slate-800 to-slate-900">
<div className="min-h-screen bg-linear-to-b from-slate-900 via-slate-800 to-slate-900">
<Button> Hola</Button>
<section className="relative py-20 px-6 text-center overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
<div className="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
<div className="relative max-w-5xl mx-auto">
<div className="flex items-center justify-center gap-6 mb-6">
<img
@@ -63,9 +63,9 @@ function App() {
alt="TanStack Logo"
className="w-24 h-24 md:w-32 md:h-32"
/>
<h1 className="text-6xl md:text-7xl font-black text-white [letter-spacing:-0.08em]">
<h1 className="text-6xl md:text-7xl font-black text-white tracking-[-0.08em]">
<span className="text-gray-300">TANSTACK</span>{" "}
<span className="bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">
<span className="bg-linear-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">
START
</span>
</h1>