+
+
}
visible={openMenu}
onCancel={() => setOpenMenu(false)}
width={window.innerWidth}
>
+
+ Theme
+
+
+
{
document
.getElementById("features")
@@ -105,21 +115,21 @@ export default function Navbar() {
Editor
Templates
Docs
diff --git a/src/components/ThemeToggle.jsx b/src/components/ThemeToggle.jsx
new file mode 100644
index 00000000..132bd314
--- /dev/null
+++ b/src/components/ThemeToggle.jsx
@@ -0,0 +1,23 @@
+import { useTheme } from "../context/ThemeContext";
+
+export default function ThemeToggle() {
+ const { theme, toggleTheme } = useTheme();
+
+ return (
+
+ {theme === "light" ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/context/ThemeContext.jsx b/src/context/ThemeContext.jsx
new file mode 100644
index 00000000..dec8f56c
--- /dev/null
+++ b/src/context/ThemeContext.jsx
@@ -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 (
+
+ {children}
+
+ );
+};
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index 44dabcd0..314778a6 100644
--- a/src/index.css
+++ b/src/index.css
@@ -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;
diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx
index 2638d733..aba9ec0e 100644
--- a/src/pages/LandingPage.jsx
+++ b/src/pages/LandingPage.jsx
@@ -18,6 +18,7 @@ import axios from "axios";
import { languages } from "../i18n/i18n";
import { Tweet } from "react-tweet";
import { socials } from "../data/socials";
+import { ThemeProvider } from "../context/ThemeContext";
function shortenNumber(number) {
if (number < 1000) return number;
@@ -36,7 +37,6 @@ export default function LandingPage() {
.then((res) => setStats(res.data));
};
- document.body.setAttribute("theme-mode", "light");
document.title =
"drawDB | Online database diagram editor and SQL generator";
@@ -44,8 +44,9 @@ export default function LandingPage() {
}, []);
return (
-
-
+
+
+
@@ -53,27 +54,27 @@ export default function LandingPage() {
{/* Hero section */}
-
+
-
+
-
+
Draw, Copy, and Paste
-
+
Free and open source, simple, and intuitive database design
editor, data-modeler, and SQL generator.{" "}
-
+
No sign up
-
+
Free of charge
-
+
Quick and easy
@@ -81,7 +82,7 @@ export default function LandingPage() {
document
.getElementById("learn-more")
@@ -103,10 +104,10 @@ export default function LandingPage() {
{/* Learn more */}
-
+
{/* Supported by */}
-
+
Supported by
@@ -114,21 +115,24 @@ export default function LandingPage() {
href="https://warp.dev/drawdb"
target="_blank"
rel="noreferrer"
+ className="block"
>
-
-
+
+
+
+
Next-gen AI-powered intelligent terminal for all platforms
-
-
+
+
Build diagrams with a few clicks, see the full picture, export SQL
scripts, customize your editor, and more.
@@ -136,31 +140,31 @@ export default function LandingPage() {
-
+
{shortenNumber(stats.stars)}
-
-
+
{shortenNumber(stats.forks)}
-
-
+
{shortenNumber(languages.length)}
-
-
+
Design for your database
@@ -169,7 +173,7 @@ export default function LandingPage() {
key={"icon-" + i}
src={s.icon}
style={{ height: s.height }}
- className="opacity-70 hover:opacity-100 transition-opacity duration-300 md:scale-[0.7] md:mx-auto"
+ className="opacity-70 hover:opacity-100 transition-all duration-300 md:scale-[0.7] md:mx-auto dark:brightness-125 dark:contrast-110 hover:scale-105"
/>
))}
@@ -184,30 +188,31 @@ export default function LandingPage() {
{/* Features */}
-
+
-
+
More than just an editor
-
+
What drawDB has to offer
{features.map((f, i) => (
-
{f.title}
- {f.content}
-
{f.footer}
+
{f.title}
+
{f.content}
+
{f.footer}
))}
@@ -216,8 +221,8 @@ export default function LandingPage() {
{/* Tweets */}
-
-
+
+
What the internet says about us
-
-
+
+
Reach out to us
-
+
We love hearing from you. Join our community on Discord, GitHub, and
X.
@@ -299,11 +305,12 @@ export default function LandingPage() {
Attention! The diagrams are saved in your browser. Before clearing the
browser make sure to back up your data.
-
-
+
+
© {new Date().getFullYear()} drawDB - All rights reserved.
-
+
+
);
}
diff --git a/tailwind.config.js b/tailwind.config.js
index 619a0f9f..661dae98 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -3,6 +3,7 @@ export default {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
+ darkMode: "class",
theme: {
screens: {
'3xl': {'max': '2047px'},