diff --git a/src/js/packages/@reactpy/client/src/vdom.tsx b/src/js/packages/@reactpy/client/src/vdom.tsx index e57ea4594..c7d423a04 100644 --- a/src/js/packages/@reactpy/client/src/vdom.tsx +++ b/src/js/packages/@reactpy/client/src/vdom.tsx @@ -93,7 +93,7 @@ function createImportSourceElement(props: { } } } else { - type = props.model.tagName; + type = props.model.tagName === "" ? Fragment : props.model.tagName; } return props.binding.create( type, diff --git a/tests/test_reactjs/js_fixtures/nest-custom-under-web.js b/tests/test_reactjs/js_fixtures/nest-custom-under-web.js new file mode 100644 index 000000000..027c9a2b7 --- /dev/null +++ b/tests/test_reactjs/js_fixtures/nest-custom-under-web.js @@ -0,0 +1,14 @@ +import React from "https://esm.sh/react@19.0" +import ReactDOM from "https://esm.sh/react-dom@19.0/client" +import {Container} from "https://esm.sh/react-bootstrap@2.10.10/?deps=react@19.0,react-dom@19.0,react-is@19.0&exports=Container"; +export {Container}; + +export function bind(node, config) { + const root = ReactDOM.createRoot(node); + return { + create: (type, props, children) => + React.createElement(type, props, children), + render: (element) => root.render(element, node), + unmount: () => root.unmount() + }; +} \ No newline at end of file diff --git a/tests/test_web/js_fixtures/nest-custom-under-web.js b/tests/test_web/js_fixtures/nest-custom-under-web.js new file mode 100644 index 000000000..027c9a2b7 --- /dev/null +++ b/tests/test_web/js_fixtures/nest-custom-under-web.js @@ -0,0 +1,14 @@ +import React from "https://esm.sh/react@19.0" +import ReactDOM from "https://esm.sh/react-dom@19.0/client" +import {Container} from "https://esm.sh/react-bootstrap@2.10.10/?deps=react@19.0,react-dom@19.0,react-is@19.0&exports=Container"; +export {Container}; + +export function bind(node, config) { + const root = ReactDOM.createRoot(node); + return { + create: (type, props, children) => + React.createElement(type, props, children), + render: (element) => root.render(element, node), + unmount: () => root.unmount() + }; +} \ No newline at end of file diff --git a/tests/test_web/test_module.py b/tests/test_web/test_module.py index cddcc86dc..c8ec22db7 100644 --- a/tests/test_web/test_module.py +++ b/tests/test_web/test_module.py @@ -563,3 +563,32 @@ async def test_module_without_bind(display: DisplayFixture): "#my-generic-component", state="attached" ) assert await element.inner_text() == "Hello World" + +async def test_nest_custom_component_under_web_component(display: DisplayFixture): + """ + Fix https://github.com/reactive-python/reactpy/discussions/1323 + + Custom components (i.e those wrapped in the component decorator) were not able to + be nested under web components. + + """ + module = reactpy.reactjs.file_to_module( + "nest-custom-under-web", JS_FIXTURES_DIR / "nest-custom-under-web.js" + ) + Container = reactpy.reactjs.module_to_vdom(module, "Container") + + @reactpy.component + def CustomComponent(): + return reactpy.html.div( + reactpy.html.h1({"id": "my-header"}, "Header 1") + ) + await display.show( + lambda: Container( + CustomComponent() + ) + ) + + element = await display.page.wait_for_selector( + "#my-header", state="attached" + ) + assert await element.inner_text() == "Header 1"