Streamlit keyboard shortcuts for your buttons.
Project description
Streamlit Shortcuts
Add keyboard shortcuts to your Streamlit buttons! 🚀
[!NOTE] v1.2.0 - Multiple Shortcuts per Button
- Added support for multiple shortcuts per button/widget (#34)
- Use lists to assign multiple shortcuts:
shortcut_button("Save", ["ctrl+s", "cmd+s"])- Works with both
shortcut_buttonandadd_shortcuts
🎯 Mirrors the native st.button pattern
# Before using native st.button:
if st.button("Save", type="primary", use_container_width=True):
save()
# After (just change function name & add shortcut):
if shortcut_button("Save", "ctrl+s", type="primary", use_container_width=True):
save()
# Multiple shortcuts for one button
if shortcut_button("Previous", ["arrowleft", "h"]):
go_previous()
🎨 Add shortcuts to ANY Streamlit widget
name = st.text_input("Name", key="name_input")
# Add shortcuts to any widget with a key
add_shortcuts(
name_input="ctrl+n", # Focus name field
)
Try the live demo or check out the example code
📦 Installation
pip install streamlit-shortcuts
📖 API Reference
shortcut_button(label, shortcut, **kwargs)
Drop-in replacement for st.button with keyboard shortcut support.
Parameters:
label(str): Button textshortcut(str | list[str]): Single shortcut or list of shortcuts (e.g., "ctrl+s", ["ctrl+s", "cmd+s"])key(str, optional): Unique key for the buttonhint(bool, optional): Show shortcut hint in button label (default: True)**kwargs: All other st.button parameters (help, on_click, args, type, icon, disabled, use_container_width)
Returns: bool - True if clicked
add_shortcuts(**shortcuts)
Add keyboard shortcuts to any Streamlit widgets.
Parameters:
**shortcuts: Keyword arguments where key is the widget's key and value is the shortcut (str | list[str])
Example:
add_shortcuts(
save_btn="ctrl+s",
search_input="ctrl+f",
submit_form="ctrl+enter"
)
# Multiple shortcuts per widget
add_shortcuts(
prev_btn=["arrowleft", "a"],
next_btn=["arrowright", "d"]
)
clear_shortcuts() (New in v1.1)
Remove all keyboard shortcuts and event listeners. Useful for:
- Multi-page apps when switching pages
- Conditionally disabling all shortcuts
- Cleaning up shortcuts in dynamic UIs
Example:
# Disable shortcuts conditionally
if not shortcuts_enabled:
clear_shortcuts()
# Clean up when switching pages
if st.sidebar.button("Go to Settings"):
clear_shortcuts()
st.switch_page("settings")
⌨️ Keyboard Shortcuts
- Modifiers:
ctrl,alt,shift,meta(cmd on Mac) - Common keys:
enter,escape,space,tab,delete - Letters:
a-z - Numbers:
0-9 - Function keys:
f1-f12 - Arrow keys:
arrowleft,arrowright,arrowup,arrowdown
Examples:
ctrl+s- Ctrl + Sctrl+shift+d- Ctrl + Shift + Dalt+enter- Alt + Enterf1- F1 key
💻 Platform Notes
- On macOS,
ctrlworks as expected (not cmd) - For OS-specific shortcuts, use
meta(Windows key on PC, Cmd on Mac) - Some shortcuts may conflict with browser/OS shortcuts
⚠️ Known Issues
Column Alignment
When using shortcut_button inside columns with vertical_alignment, the button may not align properly. This happens because the shortcut injection creates an invisible element that affects layout.
Workaround: Use st.button with add_shortcuts separately:
# ❌ Broken alignment
col1, col2 = st.columns([1, 1], vertical_alignment="bottom")
with col1:
shortcut_button("Save", "ctrl+s")
with col2:
st.selectbox("Options", ["A", "B", "C"])
# ✅ Correct alignment
col1, col2 = st.columns([1, 1], vertical_alignment="bottom")
with col1:
st.button("Save", key="save_btn")
with col2:
st.selectbox("Options", ["A", "B", "C"])
# Add shortcuts after columns
add_shortcuts(save_btn="ctrl+s")
🚨 v1.0 Breaking Changes - complete rewrite
- ⭐ No more API hijacking - v0.x monkey-patched Streamlit's API. Now we respect it:
# v0.x - Hijacked the API, confusing and unpythonic button("Save", "ctrl+s", lambda: save()) # What is this? Not st.button! # v1.0 - Respects Streamlit patterns, works like st.button if shortcut_button("Save", "ctrl+s"): # Familiar pattern! save() # Or use native st.button unchanged if st.button("Save", key="save_btn"): save() add_shortcuts(save_btn="ctrl+s")
- 📉 From 277 lines → 91 lines total (across 5 Python files → 1 file)
- 🗑️ Removed 15 files of configuration bloat
- 📁 No more src/ directory - just one flat file
- ❌ Deleted all tests - meaningless tests that tested nothing, replaced with assertions that actually fail
- 🔥 Modern Python tooling - replaced setup.py/MANIFEST/VERSION with pyproject.toml + uv
- 🧹 Ruff instead of 5 linters - removed flake8, black, isort, mypy, pre-commit hooks
- ⚡ 3 workflows → 1 workflow - simple CI/CD
If upgrading from v0.x:
# Old v0.x API
button("Click me", "ctrl+k", lambda: st.write("Hi"))
# New v1.0 API
if shortcut_button("Click me", "ctrl+k"):
st.write("Hi")
# Or use st.button + add_shortcuts
if st.button("Click me", key="btn"):
st.write("Hi")
add_shortcuts(btn="ctrl+k")
🙏 Credits
Built by the Streamlit community! 🎈
Special thanks to:
- @brunomsantiago and @TomJohnH for the initial concept
- @toolittlecakes for Meta key support
- @quantum-ernest for keyboard hints
- @sammlapp for making shortcuts work with any widget
- @jcbize for improved error handling
- @csipapicsa for identifying a XSS vulnerability
Inspired by Streamlit discussion #1291
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file streamlit_shortcuts-1.2.1.tar.gz.
File metadata
- Download URL: streamlit_shortcuts-1.2.1.tar.gz
- Upload date:
- Size: 111.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c982ace38ce6f887beef2bd3f16c36d645bdcbee010c5585e6963e4615fc8f16
|
|
| MD5 |
28f8cfe38f095ce0eebe1922d93b5032
|
|
| BLAKE2b-256 |
876da3b9befa11528163b96c216f7e4152c7e6df8976bb6ad8a42fb82e8c1778
|
Provenance
The following attestation bundles were made for streamlit_shortcuts-1.2.1.tar.gz:
Publisher:
ci.yml on adriangalilea/streamlit-shortcuts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
streamlit_shortcuts-1.2.1.tar.gz -
Subject digest:
c982ace38ce6f887beef2bd3f16c36d645bdcbee010c5585e6963e4615fc8f16 - Sigstore transparency entry: 337444869
- Sigstore integration time:
-
Permalink:
adriangalilea/streamlit-shortcuts@122eba2bac3a1123a757fe6e54d3b5351032def6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adriangalilea
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@122eba2bac3a1123a757fe6e54d3b5351032def6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file streamlit_shortcuts-1.2.1-py3-none-any.whl.
File metadata
- Download URL: streamlit_shortcuts-1.2.1-py3-none-any.whl
- Upload date:
- Size: 6.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58fa6d375c9f91068bf1400f9870ff3d382b4e4f1dcbf26e05567e4db3547375
|
|
| MD5 |
e5503a7d2650db9978a00ce47a95f38c
|
|
| BLAKE2b-256 |
e0b5a9d1ad477ae69db0b6cef35bf40154ec634a42657ff684a4b3c2024dde36
|
Provenance
The following attestation bundles were made for streamlit_shortcuts-1.2.1-py3-none-any.whl:
Publisher:
ci.yml on adriangalilea/streamlit-shortcuts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
streamlit_shortcuts-1.2.1-py3-none-any.whl -
Subject digest:
58fa6d375c9f91068bf1400f9870ff3d382b4e4f1dcbf26e05567e4db3547375 - Sigstore transparency entry: 337444878
- Sigstore integration time:
-
Permalink:
adriangalilea/streamlit-shortcuts@122eba2bac3a1123a757fe6e54d3b5351032def6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adriangalilea
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@122eba2bac3a1123a757fe6e54d3b5351032def6 -
Trigger Event:
push
-
Statement type: