feat: base mui
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import {
|
||||
AppBar,
|
||||
Box,
|
||||
Button,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Toolbar,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { Link } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
import { RouterButton } from "./RouterButton";
|
||||
|
||||
const pages = ["Products", "Pricing", "Blog"];
|
||||
|
||||
export default function DashboardLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null);
|
||||
|
||||
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElNav(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseNavMenu = () => {
|
||||
setAnchorElNav(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
position: "relative",
|
||||
display: "flex",
|
||||
overflow: "hidden",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<AppBar position="static">
|
||||
<Toolbar>
|
||||
{/* desktop */}
|
||||
<Typography
|
||||
variant="h6"
|
||||
noWrap
|
||||
sx={{ mr: 2, display: { xs: "none", md: "flex" } }}
|
||||
>
|
||||
<em>owof</em> Announcements
|
||||
</Typography>
|
||||
|
||||
{/* mobile */}
|
||||
<Box sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}>
|
||||
<IconButton
|
||||
size="large"
|
||||
aria-label="account of current user"
|
||||
aria-controls="menu-appbar"
|
||||
aria-haspopup="true"
|
||||
onClick={handleOpenNavMenu}
|
||||
color="inherit"
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="menu-appbar"
|
||||
anchorEl={anchorElNav}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "left",
|
||||
}}
|
||||
keepMounted
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
open={Boolean(anchorElNav)}
|
||||
onClose={handleCloseNavMenu}
|
||||
sx={{ display: { xs: "block", md: "none" } }}
|
||||
>
|
||||
{pages.map((page) => (
|
||||
<MenuItem key={page} onClick={handleCloseNavMenu}>
|
||||
<Typography sx={{ textAlign: "center" }}>{page}</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</Box>
|
||||
|
||||
<Typography
|
||||
variant="h6"
|
||||
noWrap
|
||||
sx={{ display: { xs: "flex", md: "none" } }}
|
||||
>
|
||||
<em>owof</em> Announcements
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}>
|
||||
{pages.map((page) => (
|
||||
<RouterButton
|
||||
key={page}
|
||||
onClick={handleCloseNavMenu}
|
||||
sx={{ my: 2, color: "white", display: "block" }}
|
||||
to="."
|
||||
>
|
||||
{page}
|
||||
</RouterButton>
|
||||
))}
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
}}
|
||||
>
|
||||
<Toolbar sx={{ displayPrint: "none" }} />
|
||||
<Box
|
||||
component="main"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// src/components/ui/mui-router-button.tsx
|
||||
import { createLink } from "@tanstack/react-router";
|
||||
import { Button, type ButtonProps } from "@mui/material";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
// Create a router-compatible MUI Button
|
||||
export const RouterButton = createLink(
|
||||
forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
|
||||
return <Button ref={ref} component="button" {...props} />;
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,11 @@
|
||||
// src/components/ui/mui-router-fab.tsx
|
||||
import { createLink } from "@tanstack/react-router";
|
||||
import { Fab, type FabProps } from "@mui/material";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
// Router-compatible Floating Action Button
|
||||
export const RouterFab = createLink(
|
||||
forwardRef<HTMLButtonElement, FabProps>((props, ref) => {
|
||||
return <Fab ref={ref} {...props} />;
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,11 @@
|
||||
// src/components/ui/mui-router-link.tsx
|
||||
import { createLink } from "@tanstack/react-router";
|
||||
import { Link as MuiLink, type LinkProps } from "@mui/material";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
// Create a router-compatible MUI Link with full type safety
|
||||
export const RouterLink = createLink(
|
||||
forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
return <MuiLink ref={ref} {...props} />;
|
||||
}),
|
||||
);
|
||||
+18
-6
@@ -1,15 +1,27 @@
|
||||
import "@fontsource/roboto/300.css";
|
||||
import "@fontsource/roboto/400.css";
|
||||
import "@fontsource/roboto/500.css";
|
||||
import "@fontsource/roboto/700.css";
|
||||
import "@fontsource/raleway/300.css";
|
||||
import "@fontsource/raleway/400.css";
|
||||
import "@fontsource/raleway/500.css";
|
||||
import "@fontsource/raleway/700.css";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { RouterProvider, createRouter } from "@tanstack/react-router";
|
||||
|
||||
import App from "./App";
|
||||
// Import the generated route tree
|
||||
import { routeTree } from "./routeTree.gen";
|
||||
|
||||
// Create a new router instance
|
||||
const router = createRouter({ routeTree });
|
||||
|
||||
// Register the router instance for type safety
|
||||
declare module "@tanstack/react-router" {
|
||||
interface Register {
|
||||
router: typeof router;
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<RouterProvider router={router} />
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* 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'
|
||||
|
||||
export interface FileRoutesByFullPath {}
|
||||
export interface FileRoutesByTo {}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: never
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: never
|
||||
id: '__root__'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {}
|
||||
}
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
._addFileTypes<FileRouteTypes>()
|
||||
@@ -0,0 +1,19 @@
|
||||
import { CssBaseline } from "@mui/material";
|
||||
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
import { AppTheme } from "../theme";
|
||||
import DashboardLayout from "../components/DashboardLayout";
|
||||
|
||||
export const Route = createRootRoute({
|
||||
component: () => (
|
||||
<>
|
||||
<AppTheme>
|
||||
<CssBaseline enableColorScheme />
|
||||
<DashboardLayout>
|
||||
<Outlet />
|
||||
</DashboardLayout>
|
||||
<TanStackRouterDevtools />
|
||||
</AppTheme>
|
||||
</>
|
||||
),
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { createTheme, ThemeProvider } from "@mui/material";
|
||||
|
||||
const themeOptions = {
|
||||
palette: {
|
||||
secondary: {
|
||||
main: "#27a6b0",
|
||||
},
|
||||
primary: {
|
||||
main: "#d21981",
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
fontFamily: "Raleway",
|
||||
},
|
||||
shape: {
|
||||
borderRadius: 7,
|
||||
},
|
||||
spacing: 9,
|
||||
};
|
||||
|
||||
export const myTheme = createTheme(themeOptions);
|
||||
|
||||
export function AppTheme({ children }: React.PropsWithChildren<unknown>) {
|
||||
return <ThemeProvider theme={myTheme}>{children}</ThemeProvider>;
|
||||
}
|
||||
Reference in New Issue
Block a user