Skip to content

Commit

Permalink
feat: supports multiple sets of custom styles
Browse files Browse the repository at this point in the history
  • Loading branch information
YangFong committed Aug 18, 2024
1 parent 79b7421 commit 13fbc9c
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 6 deletions.
55 changes: 54 additions & 1 deletion src/components/CodemirrorEditor/CssEditor.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,61 @@
<script setup>
import { ElMessage, ElMessageBox } from 'element-plus'
import { useStore } from '@/stores'
const store = useStore()
function handleTabsEdit(targetName, action) {
if (action === `add`) {
ElMessageBox.prompt(`请输入方案名称`, `新建自定义 CSS`, {
confirmButtonText: `确认`,
cancelButtonText: `取消`,
inputErrorMessage: `不能与现有方案重名`,
inputValidator: store.validatorTabName,
})
.then(({ value }) => {
store.addCssContentTab(value)
ElMessage.success(`新建成功~`)
})
}
else if (action === `remove`) {
const tabs = store.cssContentConfig.tabs
let activeName = store.cssContentConfig.active
if (activeName === targetName) {
tabs.forEach((tab, index) => {
if (tab.name === targetName) {
const nextTab = tabs[index + 1] || tabs[index - 1]
if (nextTab) {
activeName = nextTab.name
}
}
})
}
store.cssContentConfig.active = activeName
store.cssContentConfig.tabs = tabs.filter(tab => tab.name !== targetName)
}
}
</script>

<template>
<transition enter-active-class="bounceInRight">
<el-col v-show="store.isShowCssEditor" :span="8" class="cssEditor-wrapper h-full">
<el-col v-show="store.isShowCssEditor" :span="8" class="cssEditor-wrapper h-full flex flex-col">
<el-tabs
v-model="store.cssContentConfig.active"
type="card"
editable
class="demo-tabs"
@edit="handleTabsEdit"
@tab-change="store.tabChanged"
>
<el-tab-pane
v-for="item in store.cssContentConfig.tabs"
:key="item.name"
:label="item.title"
:name="item.name"
/>
</el-tabs>
<textarea
id="cssEditor"
type="textarea"
Expand Down Expand Up @@ -54,4 +103,8 @@ const store = useStore()
transform: none;
}
}
:deep(.el-tabs__header) {
margin: 0;
}
</style>
65 changes: 60 additions & 5 deletions src/stores/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import CodeMirror from 'codemirror'
import { useDark, useStorage, useToggle } from '@vueuse/core'
import { ElMessage, ElMessageBox } from 'element-plus'

import { codeBlockThemeOptions, colorOptions, fontFamilyOptions, fontSizeOptions, githubConfig, legendOptions } from '@/config'
import { codeBlockThemeOptions, colorOptions, fontFamilyOptions, fontSizeOptions, legendOptions } from '@/config'
import WxRenderer from '@/utils/wx-renderer'
import DEFAULT_CONTENT from '@/assets/example/markdown.md?raw'
import DEFAULT_CSS_CONTENT from '@/assets/example/theme-css.txt?raw'
import { css2json, customCssWithTemplate, downloadMD, exportHTML, formatCss, formatDoc, setColor, setColorWithCustomTemplate, setFontSize } from '@/utils'
import { addPrefix, css2json, customCssWithTemplate, downloadMD, exportHTML, formatCss, formatDoc, setColor, setColorWithCustomTemplate, setFontSize } from '@/utils'

const defaultKeyMap = CodeMirror.keyMap.default
const modPrefix
Expand Down Expand Up @@ -132,8 +132,45 @@ export const useStore = defineStore(`store`, () => {

// 自义定 CSS 编辑器
const cssEditor = ref(null)
const setCssEditorValue = (content) => {
cssEditor.value.setValue(content)
}
// 自定义 CSS 内容
const cssContent = useStorage(`__css_content`, DEFAULT_CSS_CONTENT)
const cssContentConfig = useStorage(addPrefix(`css_content_config`), {
active: `方案 1`,
tabs: [
{
title: `方案 1`,
name: `方案 1`,
// 兼容之前的方案
content: cssContent.value || DEFAULT_CSS_CONTENT,
},
],
})
const getCurrentTab = () => cssContentConfig.value.tabs.find((tab) => {
return tab.name === cssContentConfig.value.active
})
const tabChanged = (name) => {
cssContentConfig.value.active = name
const content = cssContentConfig.value.tabs.find((tab) => {
return tab.name === name
}).content
setCssEditorValue(content)
}

const addCssContentTab = (name) => {
cssContentConfig.value.tabs.push({
name,
title: name,
content: DEFAULT_CSS_CONTENT,
})
cssContentConfig.value.active = name
setCssEditorValue(DEFAULT_CSS_CONTENT)
}
const validatorTabName = (val) => {
return cssContentConfig.value.tabs.every(({ name }) => name !== val)
}
// 更新 CSS
const updateCss = () => {
const json = css2json(cssEditor.value.getValue())
Expand All @@ -148,7 +185,7 @@ export const useStore = defineStore(`store`, () => {
// 初始化 CSS 编辑器
onMounted(() => {
const cssEditorDom = document.querySelector(`#cssEditor`)
cssEditorDom.value = cssContent.value
cssEditorDom.value = getCurrentTab().content

cssEditor.value = markRaw(
CodeMirror.fromTextArea(cssEditorDom, {
Expand All @@ -161,7 +198,7 @@ export const useStore = defineStore(`store`, () => {
extraKeys: {
[`${modPrefix}-F`]: function autoFormat(editor) {
const doc = formatCss(editor.getValue())
cssContent.value = doc
getCurrentTab().content = doc
editor.setValue(doc)
},
},
Expand All @@ -178,7 +215,7 @@ export const useStore = defineStore(`store`, () => {
// 实时保存
cssEditor.value.on(`update`, () => {
updateCss()
cssContent.value = cssEditor.value.getValue()
getCurrentTab().content = cssEditor.value.getValue()
})
})

Expand All @@ -193,6 +230,18 @@ export const useStore = defineStore(`store`, () => {
codeBlockTheme.value = codeBlockThemeOptions[2].value
legend.value = legendOptions[3].value

cssContentConfig.value = {
active: `方案 1`,
tabs: [
{
title: `方案 1`,
name: `方案 1`,
// 兼容之前的方案
content: cssContent.value || DEFAULT_CSS_CONTENT,
},
],
}

cssEditor.value.setValue(DEFAULT_CSS_CONTENT)

updateCss()
Expand Down Expand Up @@ -367,6 +416,12 @@ export const useStore = defineStore(`store`, () => {

resetStyleConfirm,
editorContent,

cssContentConfig,
addCssContentTab,
validatorTabName,
setCssEditorValue,
tabChanged,
}
})

Expand Down

0 comments on commit 13fbc9c

Please sign in to comment.