/** * MetonaEditor Constants - 常量定义 * @module constants * @version 0.1.6 * @description 默认配置、主题、动画、工具栏等常量 */ import { ICONS } from './icons.js'; import { LOCALES } from './locales.js'; /** * 默认工具栏按钮序列 * '|' 表示分组分隔符 */ export const DEFAULT_TOOLBAR = [ 'bold', 'italic', 'strikethrough', 'code', '|', 'h1', 'h2', 'h3', '|', 'quote', 'ul', 'ol', '|', 'link', 'image', 'table', 'hr', '|', 'undo', 'redo', '|', 'edit', 'split', 'preview', 'fullscreen', ]; /** * 默认配置 */ export const DEFAULTS = Object.freeze({ // 内容 value: '', placeholder: '', // 视图模式:edit / split / preview mode: 'split', // 高度:数字为 px,字符串原样使用 height: 400, // 工具栏:数组或 false(隐藏) toolbar: DEFAULT_TOOLBAR, // 字数统计状态栏 wordCount: true, // 自动聚焦 autofocus: false, // 拼写检查 spellcheck: false, // 历史栈上限 historyLimit: 100, // 历史栈防抖延迟(ms) historyDebounce: 400, // 同步滚动(分屏模式) syncScroll: true, // 制表符插入的空格数(0 表示插入 \t) tabSize: 2, // 只读模式 readOnly: false, // 主题:light / dark / auto / warm / 自定义 theme: 'auto', // 国际化 locale: 'zh-CN', // 自定义 Markdown 渲染函数 (md, env) => html,覆盖内置解析器 render: null, // 自定义代码高亮函数 (code, lang) => html highlight: null, // 自定义渲染前的 HTML 净化函数(接收渲染后的 HTML,返回安全 HTML) sanitize: null, // 外观 className: '', style: {}, // 插件 plugins: [], // 生命周期回调 onChange: null, onInput: null, onFocus: null, onBlur: null, onSave: null, onModeChange: null, onFullscreen: null, onCreate: null, onDestroy: null, }); // Icons - 从 icons.js 导入并重新导出(保持单一来源) export { ICONS }; /** * 类型颜色配置(保留用于状态提示与按钮强调) */ export const TYPE_COLORS = { success: { fg: '#10b981', bg: 'rgba(16, 185, 129, 0.1)' }, error: { fg: '#ef4444', bg: 'rgba(239, 68, 68, 0.1)' }, warning: { fg: '#f59e0b', bg: 'rgba(245, 158, 11, 0.1)' }, info: { fg: '#3b82f6', bg: 'rgba(59, 130, 246, 0.1)' }, loading: { fg: '#6366f1', bg: 'rgba(99, 102, 241, 0.1)' }, default: { fg: '#6b7280', bg: 'rgba(107, 114, 128, 0.1)' }, }; /** * 主题配置 */ export const THEMES = { light: { bg: 'rgba(255, 255, 255, 0.96)', text: '#1f2937', border: 'rgba(0, 0, 0, 0.08)', shadow: '0 10px 36px -10px rgba(0, 0, 0, 0.18), 0 4px 14px -4px rgba(0, 0, 0, 0.08)', hoverShadow: '0 14px 48px -10px rgba(0, 0, 0, 0.22), 0 6px 18px -4px rgba(0, 0, 0, 0.10)', // 编辑器专属 toolbarBg: 'rgba(248, 249, 250, 0.92)', textareaBg: '#ffffff', previewBg: '#ffffff', codeBg: 'rgba(243, 244, 246, 1)', codeText: '#1f2937', accent: '#3b82f6', muted: '#6b7280', }, dark: { bg: 'rgba(28, 32, 40, 0.94)', text: '#e6e8eb', border: 'rgba(255, 255, 255, 0.1)', shadow: '0 10px 36px -10px rgba(0, 0, 0, 0.6), 0 4px 14px -4px rgba(0, 0, 0, 0.4)', hoverShadow: '0 14px 48px -8px rgba(0, 0, 0, 0.6), 0 6px 18px -4px rgba(0, 0, 0, 0.4)', toolbarBg: 'rgba(22, 26, 33, 0.92)', textareaBg: '#1c2028', previewBg: '#1c2028', codeBg: 'rgba(15, 18, 24, 1)', codeText: '#e6e8eb', accent: '#60a5fa', muted: '#9ca3af', }, auto: 'auto', warm: { bg: 'rgba(255, 251, 235, 0.96)', text: '#78350f', border: 'rgba(245, 158, 11, 0.2)', shadow: '0 10px 36px -10px rgba(245, 158, 11, 0.18), 0 4px 14px -4px rgba(245, 158, 11, 0.08)', hoverShadow: '0 14px 48px -10px rgba(245, 158, 11, 0.22), 0 6px 18px -4px rgba(245, 158, 11, 0.10)', toolbarBg: 'rgba(254, 243, 199, 0.92)', textareaBg: '#fffbeb', previewBg: '#fffbeb', codeBg: 'rgba(254, 215, 170, 0.6)', codeText: '#78350f', accent: '#d97706', muted: '#a16207', }, }; /** * 位置配置(保留,预览面板提示等场景可用) */ export const POSITIONS = [ 'top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right', ]; /** * 动画配置(保留,DOM 过渡与未来扩展使用) */ export const ANIMATIONS = { slide: { enter: { transform: 'translateX(80px)', opacity: 0 }, leave: { transform: 'translateX(120%)', opacity: 0 }, duration: 400, easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' }, fade: { enter: { opacity: 0, filter: 'blur(3px)' }, leave: { opacity: 0, filter: 'blur(3px)' }, duration: 500, easing: 'ease' }, scale: { enter: { transform: 'scale(0.55)', opacity: 0 }, leave: { transform: 'scale(0.55)', opacity: 0 }, duration: 450, easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)' }, bounce: { enter: { transform: 'translateY(-80px)', opacity: 0 }, leave: { transform: 'translateY(20px)', opacity: 0 }, duration: 650, easing: 'ease' }, flip: { enter: { transform: 'perspective(500px) rotateX(-90deg)', opacity: 0 }, leave: { transform: 'perspective(500px) rotateX(90deg)', opacity: 0 }, duration: 500, easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' }, rotate: { enter: { transform: 'rotate(-25deg) scale(0.6)', opacity: 0 }, leave: { transform: 'rotate(25deg) scale(0.6)', opacity: 0 }, duration: 500, easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)' }, zoom: { enter: { transform: 'scale(0.1)', opacity: 0 }, leave: { transform: 'scale(0.1)', opacity: 0 }, duration: 500, easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)' }, }; /** * 主题类型 */ export const THEME_TYPES = ['light', 'dark', 'auto']; /** * 动画类型 */ export const ANIMATION_TYPES = ['slide', 'fade', 'scale', 'bounce', 'flip', 'rotate', 'zoom']; /** * 编辑器视图模式 */ export const EDIT_MODES = ['edit', 'split', 'preview']; /** * 内置工具栏动作清单 */ export const TOOLBAR_ACTIONS = [ 'bold', 'italic', 'strikethrough', 'underline', 'code', 'h1', 'h2', 'h3', 'quote', 'ul', 'ol', 'indent', 'outdent', 'hr', 'link', 'image', 'table', 'undo', 'redo', 'edit', 'split', 'preview', 'fullscreen', ]; // Locales - 从 locales.js 导入并重新导出 export { LOCALES }; /** * 进度条方向(保留兼容) */ export const PROGRESS_DIRECTIONS = ['horizontal', 'vertical'];