<light-editor>
A minimal plain text editor with syntax highlighting, line numbers, and line highlighting.
<light-editor>
is not intended to replace full solutions like CodeMirror, but it
is a lightweight alternative using a <pre>
overlaid on top of a <textarea>
and a few extra divs to make for an enjoyable text editing experience.
If you check the source code in the above example, you’ll notice a </script>
.
For more on why script tags are used, check out Why script tags for further reading.
Examples
Using the value attribute
Using the value
attribute is the generally recommended way to provide the most consistent experience. By default,
leading and trailing newlines / whitespace will be stripped.
Preserve white space with value attribute
By default, extra white space before the first character and after the last character will be stripped.
If you want to leave extra white-space, pass the preserve-whitespace
boolean attribute to the editor.
With a template tag
We can use a <template>
tag to be able to “slot” in the default value
Changing the highlight language to CSS
By default, the highlighter from Highlight.js only supports HTML / CSS / JS.
This is intentional to keep the bundle size low. Supported languages are html
, css
, and js
.
Using a script tag
<light-editor>
<!-- Important to use `type="text/plain"` -->
<script type="text/plain">
<script></script>
</script>
</light-editor>
Disabled Editor
To disable the editor, provide a disabled
attribute.
Editor with a placeholder
To provide a placeholder, use the placeholder
attribute. Note, this does not support a <slot>
because it’s using the native <textarea>
placeholder attribute.
Editor with validations
Validations are handled using “Form Associated Custom Elements”.
<light-editor>
supports minlength
, maxlength
, and required
just like the
native <textarea>
element.
minlength, maxlength, required validations
Removing line numbers
Removing line numbers can be done with the boolean attribute disable-line-numbers
Whitespace wrapping
By default <light-preview>
will “soft wrap” lines for you. Meaning, code will wrap and not overflow
the container. If this is undesirable, you can pass wrap="hard"
and lines will not wrap.
Here’s a preview of soft wrapping vs hard wrapping.
With "soft" wrapping
With "hard" wrapping
Additional Notes
Caveats to the initial editor value
Declarative slots are hard. The most “consistent” way to provide a default value for the editor
is to use value
attribute. Like so:
<light-editor value="<html></html>"></light-editor>
Problems with declarative slotting
If you really want declarative slotting, it’s best to use a <textarea>
in the default slot.
The editor is really a <textarea>
at it’s core, so its recommended to use the <textarea>
element to slot in elements.
It has 1 drawback which is around not being able to slot in a <textarea>
directly.
And showing <
and >
literals is challenging. &lt;html&gt;
is equivalent to >html<>
This limitation only exists for slotting.
Using a <textarea>
element for the default slot requires the following markup to nest a
<textarea>
string literal inside of it:
<light-editor>
<textarea>
<textarea></textarea>
</textarea>
</light-editor>
Other slottable tags
<template>
formats the HTML and strips improper HTML. It’s also not suitable for non-HTML strings. You can do it, but you’ve been warned.
<xmp>
is deprecated and also has some issues around if you do something like: <!DOCTYPE html >
<!-- -->
isn’t supported like with Prism’s auto escape plugin could be used, but runs into issues if you want comments nested in comments.
API Reference
Imports
<!-- Auto registers as <light-editor> -->
<script type="module" src="https://cdn.jsdelivr.net/npm/light-pen/exports/components/light-editor/light-editor-register.js"></script>
<script type="module">
// Auto registers as <light-editor>
import "https://cdn.jsdelivr.net/npm/light-pen/exports/components/light-editor/light-editor-register.js"
// Manual Register
import LightEditor from "https://cdn.jsdelivr.net/npm/light-pen/exports/components/light-editor/light-editor.js"
LightEditor.define()
// => Registers as <light-editor>
</script>
// Auto registers as <light-editor>
import "light-pen/exports/components/light-editor/light-editor-register.js"
// Manual Register
import LightEditor "light-pen/exports/components/light-editor/light-editor.js"
LightEditor.define()
// => Registers as <light-editor>
Attributes
Name | Description | Reflects | Type | Default |
---|---|---|---|---|
[Attribute + Property]
language
|
The language used for highlighting. Default is “html”. “css” and “js” also included by default. |
|
string
|
"html"
|
[Attribute + Property]
src
|
Points to a remote file source that should be accessible via |
|
string | null
|
null
|
[Attribute + Property]
wrap
|
If |
|
"soft" | "hard"
|
"soft"
|
[Attribute]
preserve-whitespace
[Property] preserveWhitespace
|
Whether to strip whitespace before first character, and after the last character. |
|
boolean
|
false
|
[Attribute]
disable-line-numbers
[Property] disableLineNumbers
|
-
|
|
boolean
|
false
|
[Attribute]
data-has-focused
[Property] hasFocused
|
-
|
|
boolean
|
-
|
Events
Name | Description |
---|---|
light-value-change
|
Emitted whenever the “value” attribute of the editor changes. |
change
|
-
|
light-focus
|
Re-emits the textarea’s “focus” event |
light-blur
|
Re-emits the textarea’s “blur” event |
light-selectionchange
|
Re-emits the textarea’s “selectionchange” event |
light-input
|
Re-emits the textarea’s “input” event |
input
|
-
|
light-resize
|
Is emitting whenever the editor resizes. |
light-change
|
Re-emits the textarea’s “change” event |
Functions
Name | Description | Parameters |
---|---|---|
click()
|
-
|
-
|
focus()
|
-
|
options: FocusOptions
|
getCaretPosition()
|
-
|
-
|
setCurrentLineHighlight()
|
-
|
-
|
getLinesToSelectionStart()
|
-
|
-
|
getCurrentLineNumber()
|
-
|
-
|