streamlit-lexical-extended
A rich-text Markdown editor for Streamlit, powered by
Lexical. It supports formatting, lists, quotes, code
blocks, tables, undo/redo, programmatic updates, and multiple independent
editors. Markdown output uses hard-break markers for consecutive plain-text
lines, so line breaks remain visible when rendered with st.markdown.
Version 0.3 uses package-based Streamlit Custom Components v2. The editor renders directly in Streamlit's DOM without an iframe.
Requirements
- Python 3.10+
- Streamlit 1.51+
- Node.js 24+ for development
Installation
pip install streamlit-lexical-extended
Quick start
The component natively returns a Markdown string (str). When key is set,
Streamlit stores the string in st.session_state[key].
import streamlit as st
from streamlit_lexical_extended import streamlit_lexical_extended
def editor_changed() -> None:
markdown = st.session_state["editor"]
st.toast(f"Document updated: {len(markdown)} characters")
markdown_text = streamlit_lexical_extended(
value="# Hello",
key="editor",
height=360,
on_change=editor_changed,
)
st.markdown(markdown_text)
st.code(st.session_state["editor"], language="markdown")
The function accepts value, placeholder, height, min_height,
debounce, key, on_change, width, and toolbar.
value=Noneleaves the current editor content untouched;value=""clears it. Any other string replaces the current document.height=intuses a fixed height with internal scrolling.height=Nonegrows with content and respectsmin_height.widthaccepts"stretch","content", or a positive pixel integer.on_changereceives no arguments.
Toolbar configuration
By default, toolbar=None displays every tool. Pass a list to display only
the controls needed by a particular editor:
result = streamlit_lexical_extended(
value="# Compact editor",
key="compact_editor",
toolbar=["undo", "redo", "block_type", "bold", "italic"],
)
An empty list hides the toolbar:
result = streamlit_lexical_extended(
value="Keyboard-first editor",
toolbar=[],
)
Available tool names:
| Tool | Control |
|---|---|
undo, redo |
History |
block_type |
Paragraph and heading selector |
bold, italic, underline, strikethrough |
Inline formatting |
quote |
Block quote |
bullet_list, numbered_list |
Lists |
table |
Table insertion |
Selected controls retain the editor's standard toolbar order.
Right-to-left applications
The editor automatically reads the computed direction of its Components v2
Shadow host. No component argument is required. Parent application styles such
as the following switch the editor, toolbar, lists, quotes, tables, and table
menus to RTL:
st.markdown(
"""
<style>
body, html {
direction: RTL;
unicode-bidi: bidi-override;
text-align: right;
}
p, div, input, label, h1, h2, h3, h4, h5, h6 {
direction: RTL;
unicode-bidi: bidi-override;
text-align: right;
}
</style>
""",
unsafe_allow_html=True,
)
Use a unique key for each editor:
st.session_state["editor"] # Markdown string
Development
Install uv and Node.js 24, then run:
uv sync --extra dev
npm install --prefix streamlit_lexical_extended/frontend
npm run build --prefix streamlit_lexical_extended/frontend
uv run streamlit run streamlit_lexical_extended/example.py
For a clean, lockfile-based frontend install use npm ci. Frontend watch mode
uses stable development asset names:
npm run dev --prefix streamlit_lexical_extended/frontend
Refresh the Streamlit page after a successful rebuild.
VS Code
Open the repository and select Streamlit: run example in Run and Debug.
It creates/synchronizes .venv, installs frontend dependencies, builds the
component, starts Streamlit, and opens the app.
Use Streamlit: develop frontend for frontend watch mode. Cmd/Ctrl+Shift+B
runs the default quick verification. Additional tasks cover unit tests, E2E
tests, package building, and package metadata checks.
Tests
uv run pytest tests -q
uv run playwright install chromium
uv run pytest streamlit_lexical_extended/tests/e2e -q
The E2E suite covers direct-DOM rendering, callbacks, focus, external updates, multiple editors, dimensions, formatting, themes, tables, and Markdown round-trips.
Publishing
- Update the version in the root
pyproject.toml, componentpyproject.toml, and frontendpackage.json, then updateCHANGELOG.md. - Run the VS Code tasks
Project: verify,Tests: e2e, andPackage: check. - Configure a PyPI Trusted Publisher for this repository, workflow
publish.yml, and environmentpypi. - Create and publish a GitHub release whose tag matches the version, such as
v0.3.0.
The release workflow builds the frontend and Python distributions, validates the metadata, and publishes to PyPI using short-lived OIDC credentials.
See CONTRIBUTING.md for contributor setup and CHANGELOG.md for release history.
License
MIT
Metadata
Release files for streamlit-lexical-extended 0.3.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| streamlit_lexical_extended-0.3.7.tar.gz | 225.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| streamlit_lexical_extended-0.3.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 449.2 kB
Release files / streamlit_lexical_extended-0.3.7.tar.gz
| Download URL | streamlit_lexical_extended-0.3.7.tar.gz |
|---|---|
| Size | 225.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a8374d27e830e2a3a40d5518138127f437df1e3b34a5d8040c6857b0888ea203
|
|
BLAKE2b-256 checksum How to use checksums |
c0f67cafbfa64f8e123d5d6793cbb5a8303e4617039c4e10e22ca9e02a7f8061
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / streamlit_lexical_extended-0.3.7-py3-none-any.whl
| Download URL | streamlit_lexical_extended-0.3.7-py3-none-any.whl |
|---|---|
| Size | 223.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2ea3b1e27b695bf8bbc1ca94acf791c6f084d25c91a1f0a290de70da60025220
|
|
BLAKE2b-256 checksum How to use checksums |
e3fbec3f142cb4da31ee48c4397b5249322651706729539f825a6e85ea947d7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|