An embeddable code editor
for the browser.

Tiny (~3 kB), no dependencies. Type straight into highlighted code, with any highlighter.

npm i codejar

How it works

Most small editors lay a transparent <textarea> over a highlighted <pre>. Both must match exactly, or the caret drifts. CodeJar makes the highlighted element itself contenteditable: it saves the caret, lets your highlighter re-render, and restores the caret. Tokens can be styled freely and long lines wrap naturally. Turn on Outline tokens above to see the elements you type into.

Two layers. You type into an invisible textarea and look at a copy. Every style has to match on both layers.
CodeJar. One element. You type directly into the highlighted <span>s.

Usage

import { CodeJar } from 'codejar'
import Prism from 'prismjs'

const jar = CodeJar(document.querySelector('.editor'), (editor) => {
  editor.innerHTML = Prism.highlight(
    editor.textContent,
    Prism.languages.js,
    'js',
  )
})

The second argument is your highlighter: it gets the element and rewrites its HTML. Give the element a monospace font; use CSS tab-size to size tabs.

Options

Passed as the third argument.

tab = '\t'
String inserted on Tab.
indentOn = /[({[]$/
Indent the new line if the text before the caret matches.
moveToNewLine = /^[)}\]]/
Move the text after the caret to its own line if it matches.
spellcheck = false
Enable the browser spellchecker.
catchTab = true
Handle Tab and Shift+Tab.
preserveIdent = true
Keep indentation on a new line.
addClosing = true
Auto-close brackets and quotes.
autoclose = { open: `([{'"`, close: `)]}'"` }
Pairs to auto-close.
history = true
Undo and redo.
window = window
Window to use, e.g. for iframes.

API

updateCode(code, callOnUpdate = true)
Set the code.
updateOptions(options)
Change options.
onUpdate(callback)
Called with the code on every change.
toString()
Get the code.
save() / restore(pos)
Save and restore the caret or selection.
recordHistory()
Push the current state onto the undo stack.
destroy()
Remove event listeners.