TypeScript Tutorial: Creating a Simple Online Code Editor with Themes

In the world of web development, the ability to write and test code directly in your browser is incredibly valuable. Whether you’re a seasoned developer or just starting your coding journey, having an online code editor at your fingertips can significantly boost your productivity. This tutorial will guide you through creating a simple, yet functional, online code editor using TypeScript. We’ll focus on implementing a core feature: the ability to switch between different themes, allowing users to customize their coding environment to their liking.

Why Build an Online Code Editor?

Online code editors offer several advantages. They eliminate the need for local installations, making code accessible from any device with a web browser. They’re perfect for quick code snippets, experimenting with new languages, and collaborating with others. Moreover, they provide an excellent learning environment, allowing developers to see immediate results and iterate quickly. Adding theme support enhances the user experience, as it allows users to choose a coding environment that suits their preferences, reducing eye strain and improving overall readability.

What We’ll Cover

In this tutorial, we will cover the following key aspects:

  • Setting up a basic TypeScript project.
  • Creating the core HTML structure for our editor.
  • Implementing a code editor using a popular library (e.g., CodeMirror or Monaco Editor).
  • Adding a theme selection feature.
  • Applying different themes to the editor.
  • Handling user interactions (theme selection).

Prerequisites

Before you begin, make sure you have the following:

  • A basic understanding of HTML, CSS, and JavaScript.
  • Node.js and npm (or yarn) installed on your system.
  • A code editor (like VS Code, Sublime Text, or similar).

Step-by-Step Guide

1. Setting Up the Project

First, let’s set up our project. Open your terminal or command prompt and create a new directory for your project:

mkdir online-code-editor
cd online-code-editor

Next, initialize a new npm project:

npm init -y

Now, install TypeScript and a code editor library (we’ll use CodeMirror for this example, but you can choose Monaco Editor or another library):

npm install typescript codemirror @types/codemirror

Initialize a TypeScript configuration file:

npx tsc --init

This command creates a tsconfig.json file. You can customize this file to configure how TypeScript compiles your code. For this project, you might want to set the following options:

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "moduleResolution": "node",
    "outDir": "./dist",
    "sourceMap": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"]
}

This configuration targets ECMAScript 5 (ES5) for broader browser compatibility, uses ESNext modules, specifies a node module resolution strategy, sets the output directory to ‘dist’, enables source maps for debugging, enables strict type checking, and enables interoperation between CommonJS and ES modules. It also skips type checking for library files and ensures consistent casing for file names. The include array specifies that all files within the ‘src’ directory and its subdirectories should be included in the compilation process.

2. Creating the HTML Structure

Create an index.html file in the root directory and add the following HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Online Code Editor</title>
    <link rel="stylesheet" href="codemirror/lib/codemirror.css">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <select id="theme-select">
            <option value="default">Default</option>
            <option value="dracula">Dracula</option>
            <option value="monokai">Monokai</option>
            <option value="solarized dark">Solarized Dark</option>
            <option value="solarized light">Solarized Light</option>
        </select>
        <div id="editor-container"></div>
    </div>
    <script src="codemirror/lib/codemirror.js"></script>
    <script src="codemirror/mode/javascript/javascript.js"></script>
    <script src="codemirror/mode/css/css.js"></script>
    <script src="codemirror/mode/htmlmixed/htmlmixed.js"></script>
    <script src="dist/app.js"></script>
</body>
</html>

This HTML sets up the basic layout. It includes a theme selection dropdown and a container for the code editor. It also links to the CodeMirror CSS and JavaScript files, as well as our custom CSS and compiled TypeScript (app.js). The included JavaScript files for the various modes (JavaScript, CSS, HTMLMixed) are essential for syntax highlighting.

Create a basic style.css file in the root directory for styling:

body {
    font-family: sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
}

.container {
    display: flex;
    flex-direction: column;
    height: 100vh;
}

#theme-select {
    padding: 10px;
    margin: 10px;
    border-radius: 5px;
    border: 1px solid #ccc;
    font-size: 16px;
}

