From 7689b8d07a5db3884287dd30a215af3753dde94c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 23:16:33 +0000 Subject: [PATCH 1/2] fix(internal): omit the demo form dialog trigger when none is given `demo_form_dialog` fell back to `rx.fragment()` when no trigger was passed, so the base-ui `Dialog.Trigger` compiled to `render:(jsx(Fragment, ({})))`. A Fragment cannot accept the props and ref that base-ui forwards through the render prop, which makes React complain in the console. Match the pattern already used by the dialog, drawer, preview card, and collapsible namespaces: render the trigger only when one is provided. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01FcXXMZnAkNtwBj7v2bshXH --- .../blocks/demo_form.py | 4 +-- .../blocks/test_demo_form.py | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 tests/units/reflex_components_internal/blocks/test_demo_form.py diff --git a/packages/reflex-components-internal/src/reflex_components_internal/blocks/demo_form.py b/packages/reflex-components-internal/src/reflex_components_internal/blocks/demo_form.py index cae1362ac7e..93c02952232 100644 --- a/packages/reflex-components-internal/src/reflex_components_internal/blocks/demo_form.py +++ b/packages/reflex-components-internal/src/reflex_components_internal/blocks/demo_form.py @@ -404,11 +404,9 @@ def demo_form_dialog( Returns: A Reflex dialog component containing the demo form """ - if trigger is None: - trigger = rx.fragment() class_name = cn("w-auto", props.pop("class_name", "")) return dialog.root( - dialog.trigger(render_=trigger), + dialog.trigger(render_=trigger) if trigger is not None else None, dialog.portal( dialog.backdrop(), dialog.popup( diff --git a/tests/units/reflex_components_internal/blocks/test_demo_form.py b/tests/units/reflex_components_internal/blocks/test_demo_form.py new file mode 100644 index 00000000000..d085471ac92 --- /dev/null +++ b/tests/units/reflex_components_internal/blocks/test_demo_form.py @@ -0,0 +1,27 @@ +"""Tests for the demo form block.""" + +import re + +from reflex_components_internal.blocks.demo_form import demo_form_dialog + +import reflex as rx + +RENDER_PROP_PATTERN = re.compile(r"render:\(jsx\((\w+)") + + +def test_demo_form_dialog_omits_trigger_when_not_given() -> None: + """A dialog without a trigger renders no trigger instead of an empty fragment.""" + rendered = str(demo_form_dialog()) + + assert "Dialog.Trigger" not in rendered + # A Fragment cannot receive the props and ref that a base-ui render prop + # forwards to it, which makes React complain at runtime. + assert "Fragment" not in RENDER_PROP_PATTERN.findall(rendered) + + +def test_demo_form_dialog_renders_given_trigger() -> None: + """A dialog with a trigger renders it through the trigger's render prop.""" + rendered = str(demo_form_dialog(trigger=rx.el.button("Book a Demo"))) + + assert "Dialog.Trigger" in rendered + assert "Book a Demo" in rendered From 76046529c54489e495b2653451253655dee1cc2c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 23:53:11 +0000 Subject: [PATCH 2/2] test(internal): assert the demo form trigger with a trigger-only label `Book a Demo` is also the dialog's own heading, so the assertion passed even if the trigger's content were dropped. Use a label the dialog body never renders, and assert it is absent without a trigger so the test keeps guarding against a collision. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01FcXXMZnAkNtwBj7v2bshXH --- .../reflex_components_internal/blocks/test_demo_form.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/units/reflex_components_internal/blocks/test_demo_form.py b/tests/units/reflex_components_internal/blocks/test_demo_form.py index d085471ac92..4d8e058ad7f 100644 --- a/tests/units/reflex_components_internal/blocks/test_demo_form.py +++ b/tests/units/reflex_components_internal/blocks/test_demo_form.py @@ -7,6 +7,7 @@ import reflex as rx RENDER_PROP_PATTERN = re.compile(r"render:\(jsx\((\w+)") +TRIGGER_LABEL = "Show me the demo form" def test_demo_form_dialog_omits_trigger_when_not_given() -> None: @@ -21,7 +22,11 @@ def test_demo_form_dialog_omits_trigger_when_not_given() -> None: def test_demo_form_dialog_renders_given_trigger() -> None: """A dialog with a trigger renders it through the trigger's render prop.""" - rendered = str(demo_form_dialog(trigger=rx.el.button("Book a Demo"))) + # The dialog body has fixed copy of its own, so the label must be one that + # only the trigger can contribute. + assert TRIGGER_LABEL not in str(demo_form_dialog()) + + rendered = str(demo_form_dialog(trigger=rx.el.button(TRIGGER_LABEL))) assert "Dialog.Trigger" in rendered - assert "Book a Demo" in rendered + assert TRIGGER_LABEL in rendered