CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-uiw--react-codemirror

React wrapper component for CodeMirror 6 editor with TypeScript support and extensible theming system

Pending
Overview
Eval results
Files

themes.mddocs/

Theme System

Built-in themes and utilities for creating custom themes for the CodeMirror editor. The theme system provides light, dark, and no-theme variants out of the box, plus full support for custom theme creation.

Capabilities

Built-in Light Theme

Default light theme with clean styling optimized for readability.

/**
 * Default light theme extension with white background
 * Provides clean, minimal styling for light environments
 */
const defaultLightThemeOption: Extension;

Usage Examples:

import CodeMirror from "@uiw/react-codemirror";
import { defaultLightThemeOption } from "@uiw/react-codemirror";

// Using the built-in light theme directly
function LightThemedEditor() {
  return (
    <CodeMirror
      value="// Light theme example"
      theme={defaultLightThemeOption}
      height="200px"
    />
  );
}

// Using string shorthand (equivalent)
function LightThemedEditorShorthand() {
  return (
    <CodeMirror
      value="// Light theme example"
      theme="light"
      height="200px"
    />
  );
}

Built-in Dark Theme

One Dark theme imported from CodeMirror's official theme collection.

/**
 * One Dark theme extension (re-exported from @codemirror/theme-one-dark)
 * Popular dark theme with purple-blue accent colors
 */
const oneDark: Extension;

Usage Examples:

import CodeMirror from "@uiw/react-codemirror";
import { oneDark } from "@uiw/react-codemirror";

// Using the built-in dark theme directly
function DarkThemedEditor() {
  return (
    <CodeMirror
      value="// Dark theme example"
      theme={oneDark}
      height="200px"
    />
  );
}

// Using string shorthand (equivalent)
function DarkThemedEditorShorthand() {
  return (
    <CodeMirror
      value="// Dark theme example"
      theme="dark"
      height="200px"
    />
  );
}

No Theme Option

Option to disable all built-in theming and use only manually provided theme extensions.

/**
 * No theme option - disables all built-in themes
 * Use when you want complete control over styling via custom extensions
 */
theme: 'none'

Usage Examples:

import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";

// Using no theme - completely unstyled
function UnstyledEditor() {
  return (
    <CodeMirror
      value="// No built-in theme applied"
      theme="none"
      height="200px"
    />
  );
}

// Using no theme with custom styling
function CustomStyledEditor() {
  const customTheme = EditorView.theme({
    '&': {
      backgroundColor: '#f8f9fa',
      color: '#343a40',
    },
    '.cm-content': {
      fontFamily: 'Monaco, monospace',
      fontSize: '14px',
    },
  });

  return (
    <CodeMirror
      value="// Custom styled editor"
      theme="none"
      extensions={[customTheme]}
      height="200px"
    />
  );
}

Custom Theme Creation

Support for creating completely custom themes using CodeMirror's theme system.

Usage Examples:

import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";
import { javascript } from "@codemirror/lang-javascript";

// Creating a custom theme
function CustomThemedEditor() {
  const customTheme = EditorView.theme({
    // Editor container
    '&': {
      color: '#2d3748',
      backgroundColor: '#f7fafc',
      fontSize: '14px',
      fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
    },
    
    // Content area
    '.cm-content': {
      padding: '16px',
      minHeight: '100px',
      caretColor: '#4299e1',
    },
    
    // Cursor and selection
    '.cm-cursor, .cm-dropCursor': {
      borderLeftColor: '#4299e1',
      borderLeftWidth: '2px',
    },
    
    '.cm-focused .cm-selectionBackground, ::selection': {
      backgroundColor: '#bee3f8',
    },
    
    // Line numbers
    '.cm-gutters': {
      backgroundColor: '#edf2f7',
      color: '#a0aec0',
      border: 'none',
      borderRight: '1px solid #e2e8f0',
    },
    
    '.cm-activeLineGutter': {
      backgroundColor: '#e2e8f0',
      color: '#4a5568',
    },
    
    // Active line
    '.cm-activeLine': {
      backgroundColor: '#f1f5f9',
    },
    
    // Matching brackets
    '.cm-matchingBracket': {
      backgroundColor: '#fed7d7',
      outline: '1px solid #fc8181',
    },
    
    // Search highlighting
    '.cm-searchMatch': {
      backgroundColor: '#fef5e7',
      outline: '1px solid #f6ad55',
    },
    
    '.cm-searchMatch.cm-searchMatch-selected': {
      backgroundColor: '#fbd38d',
    },
  });

  return (
    <CodeMirror
      value={`// Custom themed editor
const greeting = "Hello World!";
console.log(greeting);

function add(a, b) {
  return a + b;
}`}
      theme={customTheme}
      extensions={[javascript()]}
      height="250px"
    />
  );
}

// Creating a high-contrast theme
function HighContrastEditor() {
  const highContrastTheme = EditorView.theme({
    '&': {
      color: '#000000',
      backgroundColor: '#ffffff',
      fontSize: '16px',
      fontWeight: 'bold',
    },
    
    '.cm-content': {
      padding: '20px',
      caretColor: '#000000',
    },
    
    '.cm-cursor': {
      borderLeftColor: '#000000',
      borderLeftWidth: '3px',
    },
    
    '.cm-focused .cm-selectionBackground': {
      backgroundColor: '#ffff00',
      color: '#000000',
    },
    
    '.cm-gutters': {
      backgroundColor: '#f0f0f0',
      color: '#000000',
      borderRight: '2px solid #000000',
      fontWeight: 'bold',
    },
    
    '.cm-activeLine': {
      backgroundColor: '#ffffcc',
    },
    
    '.cm-matchingBracket': {
      backgroundColor: '#ff0000',
      color: '#ffffff',
      fontWeight: 'bold',
    },
  });

  return (
    <CodeMirror
      value="// High contrast theme for accessibility"
      theme={highContrastTheme}
      height="150px"
    />
  );
}