#editor-container {
    flex-grow: 1;
    overflow: hidden;
}

3. Implementing the Code Editor in TypeScript

Create a src directory and inside it, create a file named app.ts. This is where we’ll write our TypeScript code. Here’s the initial code to set up CodeMirror:

import {EditorView} from '@codemirror/view';
import {EditorState} from '@codemirror/state';
import {javascript} from '@codemirror/lang-javascript';
import {html} from '@codemirror/lang-html';
import {css} from '@codemirror/lang-css';

const editorContainer = document.getElementById('editor-container') as HTMLElement;
const themeSelect = document.getElementById('theme-select') as HTMLSelectElement;

if (!editorContainer || !themeSelect) {
    throw new Error('Editor container or theme select element not found');
}

const startingCode = `// Your code here
function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet('World');`;

const editorState = EditorState.create({
  doc: startingCode,
  extensions: [
    javascript(),
    html(),
    css(),
    EditorView.theme({}), // Add basic theme support here
  ],
});

const editorView = new EditorView({
  state: editorState,
  parent: editorContainer,
});

This code imports necessary modules from CodeMirror and sets up the basic editor. It retrieves the editor container and theme select elements from the DOM, initializes an editor state with some starting code, and creates an EditorView instance, attaching it to the editor container. The javascript(), html(), and css() extensions enable syntax highlighting for these languages.

4. Adding Theme Selection

Now, let’s add the functionality to change themes. We’ll create a function to apply themes based on the selected option:


function applyTheme(themeName: string) {
    let themeClass = '';

    switch (themeName) {
        case 'dracula':
            themeClass = 'cm-s-dracula';
            break;
        case 'monokai':
            themeClass = 'cm-s-monokai';
            break;
        case 'solarized dark':
            themeClass = 'cm-s-solarized dark';
            break;
        case 'solarized light':
            themeClass = 'cm-s-solarized light';
            break;
        default:
            themeClass = 'cm-s-default';
    }

    // Remove existing theme classes from the editor container
    editorView.dom.classList.forEach(className => {
        if (className.startsWith('cm-s-')) {
            editorView.dom.classList.remove(className);
        }
    });

    // Add the new theme class
    editorView.dom.classList.add(themeClass);
}

This applyTheme function takes a theme name as input and applies the corresponding CSS class to the editor’s DOM element. It first removes any existing theme classes to prevent conflicts and then adds the new theme class. You’ll need to include the CSS for these themes. For CodeMirror, you can find these styles in the `codemirror/theme` directory. For example, for Dracula, you would include codemirror/theme/dracula.css. Create a link tag in the index.html to import these css files like so:

<link rel="stylesheet" href="codemirror/theme/dracula.css">

To load other themes, you must include their respective CSS files.

Next, add an event listener to the theme select element to call the applyTheme function when the selection changes:


themeSelect.addEventListener('change', () => {
    const selectedTheme = themeSelect.value;
    applyTheme(selectedTheme);
});

// Initial theme application (default)
applyTheme(themeSelect.value);

This code listens for changes in the theme selection dropdown. When a new theme is selected, it calls the applyTheme function with the selected theme’s value. The last line applies the default theme when the page loads.

5. Compiling and Running

To compile your TypeScript code, run the following command in your terminal:

tsc

This will generate a dist/app.js file. Now, open index.html in your browser. You should see the code editor with the default theme. You can now select different themes from the dropdown, and the editor’s appearance should change accordingly.

Common Mistakes and How to Fix Them

1. Incorrect Paths for CSS and JavaScript Files

Mistake: The most common issue is incorrect paths in the index.html file for the CSS and JavaScript files. For example, a typo in the path to the CodeMirror CSS file can prevent the editor from displaying correctly.

Fix: Double-check all file paths in your index.html file. Ensure that the paths are relative to the HTML file’s location. Use your browser’s developer tools (usually accessed by pressing F12) to check the console for any 404 errors, which indicate that a file could not be found.

2. Missing or Incorrect Theme CSS

