mirror of
https://github.com/Lumither/nocturne.git
synced 2026-10-17 10:26:21 +00:00
feat(navbar) a navbar with theme switcher
This commit is contained in:
1 parent
65e7c101ac
commit
d26d45c65a
7 files changed
+139
-11
No files matched your search
@@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function About() {
|
||||||
|
return (
|
||||||
|
<div></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default About;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function Blog() {
|
||||||
|
return (
|
||||||
|
<div></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Blog;
|
||||||
@@ -3,6 +3,7 @@ import { Inter } from 'next/font/google';
|
|||||||
import './globals.css';
|
import './globals.css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
||||||
|
import Navbar from '@/components/Navbar';
|
||||||
|
|
||||||
const inter = Inter({ subsets: [ 'latin' ] });
|
const inter = Inter({ subsets: [ 'latin' ] });
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ export default function RootLayout({
|
|||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" suppressHydrationWarning>
|
||||||
<body className={ inter.className }>
|
<body className={ inter.className }>
|
||||||
<NextThemesProvider attribute="class" defaultTheme="dark">
|
<NextThemesProvider attribute="class" defaultTheme="dark">
|
||||||
|
<Navbar />
|
||||||
{ children }
|
{ children }
|
||||||
</NextThemesProvider>
|
</NextThemesProvider>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
import ThemeSwitcher from '@/components/ThemeSwitcher';
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<ThemeSwitcher />
|
{/*<ThemeSwitcher />*/ }
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import {
|
||||||
|
Navbar as NextUINavbar,
|
||||||
|
NavbarBrand,
|
||||||
|
NavbarContent,
|
||||||
|
NavbarItem,
|
||||||
|
NavbarMenu,
|
||||||
|
NavbarMenuItem,
|
||||||
|
NavbarMenuToggle
|
||||||
|
} from '@nextui-org/react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
import ThemeSwitcher from '@/components/ThemeSwitcher';
|
||||||
|
|
||||||
|
|
||||||
|
const entries: { display_name: string; href: string; }[] = [
|
||||||
|
{
|
||||||
|
display_name: 'Home',
|
||||||
|
href: '/'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display_name: 'About',
|
||||||
|
href: '/about'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
display_name: 'Blog',
|
||||||
|
href: '/blog'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function Navbar() {
|
||||||
|
const [ scrolled, setScrolled ] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
const isScrolled = window.scrollY > 0;
|
||||||
|
setScrolled(isScrolled);
|
||||||
|
};
|
||||||
|
window.addEventListener('scroll', handleScroll);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('scroll', handleScroll);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NextUINavbar isBlurred isBordered>
|
||||||
|
<NavbarContent className="sm:hidden" justify="start">
|
||||||
|
<NavbarMenuToggle />
|
||||||
|
</NavbarContent>
|
||||||
|
|
||||||
|
<NavbarContent className="sm:hidden pr-3" justify="center">
|
||||||
|
<NavbarBrand>
|
||||||
|
<p className="font-bold text-inherit">{ 'Lumither\'s site' }</p>
|
||||||
|
</NavbarBrand>
|
||||||
|
</NavbarContent>
|
||||||
|
|
||||||
|
<NavbarContent className="hidden sm:flex gap-4" justify="center">
|
||||||
|
<NavbarBrand>
|
||||||
|
<p className="font-bold text-inherit">{ 'Lumither\'s site' }</p>
|
||||||
|
</NavbarBrand>
|
||||||
|
|
||||||
|
{ entries.map((item, index) => (
|
||||||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
<NavbarItem key={ index } isActive={ usePathname() === item.href }>
|
||||||
|
<Link
|
||||||
|
className="w-full"
|
||||||
|
href={ item.href }
|
||||||
|
>
|
||||||
|
{ item.display_name }
|
||||||
|
</Link>
|
||||||
|
</NavbarItem>
|
||||||
|
)) }
|
||||||
|
</NavbarContent>
|
||||||
|
|
||||||
|
<NavbarContent justify="end">
|
||||||
|
<NavbarItem>
|
||||||
|
<ThemeSwitcher />
|
||||||
|
</NavbarItem>
|
||||||
|
</NavbarContent>
|
||||||
|
|
||||||
|
<NavbarMenu>
|
||||||
|
{ entries.map((item, index) => (
|
||||||
|
<NavbarMenuItem key={ index }>
|
||||||
|
<Link
|
||||||
|
className="w-full"
|
||||||
|
href={ item.href }
|
||||||
|
>
|
||||||
|
{ item.display_name }
|
||||||
|
</Link>
|
||||||
|
</NavbarMenuItem>
|
||||||
|
)) }
|
||||||
|
</NavbarMenu>
|
||||||
|
</NextUINavbar>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Navbar;
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
import { Button } from '@nextui-org/react';
|
import { Switch } from '@nextui-org/react';
|
||||||
|
import { MdOutlineDarkMode, MdOutlineLightMode } from 'react-icons/md';
|
||||||
|
|
||||||
function ThemeSwitcher() {
|
function ThemeSwitcher() {
|
||||||
const [ mounted, setMounted ] = useState(false);
|
const [ mounted, setMounted ] = useState(false);
|
||||||
@@ -18,12 +19,18 @@ function ThemeSwitcher() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={ () => {
|
<Switch
|
||||||
setTheme('light');
|
color={ 'default' }
|
||||||
} }>Light Mode</Button>
|
startContent={ <MdOutlineLightMode /> }
|
||||||
<Button onClick={ () => {
|
endContent={ <MdOutlineDarkMode /> }
|
||||||
setTheme('dark');
|
onValueChange={ (isSelected) => {
|
||||||
} }>Dark Mode</Button>
|
if (isSelected) {
|
||||||
|
setTheme('light');
|
||||||
|
} else {
|
||||||
|
setTheme('dark');
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
></Switch>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -14,7 +14,8 @@
|
|||||||
"next": "14.2.2",
|
"next": "14.2.2",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18",
|
||||||
|
"react-icons": "^5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
|
|||||||
Reference in new issue
Block a user