Skip to content

Commit

Permalink
✨ add nextui
Browse files Browse the repository at this point in the history
  • Loading branch information
w3cj committed Sep 12, 2024
1 parent daf83f9 commit b1934f4
Show file tree
Hide file tree
Showing 13 changed files with 4,884 additions and 1,284 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public-hoist-pattern[]=*@nextui-org/*
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"format": "prettier src/ --write"
},
"dependencies": {
"@nextui-org/react": "^2.4.6",
"@tabler/icons-react": "^3.16.0",
"framer-motion": "^11.5.4",
"next": "14.2.9",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18"
},
Expand Down
5,943 changes: 4,670 additions & 1,273 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions public/dark-bg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions public/light-bg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 12 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { Metadata } from "next";

import AppNavbar from "@/components/app-navbar";
import Providers from "@/components/providers";

import "./globals.css";

export const metadata: Metadata = {
Expand All @@ -13,14 +16,21 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en">
<html lang="en" suppressHydrationWarning>
<head>
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📦</text></svg>"
/>
</head>
<body>{children}</body>
<body className="h-screen w-screen">
<Providers>
<AppNavbar />
<main className="flex-grow overflow-auto bg-[url(/light-bg.svg)] bg-cover dark:bg-[url(/dark-bg.svg)]">
{children}
</main>
</Providers>
</body>
</html>
);
}
15 changes: 15 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Card, CardBody } from "@nextui-org/react";
import { IconFileUnknown } from "@tabler/icons-react";

export default function NotFound() {
return (
<Card className="mx-auto mt-4 max-w-md">
<CardBody>
<p className="flex items-center justify-center gap-2 text-2xl">
<IconFileUnknown />
This page cannot be found.
</p>
</CardBody>
</Card>
);
}
11 changes: 10 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import { Card, CardBody } from "@nextui-org/react";

export default function Home() {
return <h1>Hello World</h1>;
return (
<Card className="mx-auto mt-4 max-w-md">
<CardBody className="text-center">
<h1 className="text-5xl">Next.js Starter</h1>
<p className="text-xl">A simple starter for Next.js</p>
</CardBody>
</Card>
);
}
72 changes: 72 additions & 0 deletions src/components/app-navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"use client";

import React from "react";

import {
Link,
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
NavbarMenu,
NavbarMenuItem,
NavbarMenuToggle,
} from "@nextui-org/react";
import { IconPackage } from "@tabler/icons-react";

import { ThemeSwitcher } from "./theme-switcher";

export default function AppNavbar() {
const [isMenuOpen, setIsMenuOpen] = React.useState(false);

const menuItems = [
{
label: "Home",
href: "/",
},
{
label: "Profile",
href: "/profile",
},
];

return (
<Navbar onMenuOpenChange={setIsMenuOpen}>
<NavbarContent>
<NavbarMenuToggle
aria-label={isMenuOpen ? "Close menu" : "Open menu"}
className="sm:hidden"
/>
<NavbarBrand>
<IconPackage />
<p className="font-bold text-inherit">Next.js Starter</p>
</NavbarBrand>
</NavbarContent>

<NavbarContent className="hidden gap-4 sm:flex" justify="center">
{menuItems.map((item, index) => (
<NavbarItem key={`${item}-${index}`}>
<Link className="w-full" href={item.href} size="lg">
{item.label}
</Link>
</NavbarItem>
))}
<NavbarItem>
<ThemeSwitcher />
</NavbarItem>
</NavbarContent>
<NavbarMenu>
<NavbarMenuItem>
<ThemeSwitcher showLabel />
</NavbarMenuItem>
{menuItems.map((item, index) => (
<NavbarMenuItem key={`${item}-${index}`}>
<Link className="w-full" href={item.href} size="lg">
{item.label}
</Link>
</NavbarMenuItem>
))}
</NavbarMenu>
</Navbar>
);
}
21 changes: 21 additions & 0 deletions src/components/providers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";

import { useRouter } from "next/navigation";
import { ReactNode } from "react";

import { NextUIProvider } from "@nextui-org/react";
import { ThemeProvider as NextThemesProvider } from "next-themes";

export default function Providers({ children }: { children: ReactNode }) {
const router = useRouter();
return (
<NextUIProvider
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
navigate={router.push}
className="flex h-full w-full flex-col"
>
<NextThemesProvider attribute="class">{children}</NextThemesProvider>
</NextUIProvider>
);
}
34 changes: 34 additions & 0 deletions src/components/theme-switcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { useEffect, useState } from "react";

import { Switch } from "@nextui-org/react";
import { IconMoon, IconSun } from "@tabler/icons-react";

import useSystemTheme from "@/hooks/use-system-theme";

export function ThemeSwitcher({ showLabel }: { showLabel?: boolean }) {
const [mounted, setMounted] = useState(false);
const { theme, setTheme } = useSystemTheme();

useEffect(() => {
setMounted(true);
}, []);

if (!mounted) return null;

return (
<Switch
isSelected={theme === "light"}
onValueChange={() =>
theme === "dark" ? setTheme("light") : setTheme("dark")
}
size="lg"
color="success"
startContent={<IconSun />}
endContent={<IconMoon />}
>
{showLabel && "Theme"}
</Switch>
);
}
16 changes: 16 additions & 0 deletions src/hooks/use-system-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Dispatch, SetStateAction, useMemo } from "react";

import { useTheme } from "next-themes";

type Theme = "dark" | "light";
type SetTheme = Dispatch<SetStateAction<Theme>>;

export default function useSystemTheme() {
const { theme, setTheme, systemTheme } = useTheme();
return useMemo(() => {
return {
theme: theme === "system" ? systemTheme : theme,
setTheme,
} as { theme: Theme; setTheme: SetTheme };
}, [theme, setTheme, systemTheme]);
}
13 changes: 5 additions & 8 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { nextui } from "@nextui-org/react";
import type { Config } from "tailwindcss";

const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
"./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
extend: {},
},
plugins: [],
darkMode: "class",
plugins: [nextui()],
};
export default config;

0 comments on commit b1934f4

Please sign in to comment.