Skip to content

Add anywidget extra for rendering anywidget-compatible widgets - #314

Open
lukasmasuch wants to merge 5 commits into
mainfrom
lukasmasuch/anywidget-extra
Open

Add anywidget extra for rendering anywidget-compatible widgets#314
lukasmasuch wants to merge 5 commits into
mainfrom
lukasmasuch/anywidget-extra

Conversation

@lukasmasuch

Copy link
Copy Markdown
Collaborator

Summary

Adds a new anywidget extra that enables rendering any anywidget-compatible widget in Streamlit with full bidirectional interactivity. This uses a React-based Custom Components v2 implementation for stable state management.

Features:

  • Support for inline ESM, file-based ESM, and pre-bundled widgets (e.g., drawdata)
  • Bidirectional trait synchronization between Python and JavaScript
  • model.send() support for custom messaging
  • Streamlit theming integration via CSS variables

Test plan

  • Run uv run streamlit run src/streamlit_extras/anywidget/example_app.py
  • Test counter widget: clicking increments count, "Reset from Python" resets it
  • Test text input: typing updates Python state in real-time
  • Test external widget (drawdata): drawing points syncs to Python

Introduces a new `anywidget` extra that wraps any anywidget-compatible widget
and renders it in Streamlit with full bidirectional interactivity. Uses a
React-based CC v2 implementation for stable state management.

Features:
- Support for inline ESM, file-based ESM, and pre-bundled widgets
- Bidirectional trait synchronization (Python ↔ JavaScript)
- model.send() support for custom messaging
- Streamlit theming integration via CSS variables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 25, 2026 22:29
@netlify

netlify Bot commented Mar 25, 2026

Copy link
Copy Markdown

Deploy Preview for streamlit-extras-docs ready!

Name Link
🔨 Latest commit a42a600
🔍 Latest deploy log https://app.netlify.com/projects/streamlit-extras-docs/deploys/69ca36177b71b9000866286d
😎 Deploy Preview https://deploy-preview-314--streamlit-extras-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new anywidget optional extra to streamlit-extras, including a Streamlit Custom Component v2 (React) frontend and a Python wrapper to render anywidget-compatible widgets with bidirectional state sync.

Changes:

  • Add anywidget as an installable optional dependency extra (pip install streamlit-extras[anywidget]).
  • Introduce a new CCv2 React component (anywidget/frontend) plus the Python integration (streamlit_extras.anywidget).
  • Add a demo app showcasing inline widgets and an external anywidget (drawdata).

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
uv.lock Locks new Python deps for the anywidget extra and its transitive requirements.
pyproject.toml Declares the anywidget optional dependency group and updates Ruff per-file ignores.
src/streamlit_extras/pyproject.toml Registers the new CCv2 component asset directory for anywidget.
src/streamlit_extras/anywidget/__init__.py Core Python API (anywidget(...)) and trait/message synchronization logic.
src/streamlit_extras/anywidget/example_app.py End-to-end demo app for interactive validation.
src/streamlit_extras/anywidget/frontend/package.json Frontend build/tooling dependencies and scripts (Vite + React).
src/streamlit_extras/anywidget/frontend/package-lock.json Locked frontend dependency graph for reproducible builds.
src/streamlit_extras/anywidget/frontend/tsconfig.json TypeScript configuration for the React component.
src/streamlit_extras/anywidget/frontend/vite.config.ts Vite library-mode build config producing index-*.js bundles.
src/streamlit_extras/anywidget/frontend/src/index.tsx CCv2 renderer entrypoint mounting the React root per component instance.
src/streamlit_extras/anywidget/frontend/src/AnywidgetContainer.tsx Runtime widget loader (blob ESM import), model adapter, trait + message sync.
src/streamlit_extras/AGENTS.md Documents the new extra in the repo’s implementation guide table.
Files not reviewed (1)
  • src/streamlit_extras/anywidget/frontend/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/streamlit_extras/anywidget/__init__.py
Comment thread src/streamlit_extras/anywidget/__init__.py
Comment thread src/streamlit_extras/anywidget/__init__.py
Comment thread src/streamlit_extras/anywidget/frontend/src/AnywidgetContainer.tsx
Comment thread src/streamlit_extras/anywidget/frontend/src/AnywidgetContainer.tsx
lukasmasuch and others added 2 commits March 25, 2026 23:41
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lukasmasuch

Copy link
Copy Markdown
Collaborator Author

Addressed all review feedback in commit 3447606:

Comment #1 (Accessibility): Added role="button", tabindex="0", aria-label for clickable avatars, and keyboard activation for Enter/Space keys.

Comment #2 (Click state): Replaced boolean clicked with click_count that increments on each click, ensuring every click produces a distinct state change.

Comment #3 (Return value): Now tracking click count changes in st.session_state to properly detect clicks on the current run by comparing previous vs current count.

Comment #4 (Validate on_click): Added validation that raises StreamlitAPIException if on_click is not "ignore", "rerun", or a callable.

Comment #5 (Validate height): Added validation that raises StreamlitAPIException if height < 1.

@arnaudmiribel

arnaudmiribel commented Mar 26, 2026

Copy link
Copy Markdown
Owner

Wow, the drawer example is pretty sick.

  • One thing though: the draw container is scrollable; not full. Is that just because you set fixed height? I tried dropping the height but it still feels scrollable
  • Can we make draw example the first one? So it's defaulted
  • Can we add the needed dependencies to the gallery app? I don't love that we show an extra but then the demo just fails because of dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants