Skip to main content
Glama
useMonacoTheme.ts4.61 kB
import { loader } from '@monaco-editor/react'; import type * as Monaco from 'monaco-editor'; import { useCallback, useEffect, useRef, useState } from 'react'; let themeInitialized = false; let observerInitialized = false; const editorInstances = new Set<Monaco.editor.IStandaloneCodeEditor>(); function getCurrentTheme(): 'light' | 'dark' { if (typeof document === 'undefined') return 'dark'; return document.documentElement.classList.contains('dark') ? 'dark' : 'light'; } function defineThemes(monaco: typeof Monaco | any) { if (themeInitialized) return; monaco.editor.defineTheme('superglue-light', { base: 'vs', inherit: true, rules: [ { token: 'comment', foreground: '6A737D', fontStyle: 'italic' }, { token: 'keyword', foreground: 'C678DD' }, { token: 'string', foreground: '50A14F' }, { token: 'number', foreground: '0184BC' }, { token: 'regexp', foreground: 'E45649' }, { token: 'operator', foreground: '383A42' }, { token: 'delimiter', foreground: '383A42' }, { token: 'type', foreground: '0997B3' }, { token: 'function', foreground: '4078F2' }, { token: 'variable', foreground: 'E45649' }, { token: 'constant', foreground: '986801' }, ], colors: { 'editor.background': '#00000000', 'editor.foreground': '#383A42', 'editorLineNumber.foreground': '#9D9D9F', 'editorCursor.foreground': '#526FFF', 'editor.selectionBackground': '#E5E5E6', 'editor.inactiveSelectionBackground': '#EAEAEB', } }); monaco.editor.defineTheme('superglue-dark', { base: 'vs-dark', inherit: true, rules: [ { token: 'comment', foreground: '6A737D', fontStyle: 'italic' }, { token: 'keyword', foreground: 'C678DD' }, { token: 'string', foreground: '98C379' }, { token: 'number', foreground: '61AFEF' }, { token: 'regexp', foreground: 'E06C75' }, { token: 'operator', foreground: 'ABB2BF' }, { token: 'delimiter', foreground: 'ABB2BF' }, { token: 'type', foreground: '56B6C2' }, { token: 'function', foreground: '61AFEF' }, { token: 'variable', foreground: 'E06C75' }, { token: 'constant', foreground: 'D19A66' }, ], colors: { 'editor.background': '#00000000', 'editor.foreground': '#ABB2BF', 'editorLineNumber.foreground': '#5C6370', 'editorCursor.foreground': '#528BFF', 'editor.selectionBackground': '#3E4451', 'editor.inactiveSelectionBackground': '#2C313A', } }); themeInitialized = true; } function updateAllEditorsTheme(theme: 'light' | 'dark') { const themeName = theme === 'dark' ? 'superglue-dark' : 'superglue-light'; loader.init().then((monaco) => { defineThemes(monaco); monaco.editor.setTheme(themeName); editorInstances.forEach((editor) => { editor.updateOptions({ theme: themeName }); }); }); } function initThemeObserver() { if (observerInitialized || typeof window === 'undefined') return; observerInitialized = true; const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { updateAllEditorsTheme(getCurrentTheme()); break; } } }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'], }); } export function useMonacoTheme() { const [currentTheme, setCurrentTheme] = useState<'light' | 'dark'>(getCurrentTheme); const editorRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null); useEffect(() => { initThemeObserver(); let mounted = true; loader.init().then((monaco) => { defineThemes(monaco); const theme = getCurrentTheme(); if (mounted) setCurrentTheme(theme); monaco.editor.setTheme(theme === 'dark' ? 'superglue-dark' : 'superglue-light'); }); return () => { mounted = false; }; }, []); const handleEditorMount = useCallback((editor: Monaco.editor.IStandaloneCodeEditor) => { editorRef.current = editor; editorInstances.add(editor); loader.init().then((monaco) => { defineThemes(monaco); const theme = getCurrentTheme(); const themeName = theme === 'dark' ? 'superglue-dark' : 'superglue-light'; editor.updateOptions({ theme: themeName }); }); return () => { editorInstances.delete(editor); }; }, []); const themeName = currentTheme === 'dark' ? 'superglue-dark' : 'superglue-light'; return { theme: themeName, onMount: handleEditorMount, }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/superglue-ai/superglue'

If you have feedback or need assistance with the MCP directory API, please join our Discord server