Add template

This commit is contained in:
Alois 2026-07-29 15:28:20 +02:00
commit 5800a5ebbf
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
27 changed files with 7866 additions and 1 deletions

View file

@ -0,0 +1,57 @@
import { Moon, Sun } from "lucide-react";
import { Button, useTheme } from "@methanium/ui";
const homepageUrl = "https://methanium.net";
export function Header() {
const { resolvedPolarity, setTheme } = useTheme();
const isDark = resolvedPolarity === "dark";
return (
<header className="sticky top-0 z-40 h-12 border-b border-sidebar-border bg-sidebar text-sidebar-foreground shadow-sm">
<div className="flex h-full items-center justify-between overflow-x-auto px-[10px]">
<Button
nativeButton={false}
variant="ghost"
size="sm"
className="mr-1 shrink-0 text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
style={{ width: "46.59px", height: "36px", padding: "3px 13px" }}
render={<a href="/" aria-label="Methanium home" />}
>
<img src="/methanium.svg" alt="" className="h-8 w-6 object-contain" />
</Button>
<nav
className="mr-auto flex h-full shrink-0 items-center"
aria-label="Primary"
>
<Button
nativeButton={false}
variant="ghost"
size="sm"
className="h-9 text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
render={<a href={homepageUrl} />}
>
Homepage
</Button>
</nav>
<div className="flex h-full items-center gap-1">
<Button
type="button"
variant="ghost"
size="icon"
className="size-8 text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
onClick={() => setTheme(isDark ? "light" : "dark")}
>
{isDark ? (
<Sun className="size-3.5" />
) : (
<Moon className="size-3.5" />
)}
</Button>
</div>
</div>
</header>
);
}

32
apps/web/src/main.tsx Normal file
View file

@ -0,0 +1,32 @@
import "./styles.css";
import { BUILT_IN_THEMES, ThemeProvider } from "@methanium/ui";
import { Provider as MTPProvider } from "@methanium/template-mtp";
import { createRouter, RouterProvider } from "@tanstack/react-router";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { routeTree } from "./routeTree.gen";
import { mtpOptions } from "./mtp-options.ts";
const router = createRouter({ routeTree });
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ThemeProvider
defaultTheme="dark"
themes={BUILT_IN_THEMES}
defaultParentThemeId="methanium"
>
<MTPProvider options={mtpOptions}>
<RouterProvider router={router} />
</MTPProvider>
</ThemeProvider>
</StrictMode>,
);

View file

@ -0,0 +1,13 @@
import type { MTPClientOptions } from "mtp";
// Replace null with your application's stable MTP connection configuration.
export const mtpOptions: MTPClientOptions | null = null;
// Example:
// export const mtpOptions: MTPClientOptions = {
// url: "https://mtp.example.com:4433",
// credentials: { clientId: 1, keyring: new Uint8Array([...]) },
// hostPublicKey: "...",
// descriptor: "web",
// pings: true,
// };

View file

@ -0,0 +1,59 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as IndexRouteImport } from './routes/index'
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => rootRouteImport,
} as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/'
fileRoutesByTo: FileRoutesByTo
to: '/'
id: '__root__' | '/'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/': {
id: '/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof IndexRouteImport
parentRoute: typeof rootRouteImport
}
}
}
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()

View file

@ -0,0 +1,17 @@
import { createRootRoute, Outlet } from "@tanstack/react-router";
import { Header } from "../components/layout/Header";
const EmptyPage = () => (
<main className="min-h-[calc(100vh-3rem)] bg-background" />
);
export const Route = createRootRoute({
component: () => (
<div className="min-h-screen bg-background text-foreground">
<Header />
<Outlet />
</div>
),
notFoundComponent: EmptyPage,
});

View file

@ -0,0 +1,7 @@
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/")({ component: Home });
function Home() {
return <main className="min-h-[calc(100vh-3rem)] bg-background" />;
}

2
apps/web/src/styles.css Normal file
View file

@ -0,0 +1,2 @@
@import "tailwindcss";
@import "@methanium/ui/index.css";