Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fiamecaster/prism-code-editor
Lightweight, extensible code editor component for the web using Prism
https://github.com/fiamecaster/prism-code-editor
code-editor css editor highlighting javascript prismjs textarea typescript
Last synced: 24 minutes ago
JSON representation
Lightweight, extensible code editor component for the web using Prism
- Host: GitHub
- URL: https://github.com/fiamecaster/prism-code-editor
- Owner: FIameCaster
- License: mit
- Created: 2023-07-26T22:52:11.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-09T21:02:36.000Z (12 days ago)
- Last Synced: 2025-02-14T12:41:38.825Z (7 days ago)
- Topics: code-editor, css, editor, highlighting, javascript, prismjs, textarea, typescript
- Language: JavaScript
- Homepage: https://prism-code-editor.netlify.app
- Size: 3.68 MB
- Stars: 78
- Watchers: 3
- Forks: 7
- Open Issues: 4
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
Prism code editor
Lightweight, extensible code editor component for the web using Prism.
## Why?
There are multiple fully featured code editors for the web such as Monaco, Ace and CodeMirror. While these are awesome, they have a large footprint and are likely overkill for code examples, forms, playgrounds or anywhere you won't display large documents.
## How?
This library overlays syntax highlighted code over a ``. Libraries like [CodeFlask](https://github.com/kazzkiq/CodeFlask), [react-simple-code-editor](https://github.com/react-simple-code-editor/react-simple-code-editor), and many others have been doing this for years, but this library offers some distinct advantages:
- It uses a trimmed Prism's core less than ⅓ the size that no longer relies on global variables.
- It re-exports Prism's languages that now automatically import their required dependencies and embedded languages are resolved at runtime.
- It splits the highlighted code into lines. This makes it easy to add line numbers, highlight a line and only update changed lines in the DOM for efficient updates.
- The core is light as a feather with a wide array of [extensions](#extensions) you can choose from and [multiple events](#events) to listen to.## Contents
- [Installation](#installation)
- [Basic usage](#basic-usage)
- [Advanced usage](#advanced-usage)
- [Usage with frameworks](#usage-with-frameworks)
- [Options](#options)
- [Events](#events)
- [Importing Prism](#importing-prism)
- [Importing grammars](#importing-grammars)
- [Usage with Node.js](#usage-with-nodejs)
- [Examples](#examples)
- [Extensions](#extensions)
- [Importing extensions](#importing-extensions)
- [Creating your own](#creating-your-own)
- [Styling](#styling)
- [Importing themes](#importing-themes)
- [Adding themes](#adding-themes)
- [Scrollbar styling](#scrollbar-styling)
- [Advanced styling](#advanced-styling)
- [Creating a theme](#creating-a-theme)
- [Language specific behavior](#language-specific-behavior)
- [Importing](#importing)
- [Individual imports](#individual-imports)
- [Adding your own](#adding-your-own)
- [Avoiding layout shifts](#avoiding-layout-shifts)
- [Tooltips](#tooltips)
- [Overscroll](#overscroll)
- [RTL support](#rtl-support)
- [Editing key commands](#editing-key-commands)
- [Web components](#web-components)
- [Performance](#performance)
- [Compatibility](#compatibility)
- [Credits](#credits)
- [Contributing](#contributing)## Installation
npm i prism-code-editor
## Basic usage
The library includes 4 different setups you can import. These will automatically import the necessary styles and scope them with a shadow root, add various extensions and import all language specific behavior. There are also [web components](#web-components) wrapping these setups if that's preferred.
These setups are very cumbersome to customize and are therefore only recommended while getting started.
```javascript
import { minimalEditor, basicEditor, fullEditor, readonlyEditor } from "prism-code-editor/setups"
// Importing Prism grammars
import "prism-code-editor/prism/languages/markup"const editor = basicEditor(
"#editor",
{
language: "html",
theme: "github-dark",
},
() => console.log("ready"),
)
```**Note:** You might want to add `display: grid` to the container the editor is added to.
## Advanced usage
With little effort, you can fully customize which extensions are added and how they're loaded. This won't use a shadow root which makes the editor much easier to style and customize.
```javascript
// index.ts
import "prism-code-editor/prism/languages/markup"
import "prism-code-editor/prism/languages/css-extras"
import "prism-code-editor/prism/languages/javascript"import { createEditor } from "prism-code-editor"
import { matchBrackets } from "prism-code-editor/match-brackets"
import { indentGuides } from "prism-code-editor/guides"// Importing styles
import "prism-code-editor/layout.css"
import "prism-code-editor/scrollbar.css"
import "prism-code-editor/themes/github-dark.css"export const editor = createEditor(
"#editor",
{ language: "html" },
indentGuides(),
matchBrackets(),
)
import("./extensions")
```To minimize your main JavaScript bundle, you can dynamically import all extensions *(but some probably shouldn't be)*.
```typescript
// extensions.ts
import "prism-code-editor/search.css"
import "prism-code-editor/copy-button.css"
import "prism-code-editor/languages/html"
import "prism-code-editor/languages/clike"
import "prism-code-editor/languages/css"import { searchWidget, highlightSelectionMatches } from "prism-code-editor/search"
import { defaultCommands, editHistory } from "prism-code-editor/commands"
import { cursorPosition } from "prism-code-editor/cursor"
import { copyButton } from "prism-code-editor/copy-button"
import { matchTags } from "prism-code-editor/match-tags"
import { highlightBracketPairs } from "prism-code-editor/highlight-brackets"
import { editor } from "./index"editor.addExtensions(
highlightSelectionMatches(),
searchWidget(),
defaultCommands(),
copyButton(),
matchTags(),
highlightBracketPairs(),
cursorPosition(),
editHistory(),
)
```## Usage with frameworks
This library has been rewritten for React and SolidJS. These rewrites better integrate with their respective framework than any wrapper ever could and are highly recommended if you're already using React or SolidJS.
- [React rewrite](https://github.com/FIameCaster/prism-react-editor)
- [SolidJS rewrite](https://github.com/FIameCaster/solid-prism-editor)## Options
| Name | Type | Description |
| ---- | ---- | ----------- |
| `language` | `string` | Language used for syntax highlighting. Defaults to `text`. |
| `tabSize` | `number` | Tab size used for indentation. Defaults to `2`. |
| `insertSpaces` | `boolean` | Whether the editor should insert spaces for indentation. Defaults to `true`. Requires the `defaultCommands()` extension to work. |
| `lineNumbers` | `boolean` | Whether line numbers should be shown. Defaults to `true`. |
| `readOnly` | `boolean` | Whether the editor should be read only. Defaults to `false`. |
| `wordWrap` | `boolean` | Whether the editor should have word wrap. Defaults to `false`. |
| `value` | `string` | Initial value to display in the editor. |
| `rtl` | `boolean` | Whether the editor uses right to left directionality. Defaults to `false`. Requires extra CSS from `prism-code-editor/rtl-layout.css` to work. |
| `onUpdate` | `(value: string => void` | Function called after the editor updates. |
| `onSelectionChange` | `(selection: InputSelection, value: string) => void` | Function called when the editor's selection changes. |
| `onTokenize` | `(tokens: TokenStream, language: string, value: string) => void` | Function called before the tokens are stringified to HTML. |## Events
There are three different event both you and extensions can listen to: `tokenize`, `update` and `selectionChange`.
The `tokenize` event is dispatched after the code is tokenized, which makes it possible to change the tokens before the HTML string is created.
The `update` event is dispatched after the syntax highlighted DOM has been updated.
The `selectionChange` event is dispatched right after the `update` event or when the user changes the selection.
## Importing Prism
If you want to add your own language to Prism or perform syntax highlighting outside of an editor, this is where to import from:
```javascript
import {
// Functions
highlightText,
highlightTokens,
tokenizeText,
withoutTokenizer,
// Record storing loaded languages
languages,
// Symbols used in grammars
tokenize,
rest,
// Token class
Token
} from "prism-code-editor/prism"// Utilities used by grammars
import {
clone, insertBefore, extend, embeddedIn
} from "prism-code-editor/prism/utils"// To add your own language, just mutate the languages record
languages["my-language"] = {
// ...
}
```For more information about these exports, read the [API documentation](https://prism-code-editor.netlify.app/api/modules/prism).
**Note:** CRLF and CR line breaks are not supported. So before highlighting, you might need to normalize line breaks using something like `text.replace(/\r\n?/g, "\n")`.
### Importing grammars
As you might've seen from the examples, prism grammars are imported from `prism-code-editor/prism/languages/*`. Importing a grammar will automatically register it through side effects. If you're importing multiple grammars, import order usually won't matter. The exception comes when grammars modify other grammars. Take this example:
```javascript
import "prism-code-editor/prism/languages/typescript"
import "prism-code-editor/prism/languages/js-templates"
```This won't add `js-templates` features to `typescript` because it extended `javascript` before `js-templates` was added. Swapping the import order fixes the issue.
If you need access to many languages, you can import the following entry points:
- `prism-code-editor/prism/languages` for all languages (~180kB)
- `prism-code-editor/prism/languages/common` for [42 common languages](https://github.com/FIameCaster/prism-code-editor/tree/main/package/src/prism/languages/common.js) (~30kB)Take this simple markdown editor as an example. Here, only the markdown grammar is required initially. The common languages are dynamically imported and once they load, the editor is updated, which will highlight all markdown code blocks.
```javascript
import "prism-code-editor/prism/languages/markdown"
import { createEditor } from "prism-code-editor"const editor = createEditor("#editor", { language: "markdown" })
import("prism-code-editor/prism/languages/common").then(() => editor.update())
```## Usage with Node.js
The entry points `prism-code-editor/prism`, `prism-code-editor/prism/utils` and the grammars from `prism-code-editor/prism/languages/*` can all run on Node.js for those who want to generate HTML with it.
## Examples
- [`height: auto` without layout shifts](https://stackblitz.com/edit/vitejs-vite-sbvab7?file=index.html,src%2Fstyle.css,src%2Fmain.ts,readme.md)
- [Simple tooltip example](https://stackblitz.com/edit/vitejs-vite-z2fgpu?file=src%2Fmain.ts)
- [Autocomplete example](https://stackblitz.com/edit/vitejs-vite-tjcjyl?file=src%2Fautocomplete.ts)
- [Formatting with Prettier](https://stackblitz.com/edit/vitejs-vite-x7tzhu?file=src%2Fmain.ts,src%2Fextensions.ts)
- [Relative line numbers](https://stackblitz.com/edit/vitejs-vite-2wytja?file=src%2Fextensions.ts,src%2Fmain.ts)
- [Usage in forms](https://stackblitz.com/edit/vitejs-vite-pk9ud7?file=src%2Fmain.ts)
- [Adding elements to code lines](https://stackblitz.com/edit/vitejs-vite-y5pwon?file=src%2Fmain.ts,readme.md)
- [Custom cursor](https://stackblitz.com/edit/vitejs-vite-sza5zx?file=src%2Fstyle.css,src%2Fextensions.ts)## Extensions
Most behavior isn't included by default and must be imported. This is to keep the core small for those who don't need the extra functionality. See [advanced usage](#advanced-usage) for how to add extensions.
There are extensions adding:
- Many common commands
- Bracket matching and rainbow brackets
- Tag matching
- Indentation guides
- Search, regex search and replace
- Selection match highlighting
- A copy button
- Read-only code folding
- Custom undo/redoThe default commands extension includes:
- Wrapping selection in brackets/quotes
- Automatic closing of brackets, quotes, and tags
- Automatic indentation and indentation with Tab keyAnd it includes these commands:
- Alt+ArrowUp/Down: Move line up/down
- Shift+Alt+ArrowUp/Down: Copy line up/down
- Ctrl+ArrowUp/Down (Not on MacOS): Scroll up/down 1 line
- Ctrl+Enter (Cmd+Enter on MacOS) Insert blank line
- Ctrl+[ (Cmd+[ on MacOS): Outdent line
- Ctrl+] (Cmd+] on MacOS): Indent line
- Shift+Ctrl+K (Shift+Cmd+K on MacOS): Delete line
- Ctrl+/ (Cmd+/ on MacOS): Toggle comment
- Shift+Alt+A: Toggle block comment
- Ctrl+M (Ctrl+Shift+M on MacOS): Toggle Tab capturing### Importing extensions
```javascript
import { matchBrackets } from "prism-code-editor/match-brackets"
import { matchTags } from "prism-code-editor/match-tags"
import { indentGuides } from "prism-code-editor/guides"
import {
searchWidget,
highlightSelectionMatches,
highlightCurrentWord,
showInvisibles
} from "prism-code-editor/search"
import { defaultCommands, editHistory } from "prism-code-editor/commands"
import { cursorPosition } from "prism-code-editor/cursor"
import { copyButton } from "prism-code-editor/copy-button"
import { highlightBracketPairs } from "prism-code-editor/highlight-brackets"
import {
readOnlycodeFolding,
markdownFolding,
blockCommentFolding
} from "prism-code-editor/code-folding"
import { autoComplete } from "prism-code-editor/autocomplete"// And CSS
import "prism-code-editor/search.css"
import "prism-code-editor/copy-button.css"
import "prism-code-editor/code-folding.css"
import "prism-code-editor/invisibles.css"
import "prism-code-editor/autocomplete.css"
import "prism-code-editor/autocomplete-icons.css"
```### Creating your own
```typescript
import { Extension } from "prism-code-editor"interface MyExtension extends Extension {}
const myExtension = (): MyExtension => {
// Add local variables and functions in the closurereturn {
update(editor, options) {
// Called when the extension is added to an editor
// And when the options change
},
}
}
```You can also write a class with an update method if that's preferred.
You can also use a plain function as an extension. This function won't be called when the editor's options change.
```typescript
import { BasicExtension, createEditor } from "prism-code-editor"const myExtension = (): BasicExtension => {
return (editor, options) => {
// This won't be called when the options change
}
}createEditor("#editor", {}, (editor, options) => {
// This will be called before the first render
})
```## Handling Tab
If you're adding the default commands to your editor, the tab key is used for indentation. If this isn't wanted, you can change the behavior.
Users can at any time toggle tab capturing with Ctrl+M / Ctrl+Shift+M (Mac).
```javascript
import { setIgnoreTab } from "prism-code-editor/commands"
setIgnoreTab(true)
```## Styling
### Importing themes
There are currently 13 different themes you can import, one of them being from `prism-code-editor/themes/github-dark.css`.
You can also dynamically import themes into your JavaScript. This is used by the demo website.
```javascript
import { loadTheme } from "prism-code-editor/themes"const isDark = matchMedia("(prefers-color-scheme: dark)").matches
loadTheme(isDark ? "github-dark" : "github-light").then(theme => {
console.log(theme)
})
```### Adding themes
If you're using the setups or web components, you can override the existing themes or add new ones. The example below might be different if you're not using Vite as your bundler.
```javascript
import { registerTheme } from "prism-code-editor/themes"registerTheme("my-theme", () => import("./my-theme.css?inline"))
```### Scrollbar styling
You can import a stylesheet that will give a custom scrollbar to desktop Chrome and Safari.
```javascript
import "prism-code-editor/scrollbar.css"
```You can change the color of the scrollbar thumb using the custom property `--editor__bg-scrollbar`. Different alphas will be set based on the state of the scrollbar thumb.
```css
.prism-code-editor {
/* Values are: Hue, saturation, lightness */
--editor__bg-scrollbar: 210, 10%, 40%;
}
```### Advanced styling
If you're not using any of the setups, the styles aren't scoped using a shadow root, which makes them easy to change. If you want to change color, background, font, line-height or similar, you can do it on `.prism-code-editor` with CSS.
Default padding is `0.75em` left/right and `0.5em` top/bottom. If you want to change it, you can use the custom property `--padding-inline` for left/right. Padding top and bottom can changed by changing the margin on `.pce-wrapper`.
There are many classes added to `.prism-code-editor` you can use to style the editor based on its state:
- `pce-has-selection` if the textarea has a selection, and `pce-no-selection` if not
- `pce-focus` if the textarea is focused
- `show-line-numbers` if line numbers are enabled
- `pce-wrap` if word wrap is enabled, and `pce-nowrap` if not
- `pce-readonly` if the editor is read-only#### Creating a theme
It's likely that none of the themes perfectly fit your website. A great solution is to modify one of the [included themes](https://github.com/FIameCaster/prism-code-editor/tree/main/package/src/themes) to better suit your website. Alternatively, you can import one of the themes and override some of the styles in your on stylesheets.
Below is some additional styling information:
- `.pce-line::before` will match a line number
- `.pce-line.active-line` matches the line with the cursor
- `.prism-code-editor::before` is the background for the line numbers
- The variable `--number-spacing` is the spacing to the right of the line numbers which defaults to `0.75em`## Language specific behavior
If you're not using the setups, automatic indentation, toggling comments, and automatic closing of tags won't work. You'll need to import the behavior or define it yourself.
### Importing
The easiest way to get this working, is to import all languages. This will add comment toggling, etc. to almost all Prism languages at ~3.6kB gzipped. It's recommended to dynamically import this since it's usually not needed before the page has loaded.
```javascript
import("prism-code-editor/languages")
```You can also import `prism-code-editor/languages/common` instead to support a subset of common languages at less than 2kB gzipped.
#### Individual imports
Lastly, if you know exactly which languages you need, you can import behavior for individual languages. Refer to the list below for which imports adds comment toggling, etc. to which language(s).
List of all imports
The import for
ada
would beprism-code-editor/languages/ada
for example. This list is NOT for Prism grammars.
ImportLanguages/aliases added
abap
abap
abnf
abnf
actionscript
actionscript
ada
ada
agda
agda
al
al
antlr4
g4
andantlr4
apacheconf
apacheconf
apex
apex
apl
apl
applescript
applescript
aql
aql
arduino
ino
andarduino
arff
arff
arturo
art
andarturo
asciidoc
adoc
andasciidoc
asm
arm-asm
,armasm
,asm6502
,asmatmel
andnasm
aspnet
aspnet
autohotkey
autohotkey
autoit
autoit
avisynth
avs
andavisynth
avro-idl
avdl
andavro-idl
awk
awk
bash
sh
,shell
andbash
basic
basic
batch
batch
bbj
bbj
bicep
bicep
birb
birb
bison
bison
bqn
bqn
brightscript
brightscript
bro
bro
bsl
bsl
cfscript
cfscript
chaiscript
chaiscript
cil
cil
cilk
cilk-c
,cilkc
,cilk
,cilk-cpp
andcilkcpp
clike
clike
,js
,javascript
,ts
,typescript
,java
,cs
,csharp
,c
,cpp
,go
,d
,dart
,flow
andhaxe
clojure
clojure
cmake
cmake
cobol
cobol
coffeescript
coffee
andcoffeescript
concurnas
conc
andconcurnas
cooklang
cooklang
coq
coq
cshtml
razor
andcshtml
css
css
,less
,scss
andsass
cue
cue
cypher
cypher
dataweave
dataweave
dax
dax
dhall
dhall
django
jinja2
anddjango
dns-zone-file
dns-zone
anddns-zone-file
docker
dockerfile
anddocker
dot
gv
anddot
ebnf
ebnf
editorconfig
editorconfig
eiffel
eiffel
ejs
ejs
elixir
elixir
elm
elm
erb
erb
erlang
erlang
etlua
etlua
excel-formula
xlsx
,xls
andexcel-formula
factor
factor
false
false
firestore-security-rules
firestore-security-rules
fortran
fortran
fsharp
fsharp
ftl
ftl
gap
gap
gcode
gcode
gdscript
gdscript
gettext
gettext
gherkin
gherkin
git
git
glsl
glsl
andhlsl
gml
gamemakerlanguage
andgml
gn
gni
andgn
go-module
go-mod
andgo-module
gradle
gradle
graphql
graphql
groovy
groovy
haml
haml
handlebars
mustache
,hbs
andhandlebars
haskell
idr
,idris
,hs
,haskell
,purs
andpurescript
hcl
hcl
hoon
hoon
html
markup
,html
,markdown
andmd
ichigojam
ichigojam
icon
icon
iecst
iecst
ignore
npmignore
,hgignore
,gitignore
andignore
inform7
inform7
ini
ini
io
io
j
j
jolie
jolie
jq
jq
json
json
,json5
andjsonp
jsx
jsx
andtsx
julia
julia
keepalived
keepalived
keyman
keyman
kotlin
kts
,kt
andkotlin
kumir
kumir
kusto
kusto
latex
context
,tex
andlatex
latte
latte
lilypond
ly
andlilypond
linker-script
ld
andlinker-script
liquid
liquid
lisp
emacs-lisp
,emacs
,elisp
andlisp
livescript
livescript
llvm
llvm
lolcode
lolcode
lua
lua
magma
magma
makefile
makefile
mata
mata
matlab
matlab
maxscript
maxscript
mel
mel
mermaid
mermaid
metafont
metafont
mizar
mizar
mongodb
mongodb
monkey
monkey
moonscript
moon
andmoonscript
n1ql
n1ql
n4js
n4jsd
andn4js
nand2tetris-hdl
nand2tetris-hdl
naniscript
nani
andnaniscript
neon
neon
nevod
nevod
nginx
nginx
nim
nim
nix
nix
nsis
nsis
objectivec
objc
andobjectivec
ocaml
ocaml
odin
odin
opencl
opencl
openqasm
qasm
andopenqasm
oz
oz
parigp
parigp
parser
parser
pascal
pascaligo
,objectpascal
andpascal
peoplecode
pcode
andpeoplecode
perl
perl
php
php
plant-uml
plantuml
andplant-uml
powerquery
mscript
,pq
andpowerquery
powershell
powershell
processing
processing
prolog
prolog
promql
promql
properties
properties
protobuf
protobuf
psl
psl
pug
pug
puppet
puppet
pure
pure
purebasic
pbfasm
andpurebasic
python
rpy
,renpy
,py
andpython
q
q
qml
qml
qore
qore
qsharp
qs
andqsharp
r
r
reason
reason
rego
rego
rescript
res
andrescript
rest
rest
rip
rip
roboconf
roboconf
robotframework
robot
androbotframework
ruby
crystal
,rb
andruby
rust
rust
sas
sas
scala
scala
scheme
racket
andscheme
smali
smali
smalltalk
smalltalk
smarty
smarty
sml
smlnj
andsml
solidity
sol
andsolidity
solution-file
sln
andsolution-file
soy
soy
splunk-spl
splunk-spl
sqf
sqf
sql
plsql
andsql
squirrel
squirrel
stan
stan
stata
stata
stylus
stylus
supercollider
sclang
andsupercollider
swift
swift
systemd
systemd
tcl
tcl
textile
textile
toml
toml
tremor
trickle
,troy
andtremor
tt2
tt2
turtle
rq
,sparql
,trig
andturtle
twig
twig
typoscript
tsconfig
andtyposcript
unrealscript
uc
,uscript
andunrealscript
uorazor
uorazor
v
v
vala
vala
vbnet
vbnet
velocity
velocity
verilog
verilog
vhdl
vhdl
vim
vim
visual-basic
vba
,vb
andvisual-basic
warpscript
warpscript
wasm
wasm
web-idl
webidl
andweb-idl
wgsl
wgsl
wiki
wiki
wolfram
nb
,wl
,mathematica
andwolfram
wren
wren
xeora
xeoracube
andxeora
xml
xml
,ssml
,atom
,rss
,mathml
andsvg
xojo
xojo
xquery
xquery
yaml
yml
andyaml
yang
yang
zig
zig
### Adding your own
```javascript
import { languageMap } from "prism-code-editor"languageMap.whatever = {
comments: {
line: "//",
block: ["/*", "*/"]
},
getComments(editor, position) {
// Method called when a user executes a comment toggling command
// Useful if a language uses different comment tokens in different contexts
// Currently used by JSX so {/* */} is used to toggle comments in JSX contexts
},
autoIndent: [
// Whether to indent
([start], value) => /[([{][^\n)\]}]*$/.test(code.slice(0, start)),
// Whether to add an extra line
([start, end], value) => /\[]|\(\)|{}/.test(code[start - 1] + code[end])
],
autoCloseTags([start, end, direction], value) {
// Function called when the user types ">", intended to auto close tags.
// If a string is returned, it will get inserted behind the cursor.
}
}
```## Avoiding layout shifts
Adding an editor in the middle of your page will cause layout shifts. This is bad for UX and should ideally be mitigated. One way is to reserve space for the editor by giving its container a fixed height or a grid layout. This works well enough for editors with vertical scrolling.
A second solution is to have a placeholder element which gets replaced by your editor. This is the ideal solution for read-only code examples where you want `height: auto` instead of a vertical scroll bar. To make this easier, there's a wrapper around `createEditor` intended for exactly this which replaces your element instead of appending the editor to it. The placeholder element's `textContent` will be used as the editor's code unless `options.value` is defined.
```javascript
import { editorFromPlaceholder } from "prism-code-editor"const editor = editorFromPlaceholder("#editor", { language: "javascript" })
```If you know the height of the editor, your placeholder could be as simple as a div with a fixed height. If not, the placeholder element should have a very similar layout to the editor, i.e., same `padding`, `font-size`, `font-family`, `white-space`, `line-height`. How this achieved doesn't matter, but a solution is to use similar markup to the editor itself. [Here's an example](https://stackblitz.com/edit/vitejs-vite-sbvab7?file=index.html,src%2Fstyle.css,src%2Fmain.ts,readme.md) of this.
## Tooltips
There's a utility to display tooltips above or below the cursor that can be imported from `prism-code-editor/tooltips`.
```typescript
const addTooltip = (editor: PrismEditor, element: HTMLElement, fixedWidth?: boolean): [ShowTooltip, HideTooltip]const [show, hide] = addTooltip(editor, element)
```If you want the tooltip to always be visible when the user scrolls horizontally, add `position: sticky` along with the `left` and/or `right` CSS properties to your tooltip.
## Overscroll
```javascript
import { addOverscroll, removeOverscroll } from "prism-code-editor/tooltips"addOverscroll(editor)
```This will allow users to scroll until the last line is at the top of the editor.
## RTL Support
RTL support is disabled by default. To enable it, you need to import an extra stylesheet, only then will the `rtl` option do something.
```javascript
import "prism-code-editor/rtl-layout.css"
```RTL support is currently experimental due to multiple browser bugs being present:
- In Chrome and Safari, the line number background won't stick when scrolling. The line numbers themselves are given a background to compensate, but this isn't perfect.
- In Firefox, the first tab character on a line will sometimes be incorrectly sized.
- In Safari, absolutely positioned elements inside lines can change the order of characters when mixing RTL and LTR text and tab characters are super buggy.If you want to use RTL directionality, you should be aware of these bugs and use spaces instead of tabs for indenting.
## Editing key commands
Editing key commands is as simple as mutating the `keyCommandMap` for the editor. If you're adding the default commands to the editor, be sure to mutate the command map after adding that extension.
```javascript
// Adding a Ctrl+Alt shortcut without removing the default enter functionality
const oldEnterCallback = editor.keyCommandMap.Entereditor.keyCommandMap.Enter = (e, selection, value) => {
if (e.altKey) {
// Shortcut code goes here// returning true will automatically call e.preventDefault()
return true
}
return oldEnterCallback?.(e, selection, value)
}// Removing the default backspace command
editor.keyCommandMap.Backspace = null
```Changing `editor.inputCommandMap` will work the exact same way.
## Web components
The library includes a custom element wrapper for each of the 4 setups you can import.
```typescript
import { addBasicEditor, PrismEditorElement } from "prism-code-editor/web-component"// Adds a web component with the specified name
addBasicEditor("prism-editor")const editorElement = document.querySelector("prism-editor")
// Add a listener for when the editor finishes loading
editorElement.addEventListener("ready", () => console.log("ready"))// The editor can be accessed from the element
console.log(editorElement.editor)
```Attributes include `language`, `theme`, `tab-size`, `line-numbers`, `word-wrap`, `readonly`, `insert-spaces` and `rtl`. These attributes are also writable properties on the element.
```html
The editors initial code goes here
```
## Performance
All the code is tokenized each time for simplicity's sake. Even though only lines that change are updated in the DOM, the editor slows down as more code is added, although not as quickly as with zero optimizations.
Once you start approaching 1000 LOC, the editor will start slowing down on most hardware. If you need to display that much code, consider a more robust/heavy library.
## Compatibility
This has been tested to work in the latest desktop and mobile versions of both Safari, Chrome, and Firefox. It should work in slightly older browsers too, but there will be many bugs present in browsers that don't support `beforeinput` events.
This library does not support any Prism plugins since Prism hooks have been removed. Behavior like the [Highlight Keywords](https://prismjs.com/plugins/highlight-keywords/) plugin is included.
Some grammars have had small changes, most notably markup tags' grammar. So Prism themes will work to style the tokens, but there can be some slight differences.
PrismJS automatically adds the global regex flag to the pattern of greedy tokens. This has been removed, so if you're using your own Prism grammars, you might have to add the global flag to the greedy tokens.
## Credits
This library is made possible thanks to [Prism](https://prismjs.com).
## Contributing
Feature requests, bug reports, optimizations and potentially new themes and extensions are all welcome.
To test your changes during development, install dependencies:
cd package
pnpm installAnd run the development server:
pnpm run dev