feat: add editor theme switch.

This commit is contained in:
jaywcjlove
2022-09-02 17:06:30 +08:00
parent cbaad4e0fc
commit e9b3b60f6d
7 changed files with 127 additions and 9 deletions

View File

@@ -9,6 +9,19 @@
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.9",
"@uiw/codemirror-theme-abcdef": "^4.11.6",
"@uiw/codemirror-theme-androidstudio": "^4.11.6",
"@uiw/codemirror-theme-atomone": "^4.11.6",
"@uiw/codemirror-theme-bbedit": "^4.11.6",
"@uiw/codemirror-theme-bespin": "^4.11.6",
"@uiw/codemirror-theme-darcula": "^4.11.6",
"@uiw/codemirror-theme-dracula": "^4.11.6",
"@uiw/codemirror-theme-duotone": "^4.11.6",
"@uiw/codemirror-theme-eclipse": "^4.11.6",
"@uiw/codemirror-theme-github": "^4.11.6",
"@uiw/codemirror-theme-okaidia": "^4.11.6",
"@uiw/codemirror-theme-sublime": "^4.11.6",
"@uiw/codemirror-theme-xcode": "^4.11.6",
"@uiw/react-back-to-top": "^1.2.0",
"@uiw/react-github-corners": "^1.5.15",
"@uiw/react-markdown-editor": "^5.3.2",

View File

