Skip to main content

streamlit-lexical-extended

PyPI Python CI

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=None leaves the current editor content untouched; value="" clears it. Any other string replaces the current document.
  • height=int uses a fixed height with internal scrolling. height=None grows with content and respects min_height.
  • width accepts "stretch", "content", or a positive pixel integer.
  • on_change receives 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

  1. Update the version in the root pyproject.toml, component pyproject.toml, and frontend package.json, then update CHANGELOG.md.
  2. Run the VS Code tasks Project: verify, Tests: e2e, and Package: check.
  3. Configure a PyPI Trusted Publisher for this repository, workflow publish.yml, and environment pypi.
  4. 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)

Source distribution for streamlit-lexical-extended 0.3.7
File Size Uploaded
streamlit_lexical_extended-0.3.7.tar.gz 225.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for streamlit-lexical-extended 0.3.7
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

0.3.12

2 release files

0.3.11

2 release files

0.3.10

2 release files

0.3.8

2 release files

This release

0.3.7 This release

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page