From 5a388e7f14fbe5540e940f04efe96ab4f942162e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Forment?= Date: Fri, 14 Nov 2025 13:42:18 +0100 Subject: [PATCH] theme awareness --- src/App.svelte | 2 +- src/lib/components/audio/AudioScope.svelte | 19 ++-- src/lib/components/audio/Spectrogram.svelte | 51 ++++++++-- src/lib/components/editor/Editor.svelte | 18 ++-- src/lib/components/editor/LogPanel.svelte | 26 ++--- .../reference/CsoundReference.svelte | 6 +- .../settings/CsoundVersionToggle.svelte | 2 +- src/lib/components/ui/ConfirmDialog.svelte | 4 +- src/lib/components/ui/FileBrowser.svelte | 4 +- src/lib/components/ui/InputDialog.svelte | 4 +- src/lib/components/ui/Modal.svelte | 2 +- src/lib/components/ui/ResizablePopup.svelte | 2 +- src/lib/editor/codemirror-theme.ts | 96 +++++++------------ src/lib/themes/apply-theme.ts | 13 +++ src/lib/themes/definitions/ayumirage.ts | 13 +++ src/lib/themes/definitions/blue.ts | 13 +++ src/lib/themes/definitions/bluescreen.ts | 13 +++ src/lib/themes/definitions/catppuccin.ts | 13 +++ src/lib/themes/definitions/darcula.ts | 13 +++ src/lib/themes/definitions/dracula.ts | 13 +++ src/lib/themes/definitions/georges.ts | 13 +++ src/lib/themes/definitions/gruvbox.ts | 13 +++ src/lib/themes/definitions/hacker.ts | 13 +++ src/lib/themes/definitions/light.ts | 13 +++ src/lib/themes/definitions/materialdarker.ts | 13 +++ src/lib/themes/definitions/monodark.ts | 13 +++ src/lib/themes/definitions/monokai.ts | 13 +++ src/lib/themes/definitions/monolight.ts | 13 +++ src/lib/themes/definitions/nightowl.ts | 13 +++ src/lib/themes/definitions/nord.ts | 13 +++ src/lib/themes/definitions/onedarkpro.ts | 13 +++ src/lib/themes/definitions/solarizeddark.ts | 13 +++ src/lib/themes/definitions/solarizedlight.ts | 13 +++ src/lib/themes/definitions/tokyonight.ts | 13 +++ src/lib/themes/index.ts | 1 + src/lib/themes/types.ts | 13 +++ src/lib/themes/utils.ts | 30 ++++++ 37 files changed, 444 insertions(+), 109 deletions(-) create mode 100644 src/lib/themes/utils.ts diff --git a/src/App.svelte b/src/App.svelte index 1b850ee..b394917 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -603,7 +603,7 @@ margin-top: var(--space-lg); padding: var(--space-md) var(--space-2xl); background-color: var(--accent-color); - color: white; + color: var(--accent-text); border: none; font-size: var(--font-lg); font-weight: 600; diff --git a/src/lib/components/audio/AudioScope.svelte b/src/lib/components/audio/AudioScope.svelte index 12cce86..7fe726a 100644 --- a/src/lib/components/audio/AudioScope.svelte +++ b/src/lib/components/audio/AudioScope.svelte @@ -46,10 +46,15 @@ node.getByteTimeDomainData(dataArray); - canvasContext.fillStyle = '#0a0a0a'; + const computedStyle = getComputedStyle(document.documentElement); + const bgColor = computedStyle.getPropertyValue('--editor-background').trim(); + const borderColor = computedStyle.getPropertyValue('--border-color').trim(); + const accentColor = computedStyle.getPropertyValue('--accent-color').trim(); + + canvasContext.fillStyle = bgColor; canvasContext.fillRect(0, 0, canvas.width, canvas.height); - canvasContext.strokeStyle = '#333'; + canvasContext.strokeStyle = borderColor; canvasContext.lineWidth = 1; canvasContext.beginPath(); canvasContext.moveTo(0, canvas.height / 2); @@ -57,7 +62,7 @@ canvasContext.stroke(); canvasContext.lineWidth = 2; - canvasContext.strokeStyle = '#646cff'; + canvasContext.strokeStyle = accentColor; canvasContext.beginPath(); const sliceWidth = canvas.width / dataArray.length; @@ -94,7 +99,9 @@ if (canvas) { canvasContext = canvas.getContext('2d'); if (canvasContext) { - canvasContext.fillStyle = '#0a0a0a'; + const computedStyle = getComputedStyle(document.documentElement); + const bgColor = computedStyle.getPropertyValue('--editor-background').trim(); + canvasContext.fillStyle = bgColor; canvasContext.fillRect(0, 0, canvas.width, canvas.height); } } @@ -132,7 +139,7 @@ display: flex; align-items: center; justify-content: center; - background-color: #0a0a0a; + background-color: var(--editor-background); overflow: hidden; } @@ -140,6 +147,6 @@ display: block; width: 100%; height: 100%; - background-color: #0a0a0a; + background-color: var(--editor-background); } diff --git a/src/lib/components/audio/Spectrogram.svelte b/src/lib/components/audio/Spectrogram.svelte index ccfe81e..2ad4542 100644 --- a/src/lib/components/audio/Spectrogram.svelte +++ b/src/lib/components/audio/Spectrogram.svelte @@ -46,6 +46,10 @@ node.getByteFrequencyData(dataArray); + const computedStyle = getComputedStyle(document.documentElement); + const bgColor = computedStyle.getPropertyValue('--editor-background').trim(); + const accentColor = computedStyle.getPropertyValue('--accent-color').trim(); + const imageData = canvasContext.getImageData(1, 0, canvas.width - 1, canvas.height); canvasContext.putImageData(imageData, 0, 0); @@ -58,11 +62,7 @@ const y = canvas.height - (i / dataArray.length) * canvas.height; const height = (canvas.height / dataArray.length); - const hue = (1 - percent) * 240; - const saturation = 100; - const lightness = percent * 50; - - canvasContext.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`; + canvasContext.fillStyle = interpolateColor(bgColor, accentColor, percent); canvasContext.fillRect(x, y - height, barWidth, height); } }; @@ -70,6 +70,39 @@ draw(); } + function interpolateColor(color1: string, color2: string, percent: number): string { + const c1 = parseColor(color1); + const c2 = parseColor(color2); + + const r = Math.round(c1.r + (c2.r - c1.r) * percent); + const g = Math.round(c1.g + (c2.g - c1.g) * percent); + const b = Math.round(c1.b + (c2.b - c1.b) * percent); + + return `rgb(${r}, ${g}, ${b})`; + } + + function parseColor(color: string): { r: number; g: number; b: number } { + if (color.startsWith('#')) { + const hex = color.slice(1); + return { + r: parseInt(hex.slice(0, 2), 16), + g: parseInt(hex.slice(2, 4), 16), + b: parseInt(hex.slice(4, 6), 16) + }; + } + + const match = color.match(/\d+/g); + if (match && match.length >= 3) { + return { + r: parseInt(match[0]), + g: parseInt(match[1]), + b: parseInt(match[2]) + }; + } + + return { r: 0, g: 0, b: 0 }; + } + function updateSize() { if (container && canvas) { const rect = container.getBoundingClientRect(); @@ -82,7 +115,9 @@ if (canvas) { canvasContext = canvas.getContext('2d'); if (canvasContext) { - canvasContext.fillStyle = '#000'; + const computedStyle = getComputedStyle(document.documentElement); + const bgColor = computedStyle.getPropertyValue('--editor-background').trim(); + canvasContext.fillStyle = bgColor; canvasContext.fillRect(0, 0, canvas.width, canvas.height); } } @@ -120,7 +155,7 @@ display: flex; align-items: center; justify-content: center; - background-color: #0a0a0a; + background-color: var(--editor-background); overflow: hidden; } @@ -128,6 +163,6 @@ display: block; width: 100%; height: 100%; - background-color: #0a0a0a; + background-color: var(--editor-background); } diff --git a/src/lib/components/editor/Editor.svelte b/src/lib/components/editor/Editor.svelte index 6ea0783..fd5da88 100644 --- a/src/lib/components/editor/Editor.svelte +++ b/src/lib/components/editor/Editor.svelte @@ -20,6 +20,7 @@ } from '../../editor/block-eval'; import { csoundTooltip, csoundTooltipTheme } from '../../csound-reference/csoundTooltips'; import { createCodeMirrorTheme } from '../../editor/codemirror-theme'; + import { themes } from '../../themes'; interface Props { value: string; @@ -148,13 +149,14 @@ ]; const initSettings = $editorSettings; + const currentTheme = themes[initSettings.theme]; editorView = new EditorView({ doc: value, extensions: [ ...baseExtensions, languageCompartment.of(csoundMode({ fileType })), - themeCompartment.of(createCodeMirrorTheme()), + themeCompartment.of(createCodeMirrorTheme(currentTheme)), evaluateBlockKeymap, evaluateSelectionKeymap, evaluateFileKeymap, @@ -197,16 +199,12 @@ }); $effect(() => { - const theme = $editorSettings.theme; - if (!editorView) return; + const themeName = $editorSettings.theme; + const theme = themes[themeName]; + if (!editorView || !theme) return; - // Wait for CSS variables to be recomputed after theme change - requestAnimationFrame(() => { - if (editorView) { - editorView.dispatch({ - effects: themeCompartment.reconfigure(createCodeMirrorTheme()) - }); - } + editorView.dispatch({ + effects: themeCompartment.reconfigure(createCodeMirrorTheme(theme)) }); }); diff --git a/src/lib/components/editor/LogPanel.svelte b/src/lib/components/editor/LogPanel.svelte index 42d3a06..9f19040 100644 --- a/src/lib/components/editor/LogPanel.svelte +++ b/src/lib/components/editor/LogPanel.svelte @@ -276,23 +276,25 @@ } .action-button.pause-active { - color: rgba(255, 200, 100, 0.9); - background-color: rgba(255, 200, 100, 0.15); + color: var(--warning-text); + background-color: var(--warning-color); + opacity: 0.9; } .action-button.pause-active:hover { - color: rgba(255, 200, 100, 1); - background-color: rgba(255, 200, 100, 0.25); + background-color: var(--warning-hover); + opacity: 1; } .action-button.search-active { - color: rgba(100, 200, 255, 0.9); - background-color: rgba(100, 200, 255, 0.15); + color: var(--info-text); + background-color: var(--info-color); + opacity: 0.9; } .action-button.search-active:hover { - color: rgba(100, 200, 255, 1); - background-color: rgba(100, 200, 255, 0.25); + background-color: var(--info-hover); + opacity: 1; } .log-content { @@ -322,12 +324,14 @@ } .log-entry.error { - background-color: rgba(255, 0, 0, 0.1); - border-left: 3px solid rgba(255, 0, 0, 0.6); + background-color: var(--danger-color); + opacity: 0.2; + border-left: 3px solid var(--danger-color); } .log-entry.error .log-message { - color: rgba(255, 100, 100, 0.95); + color: var(--danger-color); + opacity: 1; } .log-timestamp { diff --git a/src/lib/components/reference/CsoundReference.svelte b/src/lib/components/reference/CsoundReference.svelte index 96554d9..1da241c 100644 --- a/src/lib/components/reference/CsoundReference.svelte +++ b/src/lib/components/reference/CsoundReference.svelte @@ -241,7 +241,7 @@ gap: var(--space-sm); width: 100%; padding: var(--space-md) var(--space-lg); - background-color: var(--accordion-header-bg); + background-color: var(--surface-color); border: none; color: var(--text-color); cursor: pointer; @@ -250,7 +250,7 @@ } .category-header:hover { - background-color: var(--accordion-header-hover); + background-color: var(--surface-hover); } .category-header :global(svg) { @@ -267,7 +267,7 @@ .category-count { font-size: var(--font-xs); color: var(--text-color); - background-color: var(--accent-color-subtle); + background-color: var(--surface-hover); padding: 2px var(--space-sm); border-radius: var(--radius-sm); } diff --git a/src/lib/components/settings/CsoundVersionToggle.svelte b/src/lib/components/settings/CsoundVersionToggle.svelte index 0a1f2c0..7b07ab6 100644 --- a/src/lib/components/settings/CsoundVersionToggle.svelte +++ b/src/lib/components/settings/CsoundVersionToggle.svelte @@ -71,7 +71,7 @@ .version-toggle-button.active { color: var(--accent-color); - background-color: rgba(100, 200, 255, 0.15); + background-color: var(--surface-hover); border-color: var(--accent-color); } diff --git a/src/lib/components/ui/ConfirmDialog.svelte b/src/lib/components/ui/ConfirmDialog.svelte index dcf4cdc..66d9603 100644 --- a/src/lib/components/ui/ConfirmDialog.svelte +++ b/src/lib/components/ui/ConfirmDialog.svelte @@ -69,11 +69,11 @@ .button-primary { background-color: var(--accent-color); - color: white; + color: var(--accent-text); } .button-primary:hover { - background-color: var(--accent-color-active); + background-color: var(--accent-hover); } .button-secondary { diff --git a/src/lib/components/ui/FileBrowser.svelte b/src/lib/components/ui/FileBrowser.svelte index 2220dcf..163b4ed 100644 --- a/src/lib/components/ui/FileBrowser.svelte +++ b/src/lib/components/ui/FileBrowser.svelte @@ -206,7 +206,7 @@ .new-file-button { padding: var(--space-sm); background-color: var(--accent-color); - color: white; + color: var(--accent-text); border: none; cursor: pointer; display: flex; @@ -336,7 +336,7 @@ .icon-btn.save { background-color: var(--accent-color); - color: white; + color: var(--accent-text); } .icon-btn.save:hover { diff --git a/src/lib/components/ui/InputDialog.svelte b/src/lib/components/ui/InputDialog.svelte index e39b60c..13097c2 100644 --- a/src/lib/components/ui/InputDialog.svelte +++ b/src/lib/components/ui/InputDialog.svelte @@ -101,11 +101,11 @@ .button-primary { background-color: var(--accent-color); - color: white; + color: var(--accent-text); } .button-primary:hover { - background-color: var(--accent-color-active); + background-color: var(--accent-hover); } .button-secondary { diff --git a/src/lib/components/ui/Modal.svelte b/src/lib/components/ui/Modal.svelte index e12c72c..ce2d768 100644 --- a/src/lib/components/ui/Modal.svelte +++ b/src/lib/components/ui/Modal.svelte @@ -44,7 +44,7 @@ left: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.7); + background-color: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; diff --git a/src/lib/components/ui/ResizablePopup.svelte b/src/lib/components/ui/ResizablePopup.svelte index 6de4ff5..148890a 100644 --- a/src/lib/components/ui/ResizablePopup.svelte +++ b/src/lib/components/ui/ResizablePopup.svelte @@ -150,7 +150,7 @@ z-index: 9999; background-color: var(--bg-color); border: 1px solid var(--border-color); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; } diff --git a/src/lib/editor/codemirror-theme.ts b/src/lib/editor/codemirror-theme.ts index 2edfb21..e7b09c3 100644 --- a/src/lib/editor/codemirror-theme.ts +++ b/src/lib/editor/codemirror-theme.ts @@ -1,110 +1,84 @@ import { EditorView } from '@codemirror/view'; import type { Extension } from '@codemirror/state'; -import { HighlightStyle, syntaxHighlighting } from '@codemirror/language'; -import { tags as t } from '@lezer/highlight'; +import { syntaxHighlighting } from '@codemirror/language'; +import type { Theme } from '../themes/types'; +import { createHighlightStyle } from '../themes/utils'; -function getCSSVariable(name: string): string { - if (typeof window === 'undefined') return ''; - return getComputedStyle(document.documentElement).getPropertyValue(name).trim(); -} - -export function createCodeMirrorTheme(): Extension { +export function createCodeMirrorTheme(theme: Theme): Extension { const editorTheme = EditorView.theme({ '&': { - backgroundColor: getCSSVariable('--editor-background'), - color: getCSSVariable('--editor-foreground'), + backgroundColor: theme.editor.background, + color: theme.editor.foreground, }, '.cm-content': { - caretColor: getCSSVariable('--editor-caret'), + caretColor: theme.editor.caret, }, '.cm-cursor, .cm-dropCursor': { - borderLeftColor: getCSSVariable('--editor-caret'), + borderLeftColor: theme.editor.caret, }, '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': { - backgroundColor: getCSSVariable('--editor-selection'), + backgroundColor: theme.editor.selection, }, '.cm-panels': { - backgroundColor: getCSSVariable('--surface-color'), - color: getCSSVariable('--text-color'), + backgroundColor: theme.colors.surface, + color: theme.colors.text, }, '.cm-panels.cm-panels-top': { - borderBottom: `1px solid ${getCSSVariable('--border-color')}`, + borderBottom: `1px solid ${theme.colors.border}`, }, '.cm-panels.cm-panels-bottom': { - borderTop: `1px solid ${getCSSVariable('--border-color')}`, + borderTop: `1px solid ${theme.colors.border}`, }, '.cm-searchMatch': { - backgroundColor: getCSSVariable('--syntax-number'), - outline: `1px solid ${getCSSVariable('--accent-color')}`, + backgroundColor: theme.syntax.number, + outline: `1px solid ${theme.colors.accent}`, }, '.cm-searchMatch.cm-searchMatch-selected': { - backgroundColor: getCSSVariable('--accent-color'), + backgroundColor: theme.colors.accent, }, '.cm-activeLine': { - backgroundColor: getCSSVariable('--editor-active-line'), + backgroundColor: theme.editor.activeLine, }, '.cm-selectionMatch': { - backgroundColor: getCSSVariable('--editor-selection'), + backgroundColor: theme.editor.selection, }, '&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': { - backgroundColor: getCSSVariable('--editor-selection'), + backgroundColor: theme.editor.selection, }, '.cm-gutters': { - backgroundColor: getCSSVariable('--editor-gutter'), - color: getCSSVariable('--editor-gutter-text'), + backgroundColor: theme.editor.gutter, + color: theme.editor.gutterText, border: 'none', - borderRight: `1px solid ${getCSSVariable('--border-color')}`, + borderRight: `1px solid ${theme.colors.border}`, }, '.cm-activeLineGutter': { - backgroundColor: getCSSVariable('--editor-active-line-gutter'), - color: getCSSVariable('--editor-line-number'), + backgroundColor: theme.editor.activeLineGutter, + color: theme.editor.lineNumber, }, '.cm-foldPlaceholder': { - backgroundColor: getCSSVariable('--surface-color'), - border: `1px solid ${getCSSVariable('--border-color')}`, - color: getCSSVariable('--text-secondary'), + backgroundColor: theme.colors.surface, + border: `1px solid ${theme.colors.border}`, + color: theme.colors.textSecondary, }, '.cm-tooltip': { - border: `1px solid ${getCSSVariable('--border-color')}`, - backgroundColor: getCSSVariable('--surface-color'), + border: `1px solid ${theme.colors.border}`, + backgroundColor: theme.colors.surface, }, '.cm-tooltip .cm-tooltip-arrow:before': { - borderTopColor: getCSSVariable('--border-color'), + borderTopColor: theme.colors.border, }, '.cm-tooltip .cm-tooltip-arrow:after': { - borderTopColor: getCSSVariable('--surface-color'), + borderTopColor: theme.colors.surface, }, '.cm-tooltip-autocomplete': { '& > ul > li[aria-selected]': { - backgroundColor: getCSSVariable('--editor-selection'), - color: getCSSVariable('--text-color'), + backgroundColor: theme.editor.selection, + color: theme.colors.text, }, }, - }, { dark: getCSSVariable('--editor-background').startsWith('#1') || getCSSVariable('--editor-background').startsWith('#2') || getCSSVariable('--editor-background').startsWith('#0') }); + }, { dark: theme.name !== 'Light' }); - const highlightStyle = HighlightStyle.define([ - { tag: t.keyword, color: getCSSVariable('--syntax-keyword') }, - { tag: [t.name, t.deleted, t.character, t.macroName], color: getCSSVariable('--syntax-variable') }, - { tag: [t.function(t.variableName), t.labelName], color: getCSSVariable('--syntax-function') }, - { tag: [t.color, t.constant(t.name), t.standard(t.name)], color: getCSSVariable('--syntax-constant') }, - { tag: [t.definition(t.name), t.separator], color: getCSSVariable('--syntax-variable') }, - { tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: getCSSVariable('--syntax-class') }, - { tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: getCSSVariable('--syntax-operator') }, - { tag: [t.meta, t.comment], color: getCSSVariable('--syntax-comment'), fontStyle: 'italic' }, - { tag: t.strong, fontWeight: 'bold' }, - { tag: t.emphasis, fontStyle: 'italic' }, - { tag: t.strikethrough, textDecoration: 'line-through' }, - { tag: t.link, color: getCSSVariable('--accent-color'), textDecoration: 'underline' }, - { tag: t.heading, fontWeight: 'bold', color: getCSSVariable('--syntax-keyword') }, - { tag: [t.atom, t.bool, t.special(t.variableName)], color: getCSSVariable('--syntax-boolean') }, - { tag: [t.processingInstruction, t.string, t.inserted], color: getCSSVariable('--syntax-string') }, - { tag: t.invalid, color: getCSSVariable('--danger-color') }, - { tag: t.number, color: getCSSVariable('--syntax-number') }, - { tag: [t.propertyName], color: getCSSVariable('--syntax-property') }, - { tag: [t.typeName], color: getCSSVariable('--syntax-type') }, - { tag: [t.tagName], color: getCSSVariable('--syntax-tag') }, - { tag: [t.attributeName], color: getCSSVariable('--syntax-attribute') }, - ]); + const highlightStyle = createHighlightStyle(theme); return [editorTheme, syntaxHighlighting(highlightStyle)]; } diff --git a/src/lib/themes/apply-theme.ts b/src/lib/themes/apply-theme.ts index d278215..3412338 100644 --- a/src/lib/themes/apply-theme.ts +++ b/src/lib/themes/apply-theme.ts @@ -7,17 +7,30 @@ export function applyTheme(theme: Theme): void { root.setProperty('--bg-color', theme.colors.background); root.setProperty('--surface-color', theme.colors.surface); + root.setProperty('--surface-hover', theme.colors.surfaceHover); root.setProperty('--border-color', theme.colors.border); root.setProperty('--text-color', theme.colors.text); root.setProperty('--text-secondary', theme.colors.textSecondary); root.setProperty('--accent-color', theme.colors.accent); root.setProperty('--accent-hover', theme.colors.accentHover); + root.setProperty('--accent-text', theme.colors.accentText); root.setProperty('--input-bg', theme.colors.input); root.setProperty('--input-border', theme.colors.inputBorder); + root.setProperty('--input-border-focus', theme.colors.inputBorderFocus); root.setProperty('--button-bg', theme.colors.button); root.setProperty('--button-hover', theme.colors.buttonHover); root.setProperty('--danger-color', theme.colors.danger); root.setProperty('--danger-hover', theme.colors.dangerHover); + root.setProperty('--danger-text', theme.colors.dangerText); + root.setProperty('--warning-color', theme.colors.warning); + root.setProperty('--warning-hover', theme.colors.warningHover); + root.setProperty('--warning-text', theme.colors.warningText); + root.setProperty('--info-color', theme.colors.info); + root.setProperty('--info-hover', theme.colors.infoHover); + root.setProperty('--info-text', theme.colors.infoText); + root.setProperty('--success-color', theme.colors.success); + root.setProperty('--success-hover', theme.colors.successHover); + root.setProperty('--success-text', theme.colors.successText); root.setProperty('--editor-background', theme.editor.background); root.setProperty('--editor-foreground', theme.editor.foreground); diff --git a/src/lib/themes/definitions/ayumirage.ts b/src/lib/themes/definitions/ayumirage.ts index 193be95..d5af63b 100644 --- a/src/lib/themes/definitions/ayumirage.ts +++ b/src/lib/themes/definitions/ayumirage.ts @@ -5,17 +5,30 @@ export const ayumirage: Theme = { colors: { background: '#1f2430', surface: '#232834', + surfaceHover: '#2d3540', border: '#33415e', text: '#cccac2', textSecondary: '#707a8c', accent: '#ffcc66', accentHover: '#ffd580', + accentText: '#1f2430', input: '#242936', inputBorder: '#33415e', + inputBorderFocus: '#ffcc66', button: '#33415e', buttonHover: '#3e4b66', danger: '#f28779', dangerHover: '#f5a697', + dangerText: '#1f2430', + warning: '#ffa759', + warningHover: '#f29e74', + warningText: '#1f2430', + info: '#5ccfe6', + infoHover: '#73d0ff', + infoText: '#1f2430', + success: '#d5ff80', + successHover: '#bae67e', + successText: '#1f2430', }, editor: { background: '#1f2430', diff --git a/src/lib/themes/definitions/blue.ts b/src/lib/themes/definitions/blue.ts index c34836a..97fa4fa 100644 --- a/src/lib/themes/definitions/blue.ts +++ b/src/lib/themes/definitions/blue.ts @@ -5,17 +5,30 @@ export const blue: Theme = { colors: { background: '#0e1525', surface: '#162032', + surfaceHover: '#1d2840', border: '#1f2d47', text: '#c5d4eb', textSecondary: '#7a8bb0', accent: '#4d9fff', accentHover: '#6eb0ff', + accentText: '#0e1525', input: '#1a2840', inputBorder: '#2a3d5f', + inputBorderFocus: '#4d9fff', button: '#1a2840', buttonHover: '#243554', danger: '#ff6b6b', dangerHover: '#ff5252', + dangerText: '#0e1525', + warning: '#ffb547', + warningHover: '#ff9f28', + warningText: '#0e1525', + info: '#5ccfe6', + infoHover: '#3ebfd8', + infoText: '#0e1525', + success: '#7dd3a0', + successHover: '#5ec481', + successText: '#0e1525', }, editor: { background: '#0e1525', diff --git a/src/lib/themes/definitions/bluescreen.ts b/src/lib/themes/definitions/bluescreen.ts index c905536..9b3e079 100644 --- a/src/lib/themes/definitions/bluescreen.ts +++ b/src/lib/themes/definitions/bluescreen.ts @@ -5,17 +5,30 @@ export const bluescreen: Theme = { colors: { background: '#0000aa', surface: '#0000cc', + surfaceHover: '#0000ee', border: '#5555ff', text: '#ffffff', textSecondary: '#aaaaff', accent: '#ffffff', accentHover: '#ddddff', + accentText: '#0000aa', input: '#0000cc', inputBorder: '#5555ff', + inputBorderFocus: '#ffffff', button: '#0000cc', buttonHover: '#0000ee', danger: '#ffffff', dangerHover: '#dddddd', + dangerText: '#0000aa', + warning: '#ffff00', + warningHover: '#ffff33', + warningText: '#0000aa', + info: '#00ffff', + infoHover: '#66ffff', + infoText: '#0000aa', + success: '#00ff00', + successHover: '#33ff33', + successText: '#0000aa', }, editor: { background: '#0000aa', diff --git a/src/lib/themes/definitions/catppuccin.ts b/src/lib/themes/definitions/catppuccin.ts index f90ea15..1087de5 100644 --- a/src/lib/themes/definitions/catppuccin.ts +++ b/src/lib/themes/definitions/catppuccin.ts @@ -5,17 +5,30 @@ export const catppuccin: Theme = { colors: { background: '#1e1e2e', surface: '#181825', + surfaceHover: '#313244', border: '#45475a', text: '#cdd6f4', textSecondary: '#6c7086', accent: '#89b4fa', accentHover: '#b4befe', + accentText: '#1e1e2e', input: '#181825', inputBorder: '#45475a', + inputBorderFocus: '#89b4fa', button: '#313244', buttonHover: '#45475a', danger: '#f38ba8', dangerHover: '#eba0ac', + dangerText: '#1e1e2e', + warning: '#f9e2af', + warningHover: '#fab387', + warningText: '#1e1e2e', + info: '#89dceb', + infoHover: '#74c7ec', + infoText: '#1e1e2e', + success: '#a6e3a1', + successHover: '#94e2d5', + successText: '#1e1e2e', }, editor: { background: '#1e1e2e', diff --git a/src/lib/themes/definitions/darcula.ts b/src/lib/themes/definitions/darcula.ts index c906f16..367766a 100644 --- a/src/lib/themes/definitions/darcula.ts +++ b/src/lib/themes/definitions/darcula.ts @@ -5,17 +5,30 @@ export const darcula: Theme = { colors: { background: '#2b2b2b', surface: '#313335', + surfaceHover: '#3c3f41', border: '#3c3f41', text: '#a9b7c6', textSecondary: '#808080', accent: '#4b6eaf', accentHover: '#5b7ec5', + accentText: '#ffffff', input: '#45494a', inputBorder: '#555555', + inputBorderFocus: '#4b6eaf', button: '#3c3f41', buttonHover: '#4c5052', danger: '#c75450', dangerHover: '#d96461', + dangerText: '#ffffff', + warning: '#e08a38', + warningHover: '#f0a648', + warningText: '#2b2b2b', + info: '#6897bb', + infoHover: '#78a7cb', + infoText: '#2b2b2b', + success: '#629755', + successHover: '#72a765', + successText: '#ffffff', }, editor: { background: '#2b2b2b', diff --git a/src/lib/themes/definitions/dracula.ts b/src/lib/themes/definitions/dracula.ts index bae8645..d69ad20 100644 --- a/src/lib/themes/definitions/dracula.ts +++ b/src/lib/themes/definitions/dracula.ts @@ -5,17 +5,30 @@ export const dracula: Theme = { colors: { background: '#282a36', surface: '#21222c', + surfaceHover: '#2e303e', border: '#44475a', text: '#f8f8f2', textSecondary: '#6272a4', accent: '#bd93f9', accentHover: '#d4b5ff', + accentText: '#282a36', input: '#44475a', inputBorder: '#6272a4', + inputBorderFocus: '#bd93f9', button: '#44475a', buttonHover: '#565869', danger: '#ff5555', dangerHover: '#ff6e6e', + dangerText: '#282a36', + warning: '#ffb86c', + warningHover: '#ff9a4d', + warningText: '#282a36', + info: '#8be9fd', + infoHover: '#6ad7f5', + infoText: '#282a36', + success: '#50fa7b', + successHover: '#2ee85c', + successText: '#282a36', }, editor: { background: '#282a36', diff --git a/src/lib/themes/definitions/georges.ts b/src/lib/themes/definitions/georges.ts index 85d7c72..f94bdfe 100644 --- a/src/lib/themes/definitions/georges.ts +++ b/src/lib/themes/definitions/georges.ts @@ -5,17 +5,30 @@ export const georges: Theme = { colors: { background: '#000000', surface: '#0a0a0a', + surfaceHover: '#1a1a1a', border: '#1a1a1a', text: '#e0e0e0', textSecondary: '#808080', accent: '#00d9ff', accentHover: '#33e1ff', + accentText: '#000000', input: '#0a0a0a', inputBorder: '#1a1a1a', + inputBorderFocus: '#00d9ff', button: '#1a1a1a', buttonHover: '#2a2a2a', danger: '#ff3366', dangerHover: '#ff5580', + dangerText: '#000000', + warning: '#ff9d00', + warningHover: '#ffb86c', + warningText: '#000000', + info: '#57c7ff', + infoHover: '#b4f1ff', + infoText: '#000000', + success: '#a5ff90', + successHover: '#c1ffae', + successText: '#000000', }, editor: { background: '#000000', diff --git a/src/lib/themes/definitions/gruvbox.ts b/src/lib/themes/definitions/gruvbox.ts index c6ce676..834d5f6 100644 --- a/src/lib/themes/definitions/gruvbox.ts +++ b/src/lib/themes/definitions/gruvbox.ts @@ -5,17 +5,30 @@ export const gruvbox: Theme = { colors: { background: '#282828', surface: '#3c3836', + surfaceHover: '#504945', border: '#504945', text: '#ebdbb2', textSecondary: '#a89984', accent: '#fe8019', accentHover: '#fe9720', + accentText: '#282828', input: '#3c3836', inputBorder: '#504945', + inputBorderFocus: '#fe8019', button: '#3c3836', buttonHover: '#504945', danger: '#fb4934', dangerHover: '#cc241d', + dangerText: '#282828', + warning: '#fabd2f', + warningHover: '#d79921', + warningText: '#282828', + info: '#83a598', + infoHover: '#458588', + infoText: '#282828', + success: '#b8bb26', + successHover: '#98971a', + successText: '#282828', }, editor: { background: '#282828', diff --git a/src/lib/themes/definitions/hacker.ts b/src/lib/themes/definitions/hacker.ts index ba60ebd..94802aa 100644 --- a/src/lib/themes/definitions/hacker.ts +++ b/src/lib/themes/definitions/hacker.ts @@ -5,17 +5,30 @@ export const hacker: Theme = { colors: { background: '#0d0d0d', surface: '#1a1a1a', + surfaceHover: '#252525', border: '#00ff00', text: '#00ff00', textSecondary: '#008800', accent: '#00ff00', accentHover: '#33ff33', + accentText: '#000000', input: '#1a1a1a', inputBorder: '#008800', + inputBorderFocus: '#00ff00', button: '#1a1a1a', buttonHover: '#0f2f0f', danger: '#ff0000', dangerHover: '#ff3333', + dangerText: '#000000', + warning: '#ffff00', + warningHover: '#ffff33', + warningText: '#000000', + info: '#00ffff', + infoHover: '#33ffff', + infoText: '#000000', + success: '#00ff88', + successHover: '#33ffaa', + successText: '#000000', }, editor: { background: '#0d0d0d', diff --git a/src/lib/themes/definitions/light.ts b/src/lib/themes/definitions/light.ts index 987bd97..b6069a7 100644 --- a/src/lib/themes/definitions/light.ts +++ b/src/lib/themes/definitions/light.ts @@ -5,17 +5,30 @@ export const light: Theme = { colors: { background: '#ffffff', surface: '#f5f5f5', + surfaceHover: '#e8e8e8', border: '#e0e0e0', text: '#333333', textSecondary: '#6e7681', accent: '#0066cc', accentHover: '#0052a3', + accentText: '#ffffff', input: '#ffffff', inputBorder: '#d0d0d0', + inputBorderFocus: '#0066cc', button: '#e8e8e8', buttonHover: '#d0d0d0', danger: '#d32f2f', dangerHover: '#b71c1c', + dangerText: '#ffffff', + warning: '#f57c00', + warningHover: '#e65100', + warningText: '#ffffff', + info: '#0288d1', + infoHover: '#01579b', + infoText: '#ffffff', + success: '#388e3c', + successHover: '#2e7d32', + successText: '#ffffff', }, editor: { background: '#ffffff', diff --git a/src/lib/themes/definitions/materialdarker.ts b/src/lib/themes/definitions/materialdarker.ts index c9cbbe8..b84e8ff 100644 --- a/src/lib/themes/definitions/materialdarker.ts +++ b/src/lib/themes/definitions/materialdarker.ts @@ -5,17 +5,30 @@ export const materialdarker: Theme = { colors: { background: '#212121', surface: '#292929', + surfaceHover: '#3a3a3a', border: '#3a3a3a', text: '#eeffff', textSecondary: '#616161', accent: '#80cbc4', accentHover: '#a1dbd5', + accentText: '#212121', input: '#292929', inputBorder: '#3a3a3a', + inputBorderFocus: '#80cbc4', button: '#3a3a3a', buttonHover: '#4a4a4a', danger: '#f07178', dangerHover: '#f49499', + dangerText: '#212121', + warning: '#ffcb6b', + warningHover: '#f78c6c', + warningText: '#212121', + info: '#89ddff', + infoHover: '#82aaff', + infoText: '#212121', + success: '#c3e88d', + successHover: '#a5d374', + successText: '#212121', }, editor: { background: '#212121', diff --git a/src/lib/themes/definitions/monodark.ts b/src/lib/themes/definitions/monodark.ts index af8ee9d..c90502e 100644 --- a/src/lib/themes/definitions/monodark.ts +++ b/src/lib/themes/definitions/monodark.ts @@ -5,17 +5,30 @@ export const monodark: Theme = { colors: { background: '#000000', surface: '#0a0a0a', + surfaceHover: '#1a1a1a', border: '#333333', text: '#ffffff', textSecondary: '#999999', accent: '#ffffff', accentHover: '#cccccc', + accentText: '#000000', input: '#1a1a1a', inputBorder: '#444444', + inputBorderFocus: '#666666', button: '#1a1a1a', buttonHover: '#2a2a2a', danger: '#ffffff', dangerHover: '#cccccc', + dangerText: '#000000', + warning: '#ffaa00', + warningHover: '#ff8800', + warningText: '#000000', + info: '#3399ff', + infoHover: '#1177dd', + infoText: '#000000', + success: '#00cc66', + successHover: '#00aa55', + successText: '#000000', }, editor: { background: '#000000', diff --git a/src/lib/themes/definitions/monokai.ts b/src/lib/themes/definitions/monokai.ts index 06ea3ca..871a65a 100644 --- a/src/lib/themes/definitions/monokai.ts +++ b/src/lib/themes/definitions/monokai.ts @@ -5,17 +5,30 @@ export const monokai: Theme = { colors: { background: '#272822', surface: '#2e2f2a', + surfaceHover: '#3a3b35', border: '#3e3d32', text: '#f8f8f2', textSecondary: '#75715e', accent: '#66d9ef', accentHover: '#a1efe4', + accentText: '#272822', input: '#3e3d32', inputBorder: '#5a5a47', + inputBorderFocus: '#66d9ef', button: '#3e3d32', buttonHover: '#49483e', danger: '#f92672', dangerHover: '#ff669d', + dangerText: '#272822', + warning: '#fd971f', + warningHover: '#e67e00', + warningText: '#272822', + info: '#66d9ef', + infoHover: '#a1efe4', + infoText: '#272822', + success: '#a6e22e', + successHover: '#8dc919', + successText: '#272822', }, editor: { background: '#272822', diff --git a/src/lib/themes/definitions/monolight.ts b/src/lib/themes/definitions/monolight.ts index 2f2295a..1a59d53 100644 --- a/src/lib/themes/definitions/monolight.ts +++ b/src/lib/themes/definitions/monolight.ts @@ -5,17 +5,30 @@ export const monolight: Theme = { colors: { background: '#ffffff', surface: '#f8f8f8', + surfaceHover: '#eeeeee', border: '#e0e0e0', text: '#000000', textSecondary: '#666666', accent: '#000000', accentHover: '#333333', + accentText: '#ffffff', input: '#ffffff', inputBorder: '#cccccc', + inputBorderFocus: '#666666', button: '#f0f0f0', buttonHover: '#e0e0e0', danger: '#000000', dangerHover: '#333333', + dangerText: '#ffffff', + warning: '#666666', + warningHover: '#555555', + warningText: '#ffffff', + info: '#555555', + infoHover: '#444444', + infoText: '#ffffff', + success: '#444444', + successHover: '#333333', + successText: '#ffffff', }, editor: { background: '#ffffff', diff --git a/src/lib/themes/definitions/nightowl.ts b/src/lib/themes/definitions/nightowl.ts index ce86968..f7feafa 100644 --- a/src/lib/themes/definitions/nightowl.ts +++ b/src/lib/themes/definitions/nightowl.ts @@ -5,17 +5,30 @@ export const nightowl: Theme = { colors: { background: '#011627', surface: '#0b2942', + surfaceHover: '#1d3b53', border: '#1d3b53', text: '#d6deeb', textSecondary: '#637777', accent: '#80a4c2', accentHover: '#9fb9d0', + accentText: '#011627', input: '#0b2942', inputBorder: '#1d3b53', + inputBorderFocus: '#80a4c2', button: '#1d3b53', buttonHover: '#2d4f6b', danger: '#ef5350', dangerHover: '#f27572', + dangerText: '#011627', + warning: '#ecc48d', + warningHover: '#f78c6c', + warningText: '#011627', + info: '#82aaff', + infoHover: '#7fdbca', + infoText: '#011627', + success: '#addb67', + successHover: '#7fdbca', + successText: '#011627', }, editor: { background: '#011627', diff --git a/src/lib/themes/definitions/nord.ts b/src/lib/themes/definitions/nord.ts index e15895b..2d0a3cd 100644 --- a/src/lib/themes/definitions/nord.ts +++ b/src/lib/themes/definitions/nord.ts @@ -5,17 +5,30 @@ export const nord: Theme = { colors: { background: '#2e3440', surface: '#3b4252', + surfaceHover: '#434c5e', border: '#4c566a', text: '#d8dee9', textSecondary: '#81a1c1', accent: '#88c0d0', accentHover: '#8fbcbb', + accentText: '#2e3440', input: '#3b4252', inputBorder: '#4c566a', + inputBorderFocus: '#88c0d0', button: '#434c5e', buttonHover: '#4c566a', danger: '#bf616a', dangerHover: '#d08770', + dangerText: '#2e3440', + warning: '#ebcb8b', + warningHover: '#d08770', + warningText: '#2e3440', + info: '#81a1c1', + infoHover: '#5e81ac', + infoText: '#2e3440', + success: '#a3be8c', + successHover: '#8fa876', + successText: '#2e3440', }, editor: { background: '#2e3440', diff --git a/src/lib/themes/definitions/onedarkpro.ts b/src/lib/themes/definitions/onedarkpro.ts index 9bdaecb..eba6263 100644 --- a/src/lib/themes/definitions/onedarkpro.ts +++ b/src/lib/themes/definitions/onedarkpro.ts @@ -5,17 +5,30 @@ export const onedarkpro: Theme = { colors: { background: '#1e2127', surface: '#282c34', + surfaceHover: '#3e4451', border: '#3e4451', text: '#abb2bf', textSecondary: '#5c6370', accent: '#61afef', accentHover: '#84c0f4', + accentText: '#1e2127', input: '#282c34', inputBorder: '#3e4451', + inputBorderFocus: '#61afef', button: '#3e4451', buttonHover: '#4b5362', danger: '#e06c75', dangerHover: '#e88388', + dangerText: '#1e2127', + warning: '#e5c07b', + warningHover: '#d19a66', + warningText: '#1e2127', + info: '#56b6c2', + infoHover: '#61afef', + infoText: '#1e2127', + success: '#98c379', + successHover: '#7fb068', + successText: '#1e2127', }, editor: { background: '#1e2127', diff --git a/src/lib/themes/definitions/solarizeddark.ts b/src/lib/themes/definitions/solarizeddark.ts index 562c644..cdc7b9c 100644 --- a/src/lib/themes/definitions/solarizeddark.ts +++ b/src/lib/themes/definitions/solarizeddark.ts @@ -5,17 +5,30 @@ export const solarizeddark: Theme = { colors: { background: '#002b36', surface: '#073642', + surfaceHover: '#094551', border: '#586e75', text: '#839496', textSecondary: '#657b83', accent: '#268bd2', accentHover: '#2aa198', + accentText: '#002b36', input: '#073642', inputBorder: '#586e75', + inputBorderFocus: '#268bd2', button: '#073642', buttonHover: '#094551', danger: '#dc322f', dangerHover: '#cb4b16', + dangerText: '#fdf6e3', + warning: '#b58900', + warningHover: '#cb4b16', + warningText: '#002b36', + info: '#2aa198', + infoHover: '#268bd2', + infoText: '#002b36', + success: '#859900', + successHover: '#719600', + successText: '#002b36', }, editor: { background: '#002b36', diff --git a/src/lib/themes/definitions/solarizedlight.ts b/src/lib/themes/definitions/solarizedlight.ts index b7a9da6..52208b7 100644 --- a/src/lib/themes/definitions/solarizedlight.ts +++ b/src/lib/themes/definitions/solarizedlight.ts @@ -5,17 +5,30 @@ export const solarizedlight: Theme = { colors: { background: '#fdf6e3', surface: '#eee8d5', + surfaceHover: '#e4ddc4', border: '#93a1a1', text: '#657b83', textSecondary: '#839496', accent: '#268bd2', accentHover: '#2aa198', + accentText: '#fdf6e3', input: '#eee8d5', inputBorder: '#93a1a1', + inputBorderFocus: '#268bd2', button: '#eee8d5', buttonHover: '#e4ddc4', danger: '#dc322f', dangerHover: '#cb4b16', + dangerText: '#fdf6e3', + warning: '#b58900', + warningHover: '#cb4b16', + warningText: '#fdf6e3', + info: '#2aa198', + infoHover: '#268bd2', + infoText: '#fdf6e3', + success: '#859900', + successHover: '#719600', + successText: '#fdf6e3', }, editor: { background: '#fdf6e3', diff --git a/src/lib/themes/definitions/tokyonight.ts b/src/lib/themes/definitions/tokyonight.ts index cf7a7e9..c0f5312 100644 --- a/src/lib/themes/definitions/tokyonight.ts +++ b/src/lib/themes/definitions/tokyonight.ts @@ -5,17 +5,30 @@ export const tokyonight: Theme = { colors: { background: '#1a1b26', surface: '#16161e', + surfaceHover: '#1f2335', border: '#414868', text: '#c0caf5', textSecondary: '#565f89', accent: '#7aa2f7', accentHover: '#89b4fa', + accentText: '#1a1b26', input: '#1f2335', inputBorder: '#414868', + inputBorderFocus: '#7aa2f7', button: '#1f2335', buttonHover: '#24283b', danger: '#f7768e', dangerHover: '#ff9e64', + dangerText: '#1a1b26', + warning: '#e0af68', + warningHover: '#ff9e64', + warningText: '#1a1b26', + info: '#2ac3de', + infoHover: '#7dcfff', + infoText: '#1a1b26', + success: '#9ece6a', + successHover: '#b9f27c', + successText: '#1a1b26', }, editor: { background: '#1a1b26', diff --git a/src/lib/themes/index.ts b/src/lib/themes/index.ts index 739e7da..d84756b 100644 --- a/src/lib/themes/index.ts +++ b/src/lib/themes/index.ts @@ -1,5 +1,6 @@ export type { Theme } from './types'; export { applyTheme } from './apply-theme'; +export { createHighlightStyle } from './utils'; import type { Theme } from './types'; import { light } from './definitions/light'; import { blue } from './definitions/blue'; diff --git a/src/lib/themes/types.ts b/src/lib/themes/types.ts index 658d616..fa071fb 100644 --- a/src/lib/themes/types.ts +++ b/src/lib/themes/types.ts @@ -3,17 +3,30 @@ export interface Theme { colors: { background: string; surface: string; + surfaceHover: string; border: string; text: string; textSecondary: string; accent: string; accentHover: string; + accentText: string; input: string; inputBorder: string; + inputBorderFocus: string; button: string; buttonHover: string; danger: string; dangerHover: string; + dangerText: string; + warning: string; + warningHover: string; + warningText: string; + info: string; + infoHover: string; + infoText: string; + success: string; + successHover: string; + successText: string; }; editor: { background: string; diff --git a/src/lib/themes/utils.ts b/src/lib/themes/utils.ts new file mode 100644 index 0000000..119dabe --- /dev/null +++ b/src/lib/themes/utils.ts @@ -0,0 +1,30 @@ +import { HighlightStyle } from '@codemirror/language'; +import { tags as t } from '@lezer/highlight'; +import type { Theme } from './types'; + +export function createHighlightStyle(theme: Theme): HighlightStyle { + return HighlightStyle.define([ + { tag: t.keyword, color: theme.syntax.keyword }, + { tag: [t.function(t.variableName), t.labelName], color: theme.syntax.function }, + { tag: [t.variableName], color: theme.syntax.function }, + { tag: [t.name, t.deleted, t.character, t.macroName], color: theme.syntax.variable }, + { tag: [t.color, t.constant(t.name), t.standard(t.name)], color: theme.syntax.constant }, + { tag: [t.definition(t.name), t.separator], color: theme.syntax.variable }, + { tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: theme.syntax.class }, + { tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: theme.syntax.operator }, + { tag: [t.meta, t.comment], color: theme.syntax.comment }, + { tag: t.strong, fontWeight: 'bold' }, + { tag: t.emphasis, fontStyle: 'italic' }, + { tag: t.strikethrough, textDecoration: 'line-through' }, + { tag: t.link, color: theme.syntax.string, textDecoration: 'underline' }, + { tag: t.heading, fontWeight: 'bold', color: theme.syntax.keyword }, + { tag: [t.atom, t.bool, t.special(t.variableName)], color: theme.syntax.boolean }, + { tag: [t.processingInstruction, t.string, t.inserted], color: theme.syntax.string }, + { tag: t.invalid, color: theme.editor.foreground }, + { tag: t.number, color: theme.syntax.number }, + { tag: [t.propertyName], color: theme.syntax.property }, + { tag: [t.typeName], color: theme.syntax.type }, + { tag: [t.tagName], color: theme.syntax.tag }, + { tag: [t.attributeName], color: theme.syntax.attribute }, + ]); +}