@@ -31,6 +31,7 @@ const Title = styled.h1`
margin: 0;
display: flex;
align-items: center;
user-select: none;
sup {
color: var(--color-fg-subtle);
margin-left: 0.4rem;
@@ -38,6 +39,8 @@ const Title = styled.h1`
border-radius: 0.1rem;
padding: 0 0.2rem;
font-weight: normal;
font-size: 0.1rem;
letter-spacing: -0.1rem;
}
`;
@@ -46,7 +49,7 @@ const Section = styled.section`
align-items: center;
gap: 0.8rem;
dark-mode {
font-size: 1.4rem;
font-size: 1.2rem;
}
a svg {
display: block;
@@ -67,7 +70,7 @@ export function Layout() {
<Section>
<dark-mode permanent dark="Dark" light="Light" />
<a href="https://github.com/jaywcjlove/wxmp" target="__blank">
<GithubIcon width={28} height={28} />
<GithubIcon width={23} height={23} />
</a>
</Section>
</Header>

View File

@@ -5,6 +5,7 @@ import BackToUp from '@uiw/react-back-to-top';
import { Toaster } from 'react-hot-toast';
import { createGlobalStyle } from 'styled-components';
import App from './App';
import { Provider } from './store/context';
export const GlobalStyle = createGlobalStyle`
[data-color-mode*='dark'], [data-color-mode*='dark'] body {
@@ -56,6 +57,8 @@ root.render(
<Toaster />
<BackToUp>Top</BackToUp>
<GlobalStyle />
<App />
<Provider>
<App />
</Provider>
</HashRouter>,
);

View File

@@ -1,26 +1,31 @@
import MarkdownEditor, { getCommands } from '@uiw/react-markdown-editor';
import { useContext } from 'react';
import { EditorView } from "@codemirror/view";
import styled from 'styled-components';
import data from '../../../README.md';
import { Preview } from './Preview';
import { copy } from './copy'
import { copy } from './copy';
import { theme as themeCommand } from './theme';
import { Context, themes } from '../../store/context';
import data from '../../../README.md';
const Warpper = styled.div`
height: calc(100vh - 2.9rem);
height: calc(100vh - 2.8rem);
`;
export const HomePage = () => {
const commands = getCommands();
const commands = [...getCommands(), themeCommand];
const { theme } = useContext(Context);
return (
<Warpper>
<MarkdownEditor
value={data.source}
toolbars={commands}
theme={themes[theme]}
toolbarsMode={[copy, 'preview', 'fullscreen']}
extensions={[EditorView.lineWrapping]}
renderPreview={Preview}
visible={true}
height="calc(100vh - 5.0rem)"
height="calc(100vh - 4.9rem)"
/>
</Warpper>
);

45
src/pages/home/theme.tsx Normal file
View File

@@ -0,0 +1,45 @@
import React, { useContext } from 'react';
import { ICommand, IMarkdownEditor, ToolBarProps } from '@uiw/react-markdown-editor';
import styled from 'styled-components';
import { Context } from '../../store/context';
const Select = styled.select`
max-width: 3rem;
`;
const ThemeView: React.FC<{ command: ICommand; editorProps: IMarkdownEditor & ToolBarProps }> = (props) => {
const { theme, setTheme } = useContext(Context);
const handleChange = (ev: React.ChangeEvent<HTMLSelectElement>) => setTheme(ev.target.value as any)
return (
<Select value={theme} onChange={handleChange}>
<option value="abcdef">Abcdef Theme</option>
<option value="androidstudio">Android Studio Theme</option>
<option value="atomone">Atomone Theme</option>
<option value="bbedit">Bbedit Theme</option>
<option value="bespin">Bespin Theme</option>
<option value="darcula">Darcula Theme</option>
<option value="dracula">Dracula Theme</option>
<option value="duotoneLight">Duotone Light Theme</option>
<option value="duotoneDark">Duotone Dark Theme</option>
<option value="eclipse">Eclipse Theme</option>
<option value="githubLight">Github Light Theme</option>
<option value="githubDark">Github Dark Theme</option>
<option value="okaidia">Okaidia Theme</option>
<option value="sublime">Sublime Theme</option>
<option value="xcodeLight">Xcode Light Theme</option>
<option value="xcodeDark">Xcode Dark Theme</option>
</Select>
);
};
export const theme: ICommand = {
name: 'theme',
keyCommand: 'theme',
button: (command, props, opts) => <ThemeView command={command} editorProps={{ ...props, ...opts }} />,
icon: (
<svg fill="currentColor" viewBox="0 0 24 24" height="16" width="16">
<path d="M20 2H10a2 2 0 0 0-2 2v2h8a2 2 0 0 1 2 2v8h2a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z"/>
<path d="M4 22h10c1.103 0 2-.897 2-2V10c0-1.103-.897-2-2-2H4c-1.103 0-2 .897-2 2v10c0 1.103.897 2 2 2zm2-10h6v2H6v-2zm0 4h6v2H6v-2z"/>
</svg>
),
};

50
src/store/context.tsx Normal file
View File

@@ -0,0 +1,50 @@
import React from "react";
import { abcdef } from '@uiw/codemirror-theme-abcdef';
import { androidstudio } from '@uiw/codemirror-theme-androidstudio';
import { atomone } from '@uiw/codemirror-theme-atomone';
import { bbedit } from '@uiw/codemirror-theme-bbedit';
import { bespin } from '@uiw/codemirror-theme-bespin';
import { darcula } from '@uiw/codemirror-theme-darcula';
import { dracula } from '@uiw/codemirror-theme-dracula';
import { duotoneLight, duotoneDark } from '@uiw/codemirror-theme-duotone';
import { eclipse } from '@uiw/codemirror-theme-eclipse';
import { githubLight, githubDark } from '@uiw/codemirror-theme-github';
import { okaidia } from '@uiw/codemirror-theme-okaidia';
import { sublime } from '@uiw/codemirror-theme-sublime';
import { xcodeLight, xcodeDark } from '@uiw/codemirror-theme-xcode';
export const themes = { abcdef, androidstudio, atomone, bbedit, bespin, darcula, dracula, duotoneLight, duotoneDark, eclipse,
githubLight, githubDark, okaidia, sublime, xcodeLight, xcodeDark
}
export type ThemeValue = keyof typeof themes;
export interface CreateContext {
css: string;
setCss: React.Dispatch<React.SetStateAction<string>>;
theme: ThemeValue;
setTheme: React.Dispatch<React.SetStateAction<ThemeValue>>;
}
export const Context = React.createContext<CreateContext>({
css: "",
setCss: () => {},
theme: 'githubLight',
setTheme: () => {},
});
export const Provider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [css, setCss] = React.useState("");
const [theme, setTheme] = React.useState<ThemeValue>("githubLight");
return (
<Context.Provider
value={{
css, setCss,
theme, setTheme,
}}
>
{children}
</Context.Provider>
);
};

View File

@@ -27,7 +27,6 @@ export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLO
});
// @ts-ignore
const data = cssdata(ast.children.head);
console.log(data)
const processor = unified()
.use(remarkParse)
.use(remarkGfm)