Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import { useState } from "react";
import { Link } from "react-router-dom";
import logo from "../assets/logo_light_160.png";
import logo_light from "../assets/logo_light_160.png";
import logo_dark from "../assets/logo_dark_160.png";
import { SideSheet } from "@douyinfe/semi-ui";
import { IconMenu } from "@douyinfe/semi-icons";
import { socials } from "../data/socials";
import ThemeToggle from "./ThemeToggle";
import { useTheme } from "../context/ThemeContext";

export default function Navbar() {
const [openMenu, setOpenMenu] = useState(false);
const { theme } = useTheme();

return (
<>
<div className="py-4 px-12 sm:px-4 flex justify-between items-center">
<div className="py-4 px-12 sm:px-4 flex justify-between items-center dark:bg-gray-900 dark:text-white">
<div className="flex items-center justify-between w-full">
<Link to="/">
<img src={logo} alt="logo" className="h-[48px] sm:h-[32px]" />
<img src={theme === "dark" ? logo_dark : logo_light} alt="logo" className="h-[48px] sm:h-[32px]" />
</Link>
<div className="md:hidden flex gap-12">
<Link
className="text-lg font-semibold hover:text-sky-800 transition-colors duration-300"
className="text-lg font-semibold hover:text-sky-800 dark:hover:text-sky-400 transition-colors duration-300"
onClick={() =>
document
.getElementById("features")
Expand All @@ -28,24 +32,25 @@ export default function Navbar() {
</Link>
<Link
to="/editor"
className="text-lg font-semibold hover:text-sky-800 transition-colors duration-300"
className="text-lg font-semibold hover:text-sky-800 dark:hover:text-sky-400 transition-colors duration-300"
>
Editor
</Link>
<Link
to="/templates"
className="text-lg font-semibold hover:text-sky-800 transition-colors duration-300"
className="text-lg font-semibold hover:text-sky-800 dark:hover:text-sky-400 transition-colors duration-300"
>
Templates
</Link>
<Link
to={socials.docs}
className="text-lg font-semibold hover:text-sky-800 transition-colors duration-300"
className="text-lg font-semibold hover:text-sky-800 dark:hover:text-sky-400 transition-colors duration-300"
>
Docs
</Link>
</div>
<div className="md:hidden block space-x-3 ms-12">
<div className="md:hidden flex items-center space-x-3 ms-12">
<ThemeToggle />
<a
title="Jump to Github"
className="px-2 py-2 hover:opacity-60 transition-all duration-300 rounded-full text-2xl"
Expand Down Expand Up @@ -85,14 +90,19 @@ export default function Navbar() {
<hr />
<SideSheet
title={
<img src={logo} alt="logo" className="sm:h-[32px] md:h-[42px]" />
<img src={theme === "dark" ? logo_dark : logo_light} alt="logo" className="sm:h-[32px] md:h-[42px]" />
}
visible={openMenu}
onCancel={() => setOpenMenu(false)}
width={window.innerWidth}
>
<div className="flex justify-between items-center p-3">
<span className="text-base font-semibold">Theme</span>
<ThemeToggle />
</div>
<hr />
<Link
className="hover:bg-zinc-100 block p-3 text-base font-semibold"
className="hover:bg-zinc-100 dark:hover:bg-gray-800 block p-3 text-base font-semibold"
onClick={() => {
document
.getElementById("features")
Expand All @@ -105,21 +115,21 @@ export default function Navbar() {
<hr />
<Link
to="/editor"
className="hover:bg-zinc-100 block p-3 text-base font-semibold"
className="hover:bg-zinc-100 dark:hover:bg-gray-800 block p-3 text-base font-semibold"
>
Editor
</Link>
<hr />
<Link
to="/templates"
className="hover:bg-zinc-100 block p-3 text-base font-semibold"
className="hover:bg-zinc-100 dark:hover:bg-gray-800 block p-3 text-base font-semibold"
>
Templates
</Link>
<hr />
<Link
to={socials.docs}
className="hover:bg-zinc-100 block p-3 text-base font-semibold"
className="hover:bg-zinc-100 dark:hover:bg-gray-800 block p-3 text-base font-semibold"
>
Docs
</Link>
Expand Down
23 changes: 23 additions & 0 deletions src/components/ThemeToggle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useTheme } from "../context/ThemeContext";

export default function ThemeToggle() {
const { theme, toggleTheme } = useTheme();

return (
<button
onClick={toggleTheme}
className="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors duration-300"
title={`Switch to ${theme === "light" ? "dark" : "light"} mode`}
>
{theme === "light" ? (
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clipRule="evenodd" />
</svg>
) : (
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
</svg>
)}
</button>
);
}
37 changes: 37 additions & 0 deletions src/context/ThemeContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { createContext, useContext, useEffect, useState } from "react";

const ThemeContext = createContext();

export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
};

export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");

useEffect(() => {
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
const initialTheme = savedTheme || systemTheme;

setTheme(initialTheme);
document.documentElement.classList.toggle("dark", initialTheme === "dark");
}, []);

const toggleTheme = () => {
const newTheme = theme === "light" ? "dark" : "light";
setTheme(newTheme);
localStorage.setItem("theme", newTheme);
document.documentElement.classList.toggle("dark", newTheme === "dark");
};

return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
5 changes: 5 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@
background-size: 20px 20px;
}

.dark .bg-dots {
background-color: rgb(31, 41, 55);
background-image: radial-gradient(rgb(118, 118, 209) 1px, rgb(31, 41, 55) 1px);
}

.sliding-vertical span {
animation: top-to-bottom 9s linear infinite 0s;
-ms-animation: top-to-bottom 9s linear infinite 0s;
Expand Down
Loading