From 1e4511f7764164e661aff912ab3f1d10c91324f5 Mon Sep 17 00:00:00 2001 From: Zachary Blackwood Date: Mon, 29 Aug 2022 11:04:43 -0400 Subject: [PATCH] Add debounce --- README.md | 9 ++++++++- setup.py | 2 +- src/__init__.py | 20 ++++++++++++++++++++ src/frontend/src/index.tsx | 10 +++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aeb29bd..73c1622 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,13 @@ from st_keyup import st_keyup value = st_keyup("Enter a value") -# Notice that value updates with every keyup +# Notice that value updates after every key press st.write(value) + +# If you want to set a default value, you can pass one +with_default = st_keyup("Enter a value", value="Example") + +# If you want to limit how often the value gets updated, pass `debounce` value, which +# will force the value to only update after that many milliseconds have passed +with_debounce = st_keyup("Enter a value", debounce=500) ``` diff --git a/setup.py b/setup.py index fad4ee0..86cc03c 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setuptools.setup( name="streamlit-keyup", - version="0.1.3", + version="0.1.4", author="Zachary Blackwood", author_email="zachary@streamlit.io", description="Text input that renders on keyup", diff --git a/src/__init__.py b/src/__init__.py index d2a8e05..e7d41d9 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -22,11 +22,23 @@ def st_keyup( label: str, value: str = "", key: Optional[str] = None, + debounce: int = 0, ): + """ + Generate a text input that renders on keyup, debouncing the input by the + specified amount of milliseconds. + + Debounce means that it will wait at least the specified amount of milliseconds + before updating the value. This is useful for preventing excessive updates + when the user is typing. Since the input updating will cause the app to rerun, + if you are having performance issues, you should consider setting a debounce + value. + """ component_value = _component_func( label=label, value=value, key=key, + debounce=debounce, default="", ) @@ -34,14 +46,22 @@ def st_keyup( def main(): + st.write("## Default keyup input") value = st_keyup("Enter a value") st.write(value) + "## Keyup input with default value" value = st_keyup("Enter a second value", value="Hello World") st.write(value) + "## Keyup input with 500 millesecond debounce" + value = st_keyup("Enter a second value", debounce=500) + + st.write(value) + + "## Standard text input for comparison" value = st.text_input("Enter a value") st.write(value) diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 584e156..b855887 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -1,4 +1,5 @@ import { Streamlit, RenderData } from "streamlit-component-lib" +import { debounce } from "underscore" declare global { interface Window { @@ -22,6 +23,7 @@ function onRender(event: Event): void { const label: string = data.args["label"] const value: string = data.args["value"] + const debounce_time: number = data.args["debounce"] const input = document.getElementsByTagName("input")[0] as HTMLInputElement @@ -37,7 +39,13 @@ function onRender(event: Event): void { input.value = value } - input.onkeyup = onKeyUp + if (debounce_time > 0) { + input.onkeyup = debounce(onKeyUp, debounce_time) + } + else { + input.onkeyup = onKeyUp + } + window.rendered = true } }