Theme Switching

Dynamic theme switching functionality for user preferences.

Usage Examples:

import React, { useState } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { oneDark, defaultLightThemeOption } from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";

function ThemeSwitchingEditor() {
  const [currentTheme, setCurrentTheme] = useState('light');
  
  const themes = {
    light: defaultLightThemeOption,
    dark: oneDark,
    custom: EditorView.theme({
      '&': {
        color: '#2d5016',
        backgroundColor: '#f0fff4',
      },
      '.cm-content': {
        caretColor: '#22543d',
      },
      '.cm-focused .cm-selectionBackground': {
        backgroundColor: '#c6f6d5',
      },
      '.cm-gutters': {
        backgroundColor: '#e6fffa',
        color: '#2d5016',
      },
    }),
  };

  return (
    <div>
      <div style={{ marginBottom: 10 }}>
        <label>
          Theme: 
          <select 
            value={currentTheme} 
            onChange={(e) => setCurrentTheme(e.target.value)}
            style={{ marginLeft: 8 }}
          >
            <option value="light">Light</option>
            <option value="dark">Dark</option>
            <option value="custom">Custom Green</option>
          </select>
        </label>
      </div>
      
      <CodeMirror
        value={`// Theme switching demo
// Current theme: ${currentTheme}
const message = "Switch themes using the dropdown above";
console.log(message);`}
        theme={themes[currentTheme]}
        height="200px"
      />
    </div>
  );
}

// System theme detection
function SystemThemeEditor() {
  const [theme, setTheme] = useState(() => {
    // Detect system preference
    if (typeof window !== 'undefined') {
      return window.matchMedia('(prefers-color-scheme: dark)').matches 
        ? 'dark' 
        : 'light';
    }
    return 'light';
  });

  React.useEffect(() => {
    if (typeof window !== 'undefined') {
      const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
      
      const handleChange = () => {
        setTheme(mediaQuery.matches ? 'dark' : 'light');
      };
      
      mediaQuery.addListener(handleChange);
      return () => mediaQuery.removeListener(handleChange);
    }
  }, []);

  return (
    <div>
      <div style={{ marginBottom: 10 }}>
        Current theme: {theme} (auto-detected from system)
      </div>
      
      <CodeMirror
        value="// This editor follows your system theme preference"
        theme={theme}
        height="150px"
      />
    </div>
  );
}

Theme Inheritance and Customization

Extending existing themes with additional styling.

Usage Examples:

import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { oneDark } from "@uiw/react-codemirror";
import { EditorView } from "@codemirror/view";

function ExtendedThemeEditor() {
  // Extend the dark theme with custom additions
  const extendedDarkTheme = [
    oneDark, // Base dark theme
    EditorView.theme({
      // Additional customizations
      '.cm-content': {
        fontSize: '16px',
        lineHeight: '1.6',
        fontFamily: '"Fira Code", monospace',
      },
      
      '.cm-gutters': {
        fontSize: '14px',
      },
      
      // Custom class for highlighted comments
      '.cm-comment': {
        fontStyle: 'italic',
        opacity: '0.8',
      },
      
      // Custom scrollbar (webkit browsers)
      '.cm-scroller::-webkit-scrollbar': {
        width: '8px',
      },
      
      '.cm-scroller::-webkit-scrollbar-track': {
        background: '#1e1e1e',
      },
      
      '.cm-scroller::-webkit-scrollbar-thumb': {
        background: '#4a4a4a',
        borderRadius: '4px',
      },
      
      '.cm-scroller::-webkit-scrollbar-thumb:hover': {
        background: '#5a5a5a',
      },
    }),
  ];

  return (
    <CodeMirror
      value={`// Extended dark theme with custom font and scrollbar
// This comment should appear italic
const code = "Beautiful syntax highlighting";
console.log(code);`}
      theme={extendedDarkTheme}
      height="200px"
    />
  );
}

// Theme with CSS variables for dynamic customization
function VariableThemeEditor() {
  const [primaryColor, setPrimaryColor] = useState('#4299e1');
  
  const variableTheme = EditorView.theme({
    '&': {
      '--primary-color': primaryColor,
      '--primary-light': primaryColor + '20',
      '--primary-dark': primaryColor + 'dd',
    },
    
    '.cm-content': {
      caretColor: 'var(--primary-color)',
    },
    
    '.cm-focused .cm-selectionBackground': {
      backgroundColor: 'var(--primary-light)',
    },
    
    '.cm-cursor': {
      borderLeftColor: 'var(--primary-color)',
    },
    
    '.cm-activeLine': {
      backgroundColor: 'var(--primary-light)',
    },
    
    '.cm-matchingBracket': {
      backgroundColor: 'var(--primary-dark)',
      color: 'white',
    },
  });

  return (
    <div>
      <div style={{ marginBottom: 10 }}>
        <label>
          Primary Color: 
          <input
            type="color"
            value={primaryColor}
            onChange={(e) => setPrimaryColor(e.target.value)}
            style={{ marginLeft: 8 }}
          />
        </label>
      </div>
      
      <CodeMirror
        value="// Dynamic theme with CSS variables"
        theme={variableTheme}
        height="150px"
      />
    </div>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-uiw--react-codemirror

docs

extensions.md

hook-api.md

index.md

main-component.md

themes.md

utilities.md

tile.json