Mistake: If the themes aren’t changing, or the editor’s appearance is not updating, you might be missing the CSS files for the themes you’re trying to use, or the paths to those CSS files are incorrect.

Fix: Make sure you’ve included the correct CSS files for each theme in your index.html file. For CodeMirror, these files are usually located in the codemirror/theme directory. Inspect the network tab in your browser’s developer tools to confirm that the theme CSS files are being loaded successfully.

3. Type Errors in TypeScript

Mistake: TypeScript’s strong typing system can help catch errors, but it can also lead to compilation errors if your code doesn’t adhere to the defined types.

Fix: Carefully review any TypeScript compilation errors. VS Code (or your chosen editor) will highlight these errors. Ensure that your variable types match the expected types and that you’re using the correct syntax for the libraries you’re using. If you’re unsure, consult the documentation for CodeMirror or the specific library you’re using.

4. Incorrect DOM Element Selection

Mistake: If your editor isn’t appearing, or if the theme selection isn’t working, it’s possible you’ve made a mistake when selecting the DOM elements (the editor container and the theme selection dropdown) in your TypeScript code.

Fix: Use the browser’s developer tools to inspect your HTML and verify that the IDs you’re using in your TypeScript code (e.g., 'editor-container', 'theme-select') match the actual IDs in your HTML. Also, double-check that the elements exist in the DOM when your TypeScript code runs. Make sure the script tag loading the `app.js` file is placed at the end of the `body` tag.

5. Incorrect CodeMirror Initialization

Mistake: Errors in how you initialize the CodeMirror editor can prevent it from displaying or functioning correctly.

Fix: Review the CodeMirror documentation to ensure you’re initializing the editor correctly. Pay close attention to the required options and the correct methods for setting up the editor. Make sure you are importing the correct modules for syntax highlighting (e.g., javascript, css, html) and that the extensions are properly included in the `EditorState.create()` call.

Key Takeaways

This tutorial demonstrated how to create a simple online code editor with theme selection using TypeScript and CodeMirror. We’ve covered the fundamental steps, from setting up the project and HTML structure to implementing the editor and theme switching functionality. By following these steps, you can create a functional and customizable online code editor, enhancing your coding experience.

FAQ

1. Can I use a different code editor library?

Yes, you can. While this tutorial uses CodeMirror, you can easily adapt the code to use other libraries like Monaco Editor. The core concepts (HTML structure, theme selection logic) will remain similar; you’ll just need to adjust the code that interacts with the specific editor library.

2. How can I add more themes?

To add more themes, you’ll need to include the CSS files for those themes in your index.html file and add corresponding cases to the applyTheme function. Each theme will have a unique CSS class that you’ll apply to the editor’s DOM element.

3. How do I add syntax highlighting for other languages?

To add syntax highlighting for other languages, you’ll need to import the relevant language mode modules from CodeMirror (or your chosen library) and include them in the editor’s configuration. For example, for Python, you would import the Python mode and add it to the `extensions` array in the `EditorState.create()` call.

4. How can I add features like auto-completion and code formatting?

CodeMirror (and other editor libraries) offer extensions for features like auto-completion and code formatting. You’ll need to import and configure these extensions in your TypeScript code. Consult the documentation for your chosen library to learn how to add these features.

5. Where can I find more themes for CodeMirror?

The CodeMirror documentation and community resources are great places to find more themes. You can also find themes on websites like GitHub, where developers often share custom themes for various code editors. Always make sure the theme is compatible with the CodeMirror version you are using.

Building an online code editor is a fantastic way to learn about web development and TypeScript. By starting with a simple project and gradually adding features like theme selection, you can gain valuable experience and create a useful tool. Remember to practice, experiment, and don’t be afraid to consult the documentation and community resources when you encounter challenges. The ability to customize your coding environment is a powerful tool, and with the techniques you’ve learned here, you’re well on your way to creating a coding experience that is both functional and enjoyable.

” ,
“aigenerated_tags”: “TypeScript, Code Editor, Web Development, Tutorial, Themes, CodeMirror, Online Editor