Skip to content

Instantly share code, notes, and snippets.

@hansthen
Created June 15, 2025 21:10
Show Gist options
  • Save hansthen/bdfc03f45ce399d96e881731970ef63f to your computer and use it in GitHub Desktop.
Save hansthen/bdfc03f45ce399d96e881731970ef63f to your computer and use it in GitHub Desktop.
Keyboard shortcuts in streamlit
def shortcuts(**buttons):
key = str(uuid.uuid4())
styl = f"""
<style>
.st-key-{key} {{
display: none;
}}
</style>
"""
st.markdown(styl, unsafe_allow_html=True)
with st.container(key=key):
buttons_map = {}
for title, (code, callback) in buttons.items():
st.button(title, on_click=callback)
buttons_map[code] = title
st.write(st.session_state.count)
template = Template("""
<script>
const doc = window.parent.document;
buttons = Array.from(doc.querySelectorAll('button[kind=secondary]'));
button_map = {}
{% for key, label in buttons.items() %}
button_map['{{key}}'] = buttons.find(el => el.innerText === '{{label}}');
{% endfor %}
doc.addEventListener('keydown', function(e) {
for (const [shortcut, el] of Object.entries(button_map)) {
const parts = shortcut.toLowerCase().split('+');
const hasCtrl = parts.includes('ctrl');
const hasAlt = parts.includes('alt');
const hasShift = parts.includes('shift');
const hasMeta = parts.includes('meta') || parts.includes('cmd');
const mainKey = parts.find(p => !['ctrl', 'alt', 'shift', 'meta', 'cmd'].includes(p));
if (hasCtrl === e.ctrlKey &&
hasAlt === e.altKey &&
hasShift === e.shiftKey &&
hasMeta === e.metaKey &&
e.key.toLowerCase() === mainKey) {
e.preventDefault();
el.click();
el.focus();
break;
}
}
});
</script>
""")
html = template.render(buttons=
buttons_map
)
components.html(
html,
height=0,
width=0,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment