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.6

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.6
File Size Uploaded
streamlit_lexical_extended-0.3.6.tar.gz 225.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for streamlit-lexical-extended 0.3.6
File Interpreter ABI Platform
streamlit_lexical_extended-0.3.6-py3-none-any.whl Python 3 none any Details

Total release size: 449.1 kB

Release files / streamlit_lexical_extended-0.3.6.tar.gz

Download URL streamlit_lexical_extended-0.3.6.tar.gz
Size 225.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1ed16bc70f73340eaf65fe88d9701cb099d52d16161ae82dbc2555de61b93071
BLAKE2b-256 checksum
How to use checksums
54ecd0e6ccde578d86cd079d437608175df44fe729bdfee6f266c52d33d0d903
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.6-py3-none-any.whl

Download URL streamlit_lexical_extended-0.3.6-py3-none-any.whl
Size 223.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1c072912b7769cce9bbe63fc32930144d0cd783124c14067a4279894c0a8b08b
BLAKE2b-256 checksum
How to use checksums
df7eb3b4271b14d60c77c5a662beeff93d77d702e7420739f6fa03c7c3526c3f
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

0.3.7

2 release files

This release

0.3.6 This release

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