From 8f62d4102013363827929d811f08d7e821715545 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 6 Sep 2022 00:06:36 +0800 Subject: [PATCH] feat: add color palette. --- README.md | 4 +-- website/src/commands/color.tsx | 42 ++++++++++++++++++++++++ website/src/commands/copy.tsx | 7 ++-- website/src/commands/theme.tsx | 1 - website/src/components/Layout.tsx | 6 ++-- website/src/pages/home/Preview.tsx | 4 +-- website/src/pages/home/index.tsx | 3 +- website/src/pages/theme/Preview.tsx | 7 ++-- website/src/store/Provider.tsx | 6 ++++ website/src/store/context.tsx | 41 ++++++++++++++++++++++++ website/src/themes/base.md.css | 22 ++++++------- website/src/themes/default.md.css | 45 +++++++++++++------------- website/src/themes/simple.md.css | 47 ++++++++++++++------------- website/src/themes/underscore.md.css | 40 ++++++++++++----------- website/src/utils/css.ts | 48 ++++++++++++++++++++++++---- website/src/utils/markdownToHTML.ts | 11 ++++--- 16 files changed, 232 insertions(+), 102 deletions(-) create mode 100644 website/src/commands/color.tsx diff --git a/README.md b/README.md index d7325ed..914507b 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,11 @@ - [x] 支持主题选择 & 编辑预览。 - [x] 支持明暗两种主题预览。 - [ ] 支持代码块主题样式选择。 -- [ ] 支持全局字号大小选择。 -- [ ] 支持色盘取色,快速替换文章整体色调 +- [x] 支持色盘取色,快速替换文章整体色调 - [x] 支持 URL 参数加载 Markdown 内容。 - [x] 支持 URL 参数选择预览主题。 - [x] CI 自动生成 Electron 桌面应用。 +- [ ] ~~支持全局字号大小选择。~~ ### 支持代码块样式 diff --git a/website/src/commands/color.tsx b/website/src/commands/color.tsx new file mode 100644 index 0000000..fc39450 --- /dev/null +++ b/website/src/commands/color.tsx @@ -0,0 +1,42 @@ +import React, { useContext } from 'react'; +import { ICommand } from '@uiw/react-markdown-editor'; +import styled from 'styled-components'; +import { Context } from '../store/context'; + +const Input = styled.input` + position: absolute; + opacity: 0; + height: 20px; + width: 20px; +`; + +const Button = styled.button``; + +const ColorView: React.FC<{}> = (props) => { + const { preColor, setPreColor } = useContext(Context); + const handleChange = (evn: React.ChangeEvent) => { + setPreColor(evn.target.value); + }; + const color = preColor ? preColor : 'currentColor'; + return ( + + ); +}; + +export const colorCommand: ICommand = { + name: 'color', + keyCommand: 'color', + button: () => , +}; diff --git a/website/src/commands/copy.tsx b/website/src/commands/copy.tsx index 21de72c..2310b17 100644 --- a/website/src/commands/copy.tsx +++ b/website/src/commands/copy.tsx @@ -4,11 +4,10 @@ import toast from 'react-hot-toast'; import styled from 'styled-components'; const Button = styled.button` - white-space: nowrap; + /* white-space: nowrap; width: initial !important; display: flex; - align-items: center; - padding: 0 0.4rem !important; + align-items: center; */ `; const CopyView: React.FC<{ command: ICommand; editorProps: IMarkdownEditor & ToolBarProps }> = (props) => { @@ -27,7 +26,7 @@ const CopyView: React.FC<{ command: ICommand; editorProps: IMarkdownEditor & Too }; return ( ); }; diff --git a/website/src/commands/theme.tsx b/website/src/commands/theme.tsx index 90c7e3e..d584460 100644 --- a/website/src/commands/theme.tsx +++ b/website/src/commands/theme.tsx @@ -49,7 +49,6 @@ const ThemePreviewView: React.FC<{}> = () => { const { setCss, previewTheme, setPreviewTheme } = useContext(Context); const handleChange = (ev: React.ChangeEvent) => { const value = ev.target.value as PreviewThemeValue; - console.log('vvvv'); setPreviewTheme(value); setCss(previewThemes[value].value); }; diff --git a/website/src/components/Layout.tsx b/website/src/components/Layout.tsx index 4c68ef0..eb5ee19 100644 --- a/website/src/components/Layout.tsx +++ b/website/src/components/Layout.tsx @@ -72,14 +72,16 @@ const Section = styled.section` text-decoration: none; color: var(--color-theme-text); padding: 0.1rem 0.3rem; - box-shadow: inset 0 0 0 var(--color-accent-fg); transition: all 0.3s; font-size: 0.9rem; + border-radius: 0.2rem; &.active { + background-color: var(--color-accent-fg); box-shadow: inset 0 -0.3rem 0 var(--color-accent-fg); + color: #fff; } &:hover:not(.active):not(:last-child) { - box-shadow: inset 0 -1.5rem 0 var(--color-accent-fg); + background-color: var(--color-accent-fg); color: #fff; border-radius: 0.2rem; } diff --git a/website/src/pages/home/Preview.tsx b/website/src/pages/home/Preview.tsx index 20d8a26..b62a6b3 100644 --- a/website/src/pages/home/Preview.tsx +++ b/website/src/pages/home/Preview.tsx @@ -14,7 +14,7 @@ export const Warpper = styled.div` `; export const Preview = (props: MarkdownPreviewProps) => { - const { css } = useContext(Context); - const html = markdownToHTML(props.source || '', css); + const { css, preColor, previewTheme } = useContext(Context); + const html = markdownToHTML(props.source || '', css, { preColor, previewTheme }); return ; }; diff --git a/website/src/pages/home/index.tsx b/website/src/pages/home/index.tsx index d730c02..386b307 100644 --- a/website/src/pages/home/index.tsx +++ b/website/src/pages/home/index.tsx @@ -3,6 +3,7 @@ import { useContext } from 'react'; import { EditorView } from '@codemirror/view'; import { Preview } from './Preview'; import { copy } from '../../commands/copy'; +import { colorCommand } from '../../commands/color'; import { theme as themeCommand, previeTheme } from '../../commands/theme'; import { cssCommand } from '../../commands/css'; import { Context, themes } from '../../store/context'; @@ -18,7 +19,7 @@ export const HomePage = () => { toolbars={commands} theme={themeValue} readOnly={isLoading} - toolbarsMode={[cssCommand, previeTheme, copy, 'fullscreen', 'preview']} + toolbarsMode={[cssCommand, previeTheme, copy, colorCommand, 'fullscreen', 'preview']} extensions={[EditorView.lineWrapping]} renderPreview={Preview} previewWidth="420px" diff --git a/website/src/pages/theme/Preview.tsx b/website/src/pages/theme/Preview.tsx index 0e294e4..d3f99c6 100644 --- a/website/src/pages/theme/Preview.tsx +++ b/website/src/pages/theme/Preview.tsx @@ -1,12 +1,11 @@ -import { MarkdownPreviewProps } from '@uiw/react-markdown-preview'; import { useContext } from 'react'; import { Context } from '../../store/context'; import { markdownToHTML } from '../../utils/markdownToHTML'; import { Warpper } from '../home/Preview'; -export const Preview = (props: MarkdownPreviewProps) => { - const { css, markdown } = useContext(Context); - const html = markdownToHTML(markdown, css); +export const Preview = () => { + const { css, markdown, preColor, previewTheme } = useContext(Context); + const html = markdownToHTML(markdown, css, { preColor, previewTheme }); return ; }; diff --git a/website/src/store/Provider.tsx b/website/src/store/Provider.tsx index 1e2b32a..7400ebf 100644 --- a/website/src/store/Provider.tsx +++ b/website/src/store/Provider.tsx @@ -12,6 +12,9 @@ export const Provider: React.FC = ({ children }) => { const [css, setCss] = React.useState(previewThemes[initPreviewTheme].value); const [previewTheme, setPreviewTheme] = React.useState(initPreviewTheme); const [theme, setTheme] = React.useState('default'); + const [preColor, setPreColor] = React.useState( + previewThemes[initPreviewTheme] ? previewThemes[initPreviewTheme].color : '', + ); const [isLoading, setIsLoading] = React.useState(true); const { data: mddata, isLoading: loading } = useMdSource(mdurl); useEffect(() => { @@ -26,9 +29,12 @@ export const Provider: React.FC = ({ children }) => { } }, [mddata, mdurl]); useEffect(() => setIsLoading(loading), [loading]); + useEffect(() => setPreColor(previewThemes[initPreviewTheme].color), [initPreviewTheme]); return ( = { + underscore: [ + { select: 'a', name: 'color', value: '{{color}}' }, + { select: 'h1', name: 'box-shadow', value: 'inset 0 -0.9rem 0 0 {{color}}' }, + { select: 'h2', name: 'box-shadow', value: 'inset 0 -0.7rem 0 0 {{color}}' }, + { select: 'h3', name: 'border-left', value: '5px solid {{color}}' }, + ], + default: [ + { select: 'a', name: 'color', value: '{{color}}' }, + { select: 'h1', name: 'border-bottom', value: '3px solid {{color}}' }, + { select: 'h2', name: 'background', value: '{{color}}' }, + { select: 'h3', name: 'border-left', value: '5px solid {{color}}' }, + ], + simple: [ + { select: 'a', name: 'color', value: '{{color}}' }, + { select: 'h1', name: 'border-bottom', value: '3px solid {{color}}' }, + { select: 'h2', name: 'background', value: '{{color}}' }, + { select: 'h3', name: 'border-left', value: '5px solid {{color}}' }, + { select: '.code-spans', name: 'color', value: '{{color}}' }, + ], + base: [], +}; + +export type ReplaceData = { + select: string; + name: string; + value: string; +}; + +export const colors = (Object.keys(previewThemes) as Array).map( + (key) => previewThemes[key].color, +); export type ThemeValue = keyof typeof themes; export type PreviewThemeValue = keyof typeof previewThemes; export interface CreateContext { + preColor: string; + setPreColor: React.Dispatch>; isLoading: boolean; setIsLoading: React.Dispatch>; markdown: string; @@ -129,6 +168,8 @@ export interface CreateContext { } export const Context = React.createContext({ + preColor: '', + setPreColor: () => {}, isLoading: true, setIsLoading: () => {}, markdown: data.source, diff --git a/website/src/themes/base.md.css b/website/src/themes/base.md.css index 13caff3..27373bd 100644 --- a/website/src/themes/base.md.css +++ b/website/src/themes/base.md.css @@ -5,14 +5,14 @@ a { h1 { color: inherit; - font-size: 1.5rem; + font-size: 16px; font-weight: bold; } h2 { color: inherit; margin: 2.5rem 0 1rem 0; - font-size: 1.3em; + font-size: 16px; font-weight: bold; } @@ -20,19 +20,19 @@ h3 { color: inherit; margin: 1em 0 1em 0; font-weight: bold; - font-size: 1em; + font-size: 14px; } h4 { color: inherit; margin: 0.6em 0 0.6em 0; font-weight: bold; - font-size: 0.9em; + font-size: 12px; } p { color: initial; - font-size: 0.85em; + font-size: 14px; line-height: 1.5em; } @@ -46,7 +46,7 @@ ol { li { margin: 0; - font-size: 0.85em; + font-size: 14px; line-height: 1.5em; } @@ -63,7 +63,7 @@ pre { padding: 1em; color: rgb(51, 51, 51); background: rgb(248, 248, 248); - font-size: 0.85em; + font-size: 14px; font-weight: 400; letter-spacing: normal; word-spacing: 0px; @@ -76,7 +76,7 @@ table { width: 100% !important; border-collapse: collapse; line-height: 1.35; - font-size: 0.85em; + font-size: 14px; } td { @@ -93,7 +93,7 @@ th { .code-highlight { text-align: left; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; - font-size: 0.85em; + font-size: 14px; margin: 0px; white-space: nowrap; } @@ -120,14 +120,14 @@ th { display: table; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1em; + font-size: 14px; font-weight: bold; margin: 3rem 0 0.6rem 0; padding-left: 0.2rem; } .footnotes-list { - font-size: 0.75em; + font-size: 10px; font-style: italic; line-height: 1.2; margin: 0.4rem 0; diff --git a/website/src/themes/default.md.css b/website/src/themes/default.md.css index cc48402..5cddccb 100644 --- a/website/src/themes/default.md.css +++ b/website/src/themes/default.md.css @@ -1,7 +1,7 @@ a { - color: #576b95; + color: #009874; text-decoration: none; - font-size: 0.85em; + font-size: 14px; } h1 { @@ -11,11 +11,11 @@ h1 { line-height: 1.75; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1em; + font-size: 16px; font-weight: bold; margin: 2em auto 1em; padding: 0 1em; - border-bottom: 2px solid #009874; + border-bottom: 3px solid #009874; margin-top: 0; } @@ -26,7 +26,7 @@ h2 { line-height: 1.75; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.3em; + font-size: 16px; font-weight: bold; margin: 4em auto 2em; padding: 0 0.3em; @@ -34,22 +34,17 @@ h2 { background: #009874; } -p { - font-size: 0.85em; - line-height: 1.5em; -} - h3 { text-align: left; color: #3f3f3f; line-height: 1.2; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.1em; + font-size: 14px; font-weight: bold; margin: 2em 8px 0.75em 0; padding-left: 8px; - border-left: 3px solid #009874; + border-left: 5px solid #009874; } ul { @@ -63,23 +58,29 @@ ol { li { margin: 0; line-height: 1.5em; - color: rgb(30 41 59); - font-size: 0.85em; + font-size: 14px; line-height: 1.5em; } +p { + font-size: 14px; + line-height: 1.5em; + padding: 0.5em 0 !important; + margin-bottom: 0 !important; + margin-top: 0 !important; +} + blockquote { text-align: left; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 0.85em; + font-size: 14px; font-style: normal; border-left: none; - padding: 0.1rem 1rem; + padding: 0.5em 1em; border-radius: 4px; background: rgba(27, 31, 35, 0.05); - margin: 1rem 0; - line-height: 1.5em; + margin: 1em 0; } pre { @@ -113,7 +114,7 @@ table { width: 100% !important; border-collapse: collapse; line-height: 1.35; - font-size: 0.85em; + font-size: 14px; } td { @@ -131,7 +132,7 @@ th { text-align: left; line-height: 1.75; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; - font-size: 0.85em; + font-size: 14px; margin: 0px; white-space: nowrap; } @@ -159,14 +160,14 @@ th { display: table; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1em; + font-size: 14px; font-weight: bold; margin: 3em 0 0.6em 0; padding-left: 0.2em; } .footnotes-list { - font-size: 0.75em; + font-size: 10px; font-style: italic; line-height: 1.2; margin: 0.4rem 0; diff --git a/website/src/themes/simple.md.css b/website/src/themes/simple.md.css index 8b0e76f..1f48fbb 100644 --- a/website/src/themes/simple.md.css +++ b/website/src/themes/simple.md.css @@ -1,7 +1,7 @@ a { - color: #576b95; + color: #0f4c81; text-decoration: none; - font-size: 0.85em; + font-size: 14px; } h1 { @@ -11,11 +11,11 @@ h1 { line-height: 1.75; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.2em; + font-size: 16px; font-weight: bold; margin: 2em auto 1em; padding: 0 1em; - border-bottom: 2px solid #0f4c81; + border-bottom: 3px solid #0f4c81; margin-top: 0; } @@ -26,7 +26,7 @@ h2 { line-height: 1.75; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.2em; + font-size: 16px; font-weight: bold; margin: 4em auto 2em; padding: 0 0.3em; @@ -34,22 +34,17 @@ h2 { background: #0f4c81; } -p { - font-size: 0.85em; - line-height: 1.5em; -} - h3 { text-align: left; color: #3f3f3f; line-height: 1.2; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.1em; + font-size: 14px; font-weight: bold; margin: 2em 8px 0.75em 0; padding-left: 8px; - border-left: 3px solid #0f4c81; + border-left: 5px solid #0f4c81; } ul { @@ -63,23 +58,29 @@ ol { li { margin: 0; line-height: 1.5em; - color: rgb(30 41 59); - font-size: 0.85em; + font-size: 14px; line-height: 1.5em; } +p { + font-size: 14px; + line-height: 1.5em; + padding: 0.5em 0 !important; + margin-bottom: 0 !important; + margin-top: 0 !important; +} + blockquote { text-align: left; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 0.85em; + font-size: 14px; font-style: normal; border-left: none; - padding: 0.1rem 1rem; + padding: 0.5em 1em; border-radius: 4px; background: rgba(27, 31, 35, 0.05); - margin: 1rem 0; - line-height: 1.5em; + margin: 1em 0; } pre { @@ -113,7 +114,7 @@ table { width: 100% !important; border-collapse: collapse; line-height: 1.35; - font-size: 0.85em; + font-size: 14px; } td { @@ -131,7 +132,7 @@ th { text-align: left; line-height: 1.75; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; - font-size: 0.85em; + font-size: 14px; margin: 0px; white-space: nowrap; } @@ -150,7 +151,7 @@ th { padding: 0.1em 0.3em; border-radius: 0.3em; font-weight: bold; - font-size: 1em; + font-size: 14px; top: -0.1em; position: relative; } @@ -159,14 +160,14 @@ th { display: table; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1em; + font-size: 14px; font-weight: bold; margin: 3em 0 0.6em 0; padding-left: 0.2em; } .footnotes-list { - font-size: 0.75em; + font-size: 10px; font-style: italic; line-height: 1.2; margin: 0.4rem 0; diff --git a/website/src/themes/underscore.md.css b/website/src/themes/underscore.md.css index 1b8a84d..e8c867a 100644 --- a/website/src/themes/underscore.md.css +++ b/website/src/themes/underscore.md.css @@ -1,7 +1,7 @@ a { - color: #576b95; + color: #ffb11b; text-decoration: none; - font-size: 0.85em; + font-size: 14px; } h1 { @@ -11,7 +11,7 @@ h1 { line-height: 1.15; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.3em; + font-size: 16px; font-weight: bold; margin: 2em auto 1em; padding: 0 1em 0.3em 1em; @@ -24,18 +24,13 @@ h2 { line-height: 1.35; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1.2em; + font-size: 16px; font-weight: bold; padding: 0 0.3em; margin: 2em 0 1em 0; box-shadow: inset 0 -0.7rem 0 0 #ffb11b; } -p { - font-size: 0.85em; - line-height: 1.5em; -} - h3 { text-align: left; color: #3f3f3f; @@ -60,8 +55,15 @@ ol { li { margin: 0; line-height: 1.5em; - color: rgb(30 41 59); - font-size: 0.85em; + font-size: 14px; +} + +p { + font-size: 14px; + line-height: 1.5em; + padding: 0.5em 0 !important; + margin-bottom: 0 !important; + margin-top: 0 !important; } blockquote { @@ -69,13 +71,13 @@ blockquote { line-height: 1.5em; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 0.85em; + font-size: 14px; font-style: normal; border-left: none; - padding: 0.1rem 1rem; + padding: 0.5em 1em; border-radius: 4px; background: rgba(27, 31, 35, 0.05); - margin: 1rem 0; + margin: 1em 0; } pre { @@ -109,7 +111,7 @@ table { width: 100% !important; border-collapse: collapse; line-height: 1.35; - font-size: 0.85em; + font-size: 14px; } td { @@ -127,7 +129,7 @@ th { text-align: left; line-height: 1.75; font-family: Menlo, 'Operator Mono', Consolas, Monaco, monospace; - font-size: 0.85em; + font-size: 14px; margin: 0px; white-space: nowrap; } @@ -146,7 +148,7 @@ th { padding: 0.1em 0.3em; border-radius: 0.3em; font-weight: bold; - font-size: 0.85em; + font-size: 14px; top: -0.1em; position: relative; } @@ -155,14 +157,14 @@ th { display: table; font-family: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif; - font-size: 1em; + font-size: 14px; font-weight: bold; margin: 3em 0 0.6em 0; padding-left: 0.2em; } .footnotes-list { - font-size: 0.75em; + font-size: 10px; font-style: italic; line-height: 1.2; margin: 0.4rem 0; diff --git a/website/src/utils/css.ts b/website/src/utils/css.ts index efcf0e8..53c7ae8 100644 --- a/website/src/utils/css.ts +++ b/website/src/utils/css.ts @@ -1,20 +1,55 @@ import { RootContent, Element, Text, Root } from 'hast'; +import { PreviewThemeValue, replaceData, ReplaceData } from '../store/context'; -export const getBlock = (data: any, str: string = '') => { +/** + * { + * "replace": [ + * { select: 'a', name: 'color', value: 'red' }, + * { select: 'h1', name: 'box-shadow', value: 'red' }, + * { select: 'h2', name: 'box-shadow', value: 'red' }, + * { select: 'h3', name: 'border-left', value: 'red' }, + * { select: 'h3', name: 'color', value: 'red' }, + * ] + * } + */ +type BlockOption = { + replace?: Array; +}; + +export const getBlock = (data: any, str: string = '', opts: BlockOption = {}) => { + const { replace } = opts; if (data && data.data && data.data.type === 'Declaration') { - str = `${data.data.property}: ${data.data.value.value}${data.data.important ? ' !important' : ''};`; + const value = replace?.find((m) => m.name === data.data.property)?.value || data.data.value.value; + // console.log(value) + str = `${data.data.property}: ${value}${data.data.important ? ' !important' : ''};`; if (data.next) { - str += getBlock(data.next); + str += getBlock(data.next, '', opts); } } return str; }; -export const cssdata = (list: any, result: Record = {}) => { +type Cssdata = { + theme?: PreviewThemeValue; + color?: string; +}; + +export const cssdata = (list: any, result: Record = {}, opts: Cssdata = {}) => { if (list.data && list.data.type === 'Rule') { - result[list.data.prelude.value] = getBlock(list.data.block.children.head); + const selector = list.data.prelude.value; + const options: BlockOption = {}; + // console.log('opts:', opts) + if (opts.color && opts.theme && replaceData[opts.theme]) { + options.replace = replaceData[opts.theme] + .filter((m) => m.select === selector) + .map((m) => ({ + ...m, + value: m.value.replace('{{color}}', opts.color!), + })); + } + result[selector] = getBlock(list.data.block.children.head, '', options); if (list.next) { - result = cssdata(list.next, { ...result }); + result = cssdata(list.next, { ...result }, opts); } } return result; @@ -29,7 +64,6 @@ export const spaceEscape = (node: RootContent) => { } node.properties.className = className.filter((str: string) => !/(token|control-flow)/.test(str)); } - node.children.map((elm) => { if (elm.type === 'element' && elm.children) { spaceEscape(elm); diff --git a/website/src/utils/markdownToHTML.ts b/website/src/utils/markdownToHTML.ts index 7c99ce1..429e787 100644 --- a/website/src/utils/markdownToHTML.ts +++ b/website/src/utils/markdownToHTML.ts @@ -13,9 +13,12 @@ import rehypeRewrite from 'rehype-rewrite'; import stringify from 'rehype-stringify'; import { cssdata, spaceEscape, footnotes, footnotesLabel, imagesStyle } from './css'; -export type MarkdownToHTMLOptions = {}; +export type MarkdownToHTMLOptions = { + preColor?: string; + previewTheme?: string; +}; -export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLOptions = {}) { +export function markdownToHTML(md: string, css: string, opts: MarkdownToHTMLOptions = {}) { const ast = csstree.parse(css, { parseAtrulePrelude: false, parseRulePrelude: false, @@ -24,7 +27,7 @@ export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLO positions: false, }); // @ts-ignore - const data = cssdata(ast.children.head); + const data = cssdata(ast.children.head, {}, { color: opts.preColor, theme: opts.previewTheme }); const processor = unified() .use(remarkParse) .use(remarkGfm) @@ -34,7 +37,7 @@ export function markdownToHTML(md: string, css: string, options: MarkdownToHTMLO .use(rehypeIgnore, {}) .use(rehypeAttrs, { properties: 'attr' }) .use(rehypeRewrite, { - rewrite: (node, index, parent) => { + rewrite: (node, _index, parent) => { // @ts-ignore if ( node?.type === 'element' &&