- chore: 升级 @metona-team/metona-editor 0.1.3 → 0.1.10 - feat: 三主题系统(亮色/暗色/暖色),循环切换 - feat: 应用颜色自动同步编辑器主题(MeEditor.themes.exportCSSVars) - feat: 启用编辑器新功能(lineNumbers/autoBrackets/readOnly/autofocus/exportTool) - refactor: 主题从 boolean darkMode 重构为 ThemeMode 枚举 - refactor: 插件注册改用字符串数组(与 demo 一致) - refactor: 主题同步从手动 CSS 覆写改为 editor.setTheme() 实例 API - refactor: Ctrl+S 双通道(编辑器 onSave + 全局兜底)+ 防重入锁 - style: 移除 variables.css 中硬编码 .dark 色值,改为 JS 动态驱动 - test: 更新 editorStore 测试覆盖新的 themeMode/cycleTheme
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
import { create } from 'zustand'
|
|
import type { ViewMode, ThemeMode } from '../types/settings'
|
|
import type { MarkdownEditor } from '@metona-team/metona-editor'
|
|
|
|
// Module-level getter for the MetonaEditor instance
|
|
// Used by OutlinePanel for heading navigation
|
|
let _getEditor: (() => MarkdownEditor | null) | null = null
|
|
|
|
export function setMetonaEditorGetter(fn: () => MarkdownEditor | null) {
|
|
_getEditor = fn
|
|
}
|
|
|
|
export function getMetonaEditor(): MarkdownEditor | null {
|
|
return _getEditor ? _getEditor() : null
|
|
}
|
|
|
|
const THEME_CYCLE: ThemeMode[] = ['light', 'dark', 'warm']
|
|
|
|
interface EditorState {
|
|
viewMode: ViewMode
|
|
themeMode: ThemeMode
|
|
// AR-03: 外部修改检测状态,替代 DOM CustomEvent
|
|
externallyModified: { filePath: string } | null
|
|
// UX-02: 全局加载状态
|
|
loadingStates: Record<string, boolean>
|
|
|
|
setViewMode: (mode: ViewMode) => void
|
|
setThemeMode: (mode: ThemeMode) => void
|
|
cycleTheme: () => ThemeMode
|
|
setExternallyModified: (info: { filePath: string } | null) => void
|
|
// UX-02: 加载状态管理
|
|
setLoading: (key: string, loading: boolean) => void
|
|
isLoading: (key: string) => boolean
|
|
}
|
|
|
|
export const useEditorStore = create<EditorState>((set, get) => ({
|
|
viewMode: 'editor',
|
|
themeMode: 'light',
|
|
externallyModified: null,
|
|
loadingStates: {},
|
|
|
|
setViewMode: (mode: ViewMode) => set({ viewMode: mode }),
|
|
setThemeMode: (mode: ThemeMode) => set({ themeMode: mode }),
|
|
cycleTheme: () => {
|
|
const current = get().themeMode
|
|
const idx = THEME_CYCLE.indexOf(current)
|
|
const next = THEME_CYCLE[(idx + 1) % THEME_CYCLE.length]
|
|
set({ themeMode: next })
|
|
return next
|
|
},
|
|
setExternallyModified: (info: { filePath: string } | null) => set({ externallyModified: info }),
|
|
setLoading: (key: string, loading: boolean) => set(state => ({
|
|
loadingStates: { ...state.loadingStates, [key]: loading }
|
|
})),
|
|
isLoading: (key: string) => get().loadingStates[key] ?? false
|
|
}))
|