From 52f7fb66afe9995065467eeaecc1239518b78e9e Mon Sep 17 00:00:00 2001 From: Casey Riebe Date: Wed, 2 Jul 2025 13:55:01 -0500 Subject: [PATCH 1/3] If we have `set_focus()` we need `blur_focus()`. --- reflex/.templates/web/utils/state.js | 14 ++++++++++++++ reflex/event.py | 17 +++++++++++++++++ tests/units/test_event.py | 15 +++++++++------ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index 2aa745b7175..b16766b3355 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -295,6 +295,20 @@ export const applyEvent = async (event, socket, navigate, params) => { return false; } + if (event.name == "_blur_focus") { + const ref = + event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref; + const current = ref?.current; + if (current === undefined || current?.focus === undefined) { + console.error( + `No element found for ref ${event.payload.ref} in _blur_focus`, + ); + } else { + current.blur(); + } + return false; + } + if (event.name == "_set_value") { const ref = event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref; diff --git a/reflex/event.py b/reflex/event.py index dd9cd1aeab3..f0dc035c282 100644 --- a/reflex/event.py +++ b/reflex/event.py @@ -1025,6 +1025,22 @@ def set_focus(ref: str) -> EventSpec: ) +def blur_focus(ref: str) -> EventSpec: + """Blur focus of specified ref. + + Args: + ref: The ref. + + Returns: + An event to blur focus on the ref + """ + return server_side( + "_blur_focus", + get_fn_signature(blur_focus), + ref=LiteralVar.create(format.format_ref(ref)), + ) + + def scroll_to(elem_id: str, align_to_top: bool | Var[bool] = True) -> EventSpec: """Select the id of a html element for scrolling into view. @@ -2293,6 +2309,7 @@ def wrapper( back = staticmethod(back) window_alert = staticmethod(window_alert) set_focus = staticmethod(set_focus) + blur_focus = staticmethod(blur_focus) scroll_to = staticmethod(scroll_to) set_value = staticmethod(set_value) remove_cookie = staticmethod(remove_cookie) diff --git a/tests/units/test_event.py b/tests/units/test_event.py index 4732957b8e3..38d739855dc 100644 --- a/tests/units/test_event.py +++ b/tests/units/test_event.py @@ -262,16 +262,19 @@ def test_event_window_alert(): ) -def test_set_focus(): +@pytest.mark.parametrize( + ("func", "qualname"), [("set_focus", "_set_focus"), ("blur_focus", "_blur_focus")] +) +def test_focus(func: str, qualname: str): """Test the event set focus function.""" - spec = event.set_focus("input1") + spec = getattr(event, func)("input1") assert isinstance(spec, EventSpec) - assert spec.handler.fn.__qualname__ == "_set_focus" + assert spec.handler.fn.__qualname__ == qualname assert spec.args[0][0].equals(Var(_js_expr="ref")) assert spec.args[0][1].equals(LiteralVar.create("ref_input1")) - assert format.format_event(spec) == 'Event("_set_focus", {ref:"ref_input1"})' - spec = event.set_focus("input1") - assert format.format_event(spec) == 'Event("_set_focus", {ref:"ref_input1"})' + assert format.format_event(spec) == f'Event("{qualname}", {{ref:"ref_input1"}})' + spec = getattr(event, func)("input1") + assert format.format_event(spec) == f'Event("{qualname}", {{ref:"ref_input1"}})' def test_set_value(): From 16636196842be7e9e3293d457a0d1fd0628cb314 Mon Sep 17 00:00:00 2001 From: Casey Date: Wed, 2 Jul 2025 14:02:57 -0500 Subject: [PATCH 2/3] Update reflex/.templates/web/utils/state.js Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- reflex/.templates/web/utils/state.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index b16766b3355..f476c33b6f4 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -299,7 +299,7 @@ export const applyEvent = async (event, socket, navigate, params) => { const ref = event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref; const current = ref?.current; - if (current === undefined || current?.focus === undefined) { + if (current === undefined || current?.blur === undefined) { console.error( `No element found for ref ${event.payload.ref} in _blur_focus`, ); From 98a4c1e19a84a2a5d03e5bf7fb96f327bf2e8551 Mon Sep 17 00:00:00 2001 From: Casey Riebe Date: Wed, 2 Jul 2025 15:18:03 -0500 Subject: [PATCH 3/3] Making darglint happy --- tests/units/test_event.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/units/test_event.py b/tests/units/test_event.py index 38d739855dc..3f101a4d51f 100644 --- a/tests/units/test_event.py +++ b/tests/units/test_event.py @@ -266,7 +266,12 @@ def test_event_window_alert(): ("func", "qualname"), [("set_focus", "_set_focus"), ("blur_focus", "_blur_focus")] ) def test_focus(func: str, qualname: str): - """Test the event set focus function.""" + """Test the event set focus function. + + Args: + func: The event function name. + qualname: The sig qual name passed to JS. + """ spec = getattr(event, func)("input1") assert isinstance(spec, EventSpec) assert spec.handler.fn.__qualname__ == qualname