Add template
This commit is contained in:
parent
9aa3caa0c2
commit
5800a5ebbf
27 changed files with 7866 additions and 1 deletions
38
apps/web/index.html
Normal file
38
apps/web/index.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<!doctype html>
|
||||
<html lang="en" class="dark" data-theme="methanium">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#171e26" />
|
||||
<title>Methanium Vite Template</title>
|
||||
<style>
|
||||
html.dark,
|
||||
html.dark body {
|
||||
background-color: #171e26;
|
||||
color: #d2e0f0;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
html.light,
|
||||
html.light body {
|
||||
background-color: #edf1f4;
|
||||
color: #10161d;
|
||||
color-scheme: light;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
const savedTheme = localStorage.getItem("theme");
|
||||
const theme =
|
||||
savedTheme === "light" ||
|
||||
(savedTheme === "system" &&
|
||||
matchMedia("(prefers-color-scheme: light)").matches)
|
||||
? "light"
|
||||
: "dark";
|
||||
document.documentElement.classList.replace("dark", theme);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
28
apps/web/package.json
Normal file
28
apps/web/package.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "@methanium/template-web",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@methanium/template-mtp": "workspace:*",
|
||||
"@methanium/ui": "*",
|
||||
"@tanstack/react-router": "^1.131.35",
|
||||
"lucide-react": "^1.21.0",
|
||||
"mtp": "*",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/vite": "^4.3.1",
|
||||
"@tanstack/router-plugin": "^1.131.35",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"tailwindcss": "^4.3.1",
|
||||
"vite": "^7.1.12"
|
||||
}
|
||||
}
|
||||
27
apps/web/public/methanium.svg
Normal file
27
apps/web/public/methanium.svg
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="4441.4" height="6468.8" shape-rendering="geometricPrecision" viewBox="0 0 4441 6469">
|
||||
<path fill="#331c4e" d="m1714 6033-33-248-5-676 69-1110-247-2069-388-302 196 3614Z"/>
|
||||
<path fill="#6a438a" d="m1864 2038-214 3093 31 640 820-1486 125-2262Z"/>
|
||||
<path fill="#291641" d="m3130 1586-504 437-125 2262 305 315Z"/>
|
||||
<path fill="#0e0619" d="m2501 4285 305 315-120 1018-384 830h-56Z"/>
|
||||
<path fill="#211136" d="m1762 6196 247 254 237-2 255-2163-822 1476 17 221Z"/>
|
||||
<path fill="#3f245b" d="m740 4907 255-267 719 1393 48 163-340-112Z"/>
|
||||
<path fill="#05020d" d="m1407 6080-147 198 414 172h335l-247-254Z"/>
|
||||
<path fill="#030106" d="m1273 6283-85 173 486-6Z"/>
|
||||
<path fill="#0a0413" d="m10 5229 297-41 966 1095-85 173-100 3Z"/>
|
||||
<path fill="#5b3878" d="m740 4907 682 1177-149 199-966-1095Z"/>
|
||||
<path fill="#794f9a" d="M159 4369 10 5229l297-41Z"/>
|
||||
<path fill="#b984c5" d="m307 5188 433-281-581-538Z"/>
|
||||
<path fill="#d4abda" d="m159 4369 581 538 255-267Z"/>
|
||||
<path d="m2686 5604 312 564-179 263-517 17Z"/>
|
||||
<path fill="#130922" d="m2686 5604 294-421 588-268 48 443-618 810Z"/>
|
||||
<path fill="#975dac" d="m2686 5604 1115-1590-379-274-666 1279Z"/>
|
||||
<path fill="#6a438a" d="m2980 5183 588-268 511-814-429-152Z"/>
|
||||
<path fill="#190c2b" d="m4079 4101 352 111-815 1146-48-443Z"/>
|
||||
<path fill="#f0d7f2" d="m2045 11-547 1919 366 108 762-15 70-59Z"/>
|
||||
<path fill="#a558aa" d="m2045 11 651 1953 434-378Z"/>
|
||||
<path fill="#b06ab6" d="m2045 11-547 1919-388-302Z"/>
|
||||
<path fill="#885ca8" d="m1498 1930 238 1992 128-1884Z"/>
|
||||
<path fill="#c698d0" d="m3650 3949 429 152 273-790Z"/>
|
||||
<path fill="#4c2d68" d="m4079 4101 352 111-79-901Z"/>
|
||||
<path fill="#e2c1e6" d="m3422 3740 228 209 702-638Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
57
apps/web/src/components/layout/Header.tsx
Normal file
57
apps/web/src/components/layout/Header.tsx
Normal 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
32
apps/web/src/main.tsx
Normal 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>,
|
||||
);
|
||||
13
apps/web/src/mtp-options.ts
Normal file
13
apps/web/src/mtp-options.ts
Normal 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,
|
||||
// };
|
||||
59
apps/web/src/routeTree.gen.ts
Normal file
59
apps/web/src/routeTree.gen.ts
Normal 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>()
|
||||
17
apps/web/src/routes/__root.tsx
Normal file
17
apps/web/src/routes/__root.tsx
Normal 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,
|
||||
});
|
||||
7
apps/web/src/routes/index.tsx
Normal file
7
apps/web/src/routes/index.tsx
Normal 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
2
apps/web/src/styles.css
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@import "tailwindcss";
|
||||
@import "@methanium/ui/index.css";
|
||||
10
apps/web/type-maps.yaml
Normal file
10
apps/web/type-maps.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
protocol_version: "1.0"
|
||||
|
||||
type_maps:
|
||||
"1.0":
|
||||
CommunicationTypes:
|
||||
ExampleRequest: 32
|
||||
ExampleResponse: 33
|
||||
DataTypes:
|
||||
Message: 32
|
||||
ReceivedAt: 33
|
||||
28
apps/web/vite.config.ts
Normal file
28
apps/web/vite.config.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { methaniumUi } from "@methanium/ui/vite";
|
||||
import { tanstackRouter } from "@tanstack/router-plugin/vite";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { mtp } from "mtp/vite";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { defineConfig, type Plugin } from "vite";
|
||||
|
||||
const root = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tanstackRouter({ target: "react", autoCodeSplitting: true }),
|
||||
tailwindcss(),
|
||||
react(),
|
||||
methaniumUi({ defaultThemeId: "methanium" }),
|
||||
mtp({ typeMaps: "./type-maps.yaml" }) as Plugin,
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@methanium/template-mtp": path.resolve(
|
||||
root,
|
||||
"../../packages/mtp/index.ts",
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
Loading…
Reference in a new issue