diff --git a/README.md b/README.md index a255fb8..c8c7f5a 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,8 @@ To further customize the styling of the searchbox, you can override the default "clear":{ "width":20, "height":20, - "icon":"cross" + "icon":"cross", + "clearable":"always" }, "dropdown":{ "rotate":true, diff --git a/setup.py b/setup.py index 1366f16..f1e68b8 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setuptools.setup( name="streamlit-searchbox", - version="0.1.16", + version="0.1.17", author="m-wrzr", description="Autocomplete Searchbox", long_description="Streamlit searchbox that dynamically updates " diff --git a/streamlit_searchbox/__init__.py b/streamlit_searchbox/__init__.py index fa6b224..aaa5a98 100644 --- a/streamlit_searchbox/__init__.py +++ b/streamlit_searchbox/__init__.py @@ -58,6 +58,14 @@ def inner_function(*args, **kwargs): return inner_function +def _rerun(rerun_scope: Literal["app", "fragment"]) -> None: + # only pass scope if the version is >= 1.37 + if st.__version__ >= "1.37": + rerun(scope=rerun_scope) # type: ignore + else: + rerun() + + def _list_to_options_py(options: list[Any] | list[tuple[str, Any]]) -> list[Any]: """ unpack search options for proper python return types @@ -113,11 +121,7 @@ def _process_search( if execution_time_ms < min_execution_time: time.sleep((min_execution_time - execution_time_ms) / 1000) - # only pass scope if the version is >= 1.37 - if st.__version__ >= "1.37": - rerun(scope=rerun_scope) # type: ignore - else: - rerun() + _rerun(rerun_scope) def _set_defaults( @@ -146,6 +150,8 @@ def _set_defaults( { # determines which icon is used for the clear button "icon": Literal["circle-unfilled", "circle-filled", "cross"], + # determines when the clear button is shown + "clearable": Literal["always", "never", "after-submit"], # further css styles for the clear button "width": int, "height": int, @@ -192,6 +198,7 @@ def st_searchbox( placeholder: str = "Search ...", label: str | None = None, default: Any = None, + *, default_use_searchterm: bool = False, default_options: List[Any] | None = None, clear_on_submit: bool = False, @@ -224,7 +231,7 @@ def st_searchbox( default_options (List[any], optional): Initial list of options. Defaults to None. clear_on_submit (bool, optional): - Remove suggestions on select. Defaults to False. + Remove suggestions on select and reset default_options. Defaults to False. rerun_on_update (bool, optional): Rerun the streamlit app after each search. Defaults to True. edit_after_submit ("disabled", "current", "option", "concat", optional): @@ -308,6 +315,11 @@ def st_searchbox( if "options_py" in st.session_state[key] else value ) + + if clear_on_submit: + _set_defaults(key, st.session_state[key]["result"], default_options) + _rerun(rerun_scope) + return st.session_state[key]["result"] if interaction == "reset": @@ -317,11 +329,7 @@ def st_searchbox( reset_function() if rerun_on_update: - # only pass scope if the version is >= 1.37 - if st.__version__ >= "1.37": - rerun(scope=rerun_scope) # type: ignore - else: - rerun() + _rerun(rerun_scope) return default diff --git a/streamlit_searchbox/frontend/package-lock.json b/streamlit_searchbox/frontend/package-lock.json index c8bd9cd..6a09e3a 100644 --- a/streamlit_searchbox/frontend/package-lock.json +++ b/streamlit_searchbox/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "streamlit_searchbox", - "version": "0.1.16", + "version": "0.1.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "streamlit_searchbox", - "version": "0.1.16", + "version": "0.1.17", "dependencies": { "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/streamlit_searchbox/frontend/package.json b/streamlit_searchbox/frontend/package.json index d89d0c1..18abcbf 100644 --- a/streamlit_searchbox/frontend/package.json +++ b/streamlit_searchbox/frontend/package.json @@ -1,6 +1,6 @@ { "name": "streamlit_searchbox", - "version": "0.1.16", + "version": "0.1.17", "private": true, "dependencies": { "react": "^16.13.1", diff --git a/streamlit_searchbox/frontend/src/Searchbox.tsx b/streamlit_searchbox/frontend/src/Searchbox.tsx index 9403a85..6038ae8 100644 --- a/streamlit_searchbox/frontend/src/Searchbox.tsx +++ b/streamlit_searchbox/frontend/src/Searchbox.tsx @@ -139,6 +139,9 @@ class Searchbox extends StreamlitComponentBase { } }; + // option when the clear button is shown + const clearable = this.props.args.style_overrides?.clear?.clearable; + return (
{this.props.args.label && ( @@ -149,9 +152,19 @@ class Searchbox extends StreamlitComponentBase { // showing the disabled react-select leads to the component // not showing the inputValue but just an empty input field // we therefore need to re-render the component if we want to keep the focus - value={this.state.option} + value={ + this.state.option === null && + this.state.inputValue && + clearable === "always" + ? { + value: null, + label: null, + } + : this.state.option + } + // value={this.state.option} inputValue={editableAfterSubmit ? this.state.inputValue : undefined} - isClearable={true} + isClearable={clearable !== "never"} isSearchable={true} styles={this.style.select} options={this.props.args.options}