Streamlit vanilla components
Lightweight Streamlit components v2 in plain HTML, CSS and JavaScript. No npm packages, no build step. Each component copies its native Streamlit look and follows the active theme.
Built using GitHub Copilot as an AI coding agent, with manual oversight, design and testing throughout.
from streamlit_vanilla_components import st_live_searchbox, stateful_button
Run the demo with streamlit run example.py.
Installation
pip install streamlit-vanilla-components
Or install straight from GitHub:
pip install "git+https://github.com/lukehorton1/streamlit-vanilla-components.git"
Requires Python 3.10+ and Streamlit 1.57+.
Components
st_live_searchbox
A search box whose dropdown is filled by your Python function as the user types. Returns the picked option as a string.
def search_places(term: str) -> list[str]:
return db.query("SELECT label FROM places WHERE label ILIKE %s LIMIT 300", f"%{term}%")
choice = st_live_searchbox(search_places, placeholder="Search a place...", rank=True, max_results=50)
Parameters
| Parameter | Description |
|---|---|
search_fn (callable) |
Receives the typed text and returns a list of options. Required. |
placeholder (str) |
Placeholder text. Default "Type to search...". |
key (str) |
Widget key. Default "live_search". |
on_change (callable or None) |
Runs when the typed text changes. |
on_submit (callable or None) |
Runs when an option is picked. |
args (tuple or None) |
Passed to on_change and on_submit. |
kwargs (dict or None) |
Passed to on_change and on_submit. |
debounce (int) |
Milliseconds to wait after typing stops before searching. Default 250. |
default (str or None) |
Returned until something is picked. Default None. |
label (str or None) |
Label above the box. |
label_visibility (str) |
"visible", "hidden" or "collapsed". Default "visible". |
help (str or None) |
Tooltip next to the label. |
disabled (bool) |
Disables the box. Default False. |
min_chars (int) |
Characters typed before search_fn runs. Default 1. |
max_results (int or None) |
Maximum options shown, applied after ranking. Default None. |
rank (bool) |
Sorts options by match quality (exact, starts with, word starts with, contains). Default False. |
clear_on_submit (bool) |
Empties the box after a pick. Default False. |
width (str or int) |
"stretch" or a pixel width. Default "stretch". |
Returns (str or None): the picked option, or default.
See also
- Typing again after a pick replaces it with the new text.
- Ranking only sees what
search_fnreturns, so return more candidates thanmax_results.
stateful_button
A st.button look-alike that disables itself on click, shows a spinner in place of its icon while your code runs, then a tick on success.
with stateful_button("Submit", type="primary") as clicked:
if clicked:
save_records()
st.success("Saved!")
# or, for a single function call
stateful_button("Run job", on_click=run_job, args=("Job 1",))
Parameters
Same as st.button, plus icon_position and wrap.
| Parameter | Description |
|---|---|
label (str) |
Button text. Plain text, no Markdown. Required. |
key (str or None) |
Widget key. Derived from the other arguments if omitted. |
help (str or None) |
Tooltip. |
on_click (callable or None) |
Work to run. The button stays busy until it finishes. |
args (tuple or None) |
Passed to on_click. |
kwargs (dict or None) |
Passed to on_click. |
type (str) |
"primary", "secondary" or "tertiary". Default "secondary". |
icon (str or None) |
Emoji or :material/name:. |
icon_position (str) |
"left" or "right". Default "left". |
disabled (bool) |
Disables the button. Default False. |
width (str or int) |
"content", "stretch" or a pixel width. Default "content". |
shortcut (str or None) |
Keyboard shortcut. |
wrap (bool or None) |
Whether the label may wrap. |
Returns (StatefulButton): truthy on the run it was clicked. Works as a context manager, and .release(success=True) ends the busy state early.
See also
- Use either the
withform oron_click. Without either, the spinner never stops. - Errors in the
withblock or inon_clickre-enable the button, then raise.
Metadata
Release files for streamlit-vanilla-components 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| streamlit_vanilla_components-0.1.0.tar.gz | 15.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| streamlit_vanilla_components-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.5 kB
Release files / streamlit_vanilla_components-0.1.0.tar.gz
| Download URL | streamlit_vanilla_components-0.1.0.tar.gz |
|---|---|
| Size | 15.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
89084c7d66ce17b0e910bb8fdb8cf8333fc92283ce68e2890ede6403eedceb0e
|
|
BLAKE2b-256 checksum How to use checksums |
bda2fec4e68bee711bcebd712d4b9bccc4912d762214fc065d1f38440e86e60b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / streamlit_vanilla_components-0.1.0-py3-none-any.whl
| Download URL | streamlit_vanilla_components-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cd17147af34180af974fb483a5f58781fabe64c08c644557f56d91d8525649c3
|
|
BLAKE2b-256 checksum How to use checksums |
d4b3f9543b31dbeef5ccd55f0d5b081a8d8c59f7b7c9e1ddbec55545b20e490e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for streamlit-vanilla-components 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.