Skip to content

Commit

Permalink
feat:Dark Mode Toggle Feature (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
nitro56565 authored Nov 9, 2024
1 parent 5ee7ef5 commit e76ddd0
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 26 deletions.
59 changes: 58 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
"monaco-editor": "^0.50.0",
"node-stdlib-browser": "^1.2.0",
"normalize.css": "^8.0.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dark-mode-toggle": "^0.2.0",
"react-dom": "^18.2.0",
"react-dropdown": "^1.11.0",
"react-markdown": "^9.0.1",
Expand Down
6 changes: 4 additions & 2 deletions src/AgreementHtml.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import useAppStore from "./store/store";

function AgreementHtml({ loading }: { loading: any }) {
const agreementHtml = useAppStore((state) => state.agreementHtml);
const backgroundColor = useAppStore((state) => state.backgroundColor);
const textColor = useAppStore((state) => state.textColor);

return (
<div
Expand All @@ -18,7 +20,7 @@ function AgreementHtml({ loading }: { loading: any }) {
flexDirection: "column",
}}
>
<div style={{ textAlign: "center" }}>
<div style={{ textAlign: "center", color: textColor }}>
<h2>Preview Output</h2>
<p>
The result of merging the JSON data with the template. This is
Expand Down Expand Up @@ -47,7 +49,7 @@ function AgreementHtml({ loading }: { loading: any }) {
<div
className="agreement"
dangerouslySetInnerHTML={{ __html: agreementHtml }}
style={{ flex: 1 }}
style={{ flex: 1, color: textColor, backgroundColor: backgroundColor }}
/>
)}
</div>
Expand Down
38 changes: 30 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { App as AntdApp, Layout, Row, Col, Collapse, theme, Grid } from "antd";
import { App as AntdApp, Layout, Row, Col, Collapse, Grid } from "antd";
import { Routes, Route, useSearchParams } from "react-router-dom";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
Expand All @@ -15,13 +15,16 @@ import SampleDropdown from "./components/SampleDropdown";
import FullScreenModal from "./components/FullScreenModal";
import UseShare from "./components/UseShare";
import LearnContent from "./components/Content";
import ToggleDarkMode from "./components/ToggleDarkMode";

const { Content } = Layout;
const { useBreakpoint } = Grid;

const App = () => {
const init = useAppStore((state) => state.init);
const loadFromLink = useAppStore((state) => state.loadFromLink);
const backgroundColor = useAppStore((state) => state.backgroundColor);
const textColor = useAppStore((state) => state.textColor);
const [activePanel, setActivePanel] = useState<string | string[]>();
const [loading, setLoading] = useState(true);
const [searchParams] = useSearchParams();
Expand All @@ -33,9 +36,6 @@ const App = () => {
}
};

const {
token: { colorBgContainer },
} = theme.useToken();

const onChange = (key: string | string[]) => {
setActivePanel(key);
Expand All @@ -51,7 +51,26 @@ const App = () => {
setLoading(false);
};
initializeApp();
}, [init, loadFromLink, searchParams]);

// DarkMode Styles
const style = document.createElement("style");
style.innerHTML = `
.ant-collapse-header {
color: ${textColor} !important;
}
.ant-collapse-content {
background-color: ${backgroundColor} !important;
}
.ant-collapse-content-active {
background-color: ${backgroundColor} !important;
}
`;
document.head.appendChild(style);

return () => {
document.head.removeChild(style);
};
}, [init, loadFromLink, searchParams, textColor, backgroundColor]);

useEffect(() => {
const showTour = searchParams.get("showTour") === "true";
Expand Down Expand Up @@ -96,7 +115,7 @@ const App = () => {
padding: 24,
paddingBottom: 150,
minHeight: 360,
background: colorBgContainer,
background: backgroundColor,
}}
>
<Row id="explore">
Expand All @@ -121,7 +140,7 @@ const App = () => {
style={{
padding: 24,
minHeight: 360,
background: colorBgContainer,
background: backgroundColor,
}}
>
<Row gutter={24}>
Expand All @@ -138,7 +157,10 @@ const App = () => {
marginBottom: "10px",
}}
>
<FullScreenModal />
<div style={{ display: "flex" }}>
<ToggleDarkMode />
<FullScreenModal />
</div>
</div>
<AgreementHtml loading={loading} />
</Col>
Expand Down
28 changes: 26 additions & 2 deletions src/components/FullScreenModal.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { Modal } from "antd";
import AgreementHtml from "../AgreementHtml";
import { FullscreenOutlined } from "@ant-design/icons";
import useAppStore from "../store/store";

const FullScreenModal: React.FC = () => {
const [open, setOpen] = useState(false);
const textColor = useAppStore((state) => state.textColor);
const backgroundColor = useAppStore((state) => state.backgroundColor);

useEffect(() => {
const style = document.createElement("style");
style.innerHTML = `
.ant-modal-content {
background-color: ${backgroundColor} !important;
color: ${textColor} !important;
}
.ant-modal-header {
background-color: ${backgroundColor} !important;
color: ${textColor} !important;
}
.ant-modal-title{
color: ${textColor} !important;
}
`;
document.head.appendChild(style);
return () => {
document.head.removeChild(style);
};
}, [textColor, backgroundColor]);

return (
<div style={{ textAlign: "right" }} className="preview-element">
<div style={{ textAlign: "right", display: "flex", alignItems: "center", justifyContent: "flex-end", width: "100%", color: textColor, }} className="preview-element">
<FullscreenOutlined
style={{ fontSize: "24px", cursor: "pointer", marginRight: "10px" }}
onClick={() => setOpen(true)}
Expand Down
31 changes: 31 additions & 0 deletions src/components/ToggleDarkMode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, { useEffect, useState } from "react";
import { ToggleDarkModeContainer } from "../styles/components/ToggleDarkMode";
import DarkModeToggle from "react-dark-mode-toggle";
import useAppStore from "../store/store";

const ToggleDarkMode: React.FC = () => {
const { backgroundColor, toggleDarkMode } = useAppStore();
const [isDarkMode, setIsDarkMode] = useState(backgroundColor === "#121212");

useEffect(() => {
setIsDarkMode(backgroundColor === "#121212");
}, [backgroundColor]);

const handleChange = () => {
toggleDarkMode();
setIsDarkMode((prev) => !prev);
};

return (
<ToggleDarkModeContainer>
<DarkModeToggle
className="dark-mode-toggle"
onChange={handleChange}
checked={isDarkMode}
size={80}
/>
</ToggleDarkModeContainer>
);
};

export default ToggleDarkMode;
45 changes: 39 additions & 6 deletions src/editors/MarkdownEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as monaco from "@monaco-editor/react";
import { editor } from "monaco-editor";
import { useEffect } from "react";
import Editor, { useMonaco } from "@monaco-editor/react";
import useAppStore from "../store/store";

const options: editor.IStandaloneEditorConstructionOptions = {
const options = {
minimap: { enabled: false },
wordWrap: "on",
wordWrap: "on" as const,
automaticLayout: true,
scrollBeyondLastLine: false,
};
Expand All @@ -15,15 +16,47 @@ export default function MarkdownEditor({
value: string;
onChange?: (value: string | undefined) => void;
}) {
const monaco = useMonaco();
const backgroundColor = useAppStore((state) => state.backgroundColor);
const textColor = useAppStore((state) => state.textColor);

useEffect(() => {
if (monaco) {
monaco.editor.defineTheme("lightTheme", {
base: "vs",
inherit: true,
rules: [],
colors: {
"editor.background": backgroundColor,
"editor.foreground": textColor,
"editor.lineHighlightBorder": "#EDE8DC",
},
});

monaco.editor.defineTheme("darkTheme", {
base: "vs-dark",
inherit: true,
rules: [],
colors: {
"editor.background": backgroundColor,
"editor.foreground": textColor,
"editor.lineHighlightBorder": "#EDE8DC",
},
});
monaco.editor.setTheme(backgroundColor ? "darkTheme" : "lightTheme");
}
}, [monaco, backgroundColor, textColor]);

return (
<div className="editorwrapper">
<monaco.Editor
<Editor
options={options}
language="markdown"
height="60vh"
value={value}
onChange={onChange}
theme={backgroundColor ? "darkTheme" : "lightTheme"}
/>
</div>
);
}
}
Loading

0 comments on commit e76ddd0

Please sign in to comment.