JSFiddle - React, Tailwind, and code Playground

by ckissi

HTML

<script src="https://unpkg.com/[email protected]/dist/shiki.browser.min.js"></script>
<div class="code-container">
        <textarea id="codeTextarea" spellcheck="false"></textarea>
        <pre id="highlightedCode"></pre>
    </div>

CSS

<!DOCTYPE html>
<html>
<head>
    <title>Shiki Textarea Highlighter</title>
    <script src="https://unpkg.com/[email protected]/dist/shiki.browser.min.js"></script>
    <style>
        .code-container {
            position: relative;
            width: 100%;
            max-width: 600px;
        }
        #codeTextarea {
            width: 100%;
            font-family: monospace;
            min-height: 200px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 2;
            background: transparent;
            color: transparent;
            caret-color: black;
            border: 1px solid #ccc;
            resize: vertical;
        }
        #highlightedCode {
            width: 100%;
            min-height: 200px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 1;
            font-family: monospace;
            padding: 10px;
            border: 1px solid #ccc;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

JavaScript

async function setupHighlighter() {
            const highlighter = await shiki.getHighlighter({
                theme: 'github-light',
                langs: ['javascript', 'typescript', 'python', 'html', 'css']
            });

            const textarea = document.getElementById('codeTextarea');
            const highlightedCodeElement = document.getElementById('highlightedCode');

            function updateHighlighting() {
                const code = textarea.value;
                const language = textarea.dataset.language || 'javascript';
                
                try {
                    const highlighted = highlighter.codeToHtml(code, { 
                        lang: language 
                    });
                    
                    highlightedCodeElement.innerHTML = highlighted;
                } catch (error) {
                    console.error('Highlighting error:', error);
                }
            }

            textarea.addEventListener('input', updateHighlighting);
            textarea.addEventListener('scroll', () => {
                highlightedCodeElement.scrollTop = textarea.scrollTop;
            });

            textarea.dataset.language = 'javascript';
        }

        setupHighlighter();