ThemeConfigModal — configuración visual del tema Markdown del Cuaderno
ThemeConfigModal
Componente React modal que permite al usuario configurar los colores con los que el editor Tiptap pinta los elementos de Markdown en el Cuaderno de Workspace. Es una preferencia exclusivamente visual del navegador — no modifica el contenido de las notas ni los archivos exportados.
Introducido en commit e230534 (2026-05-08).
Ubicación
src/components/notebook/ThemeConfigModal.tsx
Exports públicos
| Símbolo | Tipo | Descripción |
|---|---|---|
ThemeConfigModal | default (componente React) | Modal de configuración |
ThemeConfig | interface | Tipo con los 9 colores configurables |
DEFAULT_THEME | const ThemeConfig | Valores por defecto |
loadTheme() | function | Lee tema desde localStorage |
saveTheme(theme) | function | Persiste en localStorage |
applyTheme(theme) | function | Aplica al :root via CSS vars |
Interface ThemeConfig
export interface ThemeConfig {
h1: string; // color hex Heading 1
h2: string; // color hex Heading 2
h3: string; // color hex Heading 3
code: string; // código inline
codeBlock: string; // bloque de código
link: string; // enlaces
blockquote: string;// cita
marker: string; // marcadores de lista
strong: string; // negrita
}
CSS variables generadas
applyTheme() escribe en document.documentElement.style:
| CSS var | Campo |
|---|---|
--cuaderno-color-h1 | h1 |
--cuaderno-color-h2 | h2 |
--cuaderno-color-h3 | h3 |
--cuaderno-color-code | code |
--cuaderno-color-code-block | codeBlock |
--cuaderno-color-link | link |
--cuaderno-color-blockquote | blockquote |
--cuaderno-color-marker | marker |
--cuaderno-color-strong | strong |
Persistencia
- Clave localStorage:
workspace.notebook.theme - Formato: JSON con el objeto
ThemeConfig - Merge con defaults:
loadTheme()hace{ ...DEFAULT_THEME, ...JSON.parse(raw) }, por lo que añadir campos nuevos al tipo en el futuro no rompe configuraciones guardadas. - SSR-safe: todas las funciones comprueban
typeof window === 'undefined'antes de acceder alocalStorageodocument.
Props del componente
interface Props {
onClose: () => void;
onApply: (theme: ThemeConfig) => void;
current: ThemeConfig;
}
| Prop | Descripción |
|---|---|
current | Tema activo al abrir el modal (para restaurar si se cancela) |
onApply | Callback que recibe el nuevo tema tras «Aplicar y guardar» |
onClose | Callback de cierre (Escape, Cancelar, fondo) |
Ciclo de vida del modal
- Abre → recibe
currentcomo estado inicial. - Cada cambio de color →
applyTheme()(preview en vivo, sin guardar). - «Restaurar defaults» → resetea estado local a
DEFAULT_THEME(sin cerrar). - «Cancelar» / Escape / fondo →
applyTheme(current)(restaura) y cierra sin persistir. - «Aplicar y guardar» →
saveTheme()+onApply()+ cierra.
Integración en NotebookPage
// Estado
const [theming, setTheming] = useState(false);
const [theme, setTheme] = useState<ThemeConfig>(() => loadTheme());
// Aplicar al montar
useEffect(() => { applyTheme(theme); }, [theme]);
// Render
{theming && (
<ThemeConfigModal
current={theme}
onApply={(t) => setTheme(t)}
onClose={() => setTheming(false)}
/>
)}
El botón «Tema MD» se renderiza en Toolbar.tsx y dispara onOpenTheme(), prop nueva de NoteEditor.
Valores por defecto (DEFAULT_THEME)
export const DEFAULT_THEME: ThemeConfig = {
h1: '#ffffff',
h2: '#e5e7eb',
h3: '#d1d5db',
code: '#f59e0b',
codeBlock: '#10b981',
link: '#3b82f6',
blockquote: '#9ca3af',
marker: '#6b7280',
strong: '#ffffff',
};
Paleta oscura por defecto (el Workspace usa tema dark).
Véase también
- [[feature—workspace—cuaderno-mejoras-mayo-2026]]
- [[workspace—que-es-workspace]]