From 90f11cc5e142973dbea2e11ece3740d6a89c8830 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 14:32:07 -0700 Subject: [PATCH 01/16] don't use jsx syntax --- .../.templates/jinja/web/pages/_app.js.jinja2 | 20 ++-- .../jinja/web/pages/_document.js.jinja2 | 2 +- .../jinja/web/pages/index.js.jinja2 | 2 +- .../web/pages/stateful_component.js.jinja2 | 2 +- .../jinja/web/pages/utils.js.jinja2 | 105 ++++++------------ .../jinja/web/utils/context.js.jinja2 | 24 +--- 6 files changed, 52 insertions(+), 103 deletions(-) diff --git a/reflex/.templates/jinja/web/pages/_app.js.jinja2 b/reflex/.templates/jinja/web/pages/_app.js.jinja2 index 5a10be30696..1b299d395d7 100644 --- a/reflex/.templates/jinja/web/pages/_app.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/_app.js.jinja2 @@ -22,7 +22,7 @@ function AppWrap({children}) { {{ renderHooks(hooks) }} return ( - {{utils.render(render, indent_width=0)}} + {{utils.render(render)}} ) } @@ -37,15 +37,15 @@ export default function MyApp({ Component, pageProps }) { window["__reflex"] = windowImports; }, []); return ( - - - - - - - - - + jsx(ThemeProvider, {defaultTheme:defaultColorMode,attribute:"class"}, + jsx(StateProvider, {}, + jsx(EventLoopProvider, {}, + jsx(AppWrap, {}, + jsx(Component, pageProps) + ) + ) + ) + ) ); } diff --git a/reflex/.templates/jinja/web/pages/_document.js.jinja2 b/reflex/.templates/jinja/web/pages/_document.js.jinja2 index 266c0d5a543..b17731ee0fe 100644 --- a/reflex/.templates/jinja/web/pages/_document.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/_document.js.jinja2 @@ -3,7 +3,7 @@ {% block export %} export default function Document() { return ( - {{utils.render(document, indent_width=0)}} + {{utils.render(document)}} ) } {% endblock %} diff --git a/reflex/.templates/jinja/web/pages/index.js.jinja2 b/reflex/.templates/jinja/web/pages/index.js.jinja2 index 5551ad5fcc2..98a2aefd6df 100644 --- a/reflex/.templates/jinja/web/pages/index.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/index.js.jinja2 @@ -12,7 +12,7 @@ export default function Component() { {{ renderHooks(hooks)}} return ( - {{utils.render(render, indent_width=0)}} + {{utils.render(render)}} ) } {% endblock %} diff --git a/reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 b/reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 index 208a5755f94..f170ce92057 100644 --- a/reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 @@ -6,6 +6,6 @@ export function {{tag_name}} () { {{ renderHooksWithMemo(all_hooks, memo_trigger_hooks) }} return ( - {{utils.render(component.render(), indent_width=0)}} + {{utils.render(component.render())}} ) } diff --git a/reflex/.templates/jinja/web/pages/utils.js.jinja2 b/reflex/.templates/jinja/web/pages/utils.js.jinja2 index c883dadcb62..ce96f1d4d27 100644 --- a/reflex/.templates/jinja/web/pages/utils.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/utils.js.jinja2 @@ -1,46 +1,35 @@ {# Rendering components recursively. #} {# Args: #} {# component: component dictionary #} -{# indent_width: indent width #} -{% macro render(component, indent_width=0) %} -{% filter indent(width=indent_width) %} - {%- if component is not mapping %} - {{- component }} - {%- elif "iterable" in component %} - {{- render_iterable_tag(component) }} - {%- elif component.name == "match"%} - {{- render_match_tag(component) }} - {%- elif "cond" in component %} - {{- render_condition_tag(component) }} - {%- elif component.children|length %} - {{- render_tag(component) }} - {%- else %} - {{- render_self_close_tag(component) }} - {%- endif %} -{% endfilter %} +{% macro render(component) %} +{%- if component is not mapping %}{{ component }} +{%- elif "iterable" in component %}{{ render_iterable_tag(component) }} +{%- elif component.name == "match"%}{{ render_match_tag(component) }} +{%- elif "cond" in component %}{{ render_condition_tag(component) }} +{%- elif component.children|length %}{{ render_tag(component) }} +{%- else %}{{ render_self_close_tag(component) }} +{%- endif %} {% endmacro %} {# Rendering self close tag. #} {# Args: #} {# component: component dictionary #} {% macro render_self_close_tag(component) %} -{%- if component.name|length %} -<{{ component.name }} {{- render_props(component.props) }}{% if component.autofocus %} ref={focusRef} {% endif %}/> -{%- else %} - {{- component.contents }} -{%- endif %} +{% if component.name|length %} +jsx({{ component.name }},{{ render_props(component.props) }},{{ component.contents }}) +{% elif component.contents|length -%}{{ component.contents }} +{% else %}"" +{% endif %} {% endmacro %} {# Rendering close tag with args and props. #} {# Args: #} {# component: component dictionary #} {% macro render_tag(component) %} -<{{component.name}} {{- render_props(component.props) }}> -{{ component.contents }} -{% for child in component.children %} -{{ render(child) }} -{% endfor %} - +jsx({% if component.name|length %}{{ component.name }}{% else %}Fragment{% endif %}, +{{ render_props(component.props) }}, +{% if component.contents|length %}{{ component.contents }},{% endif %} +{% for child in component.children %}{% if child is mapping or child|length %}{{ render(child) }},{% endif %}{% endfor %}) {%- endmacro %} @@ -48,11 +37,7 @@ {# Args: #} {# component: component dictionary #} {% macro render_condition_tag(component) %} -{ {{- component.cond_state }} ? ( - {{ render(component.true_value) }} -) : ( - {{ render(component.false_value) }} -)} +({{ component.cond_state }} ? ({{ render(component.true_value) }}) : ({{ render(component.false_value) }})) {%- endmacro %} @@ -60,57 +45,33 @@ {# Args: #} {# component: component dictionary #} {% macro render_iterable_tag(component) %} -<>{ {{ component.iterable_state }}.map(({{ component.arg_name }}, {{ component.arg_index }}) => ( - {% for child in component.children %} - {{ render(child) }} - {% endfor %} -))} +{{ component.iterable_state }}.map(({{ component.arg_name }},{{ component.arg_index }})=>({% for child in component.children %}{{ render(child) }}{% endfor %})) {%- endmacro %} {# Rendering props of a component. #} {# Args: #} {# component: component dictionary #} -{% macro render_props(props) %} -{% if props|length %} {{ props|join(" ") }}{% endif %} -{% endmacro %} +{% macro render_props(props) %}{ {% if props|length %}{{ props|join(",") }}{% endif %} }{% endmacro %} {# Rendering Match component. #} {# Args: #} {# component: component dictionary #} {% macro render_match_tag(component) %} -{ - (() => { - switch (JSON.stringify({{ component.cond._js_expr }})) { - {% for case in component.match_cases %} - {% for condition in case[:-1] %} - case JSON.stringify({{ condition._js_expr }}): - {% endfor %} - return {{ render(case[-1]) }}; - break; - {% endfor %} - default: - return {{ render(component.default) }}; - break; - } - })() - } -{%- endmacro %} - - -{# Rendering content with args. #} -{# Args: #} -{# component: component dictionary #} -{% macro render_arg_content(component) %} -{% filter indent(width=2) %} -{# no string below for a line break #} - -{({ {{component.args|join(", ")}} }) => ( - {% for child in component.children %} - {{ render(child) }} +(() => { + switch (JSON.stringify({{ component.cond._js_expr }})) { + {% for case in component.match_cases %} + {% for condition in case[:-1] %} + case JSON.stringify({{ condition._js_expr }}): + {% endfor %} + return {{ render(case[-1]) }}; + break; {% endfor %} -)} -{% endfilter %} + default: + return {{ render(component.default) }}; + break; + } +})() {% endmacro %} diff --git a/reflex/.templates/jinja/web/utils/context.js.jinja2 b/reflex/.templates/jinja/web/utils/context.js.jinja2 index d138d2c12be..08d3e7f16d6 100644 --- a/reflex/.templates/jinja/web/utils/context.js.jinja2 +++ b/reflex/.templates/jinja/web/utils/context.js.jinja2 @@ -1,4 +1,4 @@ -import { createContext, useContext, useMemo, useReducer, useState } from "react" +import { createContext, useContext, useMemo, useReducer, useState, createElement } from "react" import { applyDelta, Event, hydrateClientStorage, useEventLoop, refs } from "$/utils/state.js" {% if initial_state %} @@ -77,11 +77,7 @@ export function UploadFilesProvider({ children }) { delete newFilesById[id] return newFilesById }) - return ( - - {children} - - ) + return createElement(UploadFilesContext, {value:[filesById, setFilesById]}, children); } export function EventLoopProvider({ children }) { @@ -91,11 +87,7 @@ export function EventLoopProvider({ children }) { initialEvents, clientStorage, ) - return ( - - {children} - - ) + return createElement(EventLoopContext, {value:[addEvents, connectErrors]}, children); } export function StateProvider({ children }) { @@ -112,13 +104,9 @@ export function StateProvider({ children }) { return ( {% for state_name in initial_state %} - - {% endfor %} - - {children} - - {% for state_name in initial_state|reverse %} - + createElement(StateContexts.{{state_name|var_name}},{value: {{state_name|var_name}}}, {% endfor %} + createElement(DispatchContext.Provider, {value: dispatchers}, children), + {% for state_name in initial_state|reverse %}){% endfor %} ) } From c51333198e6d35beff3d6f6c8521b9815d63f5dc Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:07:11 -0700 Subject: [PATCH 02/16] fix most of the tests --- pyi_hashes.json | 220 +++++++++--------- .../jinja/web/pages/utils.js.jinja2 | 8 +- reflex/components/base/bare.py | 7 +- reflex/components/component.py | 26 +-- reflex/components/core/upload.py | 4 +- reflex/components/el/element.py | 4 + reflex/components/el/elements/metadata.py | 2 +- reflex/components/markdown/markdown.py | 13 +- reflex/components/plotly/plotly.py | 2 +- reflex/utils/format.py | 13 +- tests/units/components/base/test_bare.py | 8 +- tests/units/components/base/test_link.py | 8 +- tests/units/components/base/test_script.py | 10 +- tests/units/components/core/test_cond.py | 4 +- tests/units/components/core/test_foreach.py | 2 +- tests/units/components/core/test_html.py | 4 +- tests/units/components/core/test_match.py | 19 +- .../components/datadisplay/test_dataeditor.py | 4 +- .../components/datadisplay/test_datatable.py | 4 +- tests/units/components/el/test_svg.py | 24 +- tests/units/components/forms/test_form.py | 2 +- .../components/markdown/test_markdown.py | 10 +- tests/units/components/test_component.py | 40 ++-- tests/units/components/test_tag.py | 8 +- tests/units/test_app.py | 23 +- tests/units/utils/test_format.py | 6 +- 26 files changed, 243 insertions(+), 232 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 095221a53c8..3e53856c083 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -2,125 +2,125 @@ "reflex/__init__.pyi": "8a6d2350e96659846436792a5c7b772b", "reflex/components/__init__.pyi": "76ba0a12cd3a7ba5ab6341a3ae81551f", "reflex/components/base/__init__.pyi": "e9aaf47be1e1977eacee97b880c8f7de", - "reflex/components/base/app_wrap.pyi": "387fc7a0c2da8760d9449e2893e44eec", - "reflex/components/base/body.pyi": "2cc870cec4b1c28081dd40467752c2b7", - "reflex/components/base/document.pyi": "30377cdfb02b564f8de29b0473d2346c", - "reflex/components/base/error_boundary.pyi": "c56b591d14a92b99a1e97e04afe167d7", - "reflex/components/base/fragment.pyi": "603ee8e03af88d4a8ff6bc1fbce4e022", - "reflex/components/base/head.pyi": "893047aa32da553711db8f1345adb6b0", - "reflex/components/base/link.pyi": "396488afa3b7a5b0d0e6c5e89159f857", - "reflex/components/base/meta.pyi": "bc4b4fda6f022a517de339ffdd667e3b", - "reflex/components/base/script.pyi": "530cf8f47eb90082bf65942e8b5d745f", - "reflex/components/base/strict_mode.pyi": "d972e0ff2a6f961e7df90fc27b8bb51b", + "reflex/components/base/app_wrap.pyi": "a0f6cec6b4720a74ec9da07baf93689e", + "reflex/components/base/body.pyi": "31944453e355e0634345bc6367d7becf", + "reflex/components/base/document.pyi": "90f89615087fe6e60f68bf60177d4768", + "reflex/components/base/error_boundary.pyi": "2cf73e45744f167b07c876d75aa95707", + "reflex/components/base/fragment.pyi": "c44c7d12b412b93e21ecd758103a81cc", + "reflex/components/base/head.pyi": "b565801fb04f5be8c3f63b9115330fe3", + "reflex/components/base/link.pyi": "36df1ab367d65ebee66b0edf974b0833", + "reflex/components/base/meta.pyi": "4b384b1bc25120e09573deea6a39de01", + "reflex/components/base/script.pyi": "3e66ec86de09316d72f128878d9db2c0", + "reflex/components/base/strict_mode.pyi": "ccc408f6d640ba553cb545842bd7f33a", "reflex/components/core/__init__.pyi": "44bcee7bc4e27e2f4f4707b843acf291", - "reflex/components/core/auto_scroll.pyi": "d3012d2a4ccaab8dfebf9aa484020f59", - "reflex/components/core/banner.pyi": "48d0eb86ae09e806ebe20d0edcc3cdb3", - "reflex/components/core/client_side_routing.pyi": "9be638a2b0e00b8181697e5dd6b45e4e", - "reflex/components/core/clipboard.pyi": "af76b623d593df3b16162033c597f920", - "reflex/components/core/debounce.pyi": "76d857eb814bc64625860a5f43e8b230", - "reflex/components/core/html.pyi": "b12117b42ef79ee90b6b4dec50baeb86", - "reflex/components/core/sticky.pyi": "c65131cf7c2312c68e1fddaa0cc27150", - "reflex/components/core/upload.pyi": "6fb89607ec8f8c1971f0dbd3453901eb", + "reflex/components/core/auto_scroll.pyi": "910fc1962bf7688845f2420b66a7d2f5", + "reflex/components/core/banner.pyi": "b715bee1e2d4fbc13426120d09383b6f", + "reflex/components/core/client_side_routing.pyi": "ffc8b71f3f34fe6b165eefdb85c269ca", + "reflex/components/core/clipboard.pyi": "90120e2a738267b970d1db9d25b26258", + "reflex/components/core/debounce.pyi": "aefd587b00ec73860e1fca5bd9c842cf", + "reflex/components/core/html.pyi": "63fb3751eafb9165bfbdff57b19801df", + "reflex/components/core/sticky.pyi": "f2678e6425d15dcfaf1a957399f71ed3", + "reflex/components/core/upload.pyi": "3cb7b941f50f796771e959a557089105", "reflex/components/datadisplay/__init__.pyi": "cf087efa8b3960decc6b231cc986cfa9", - "reflex/components/datadisplay/code.pyi": "3d8f0ab4c2f123d7f80d15c7ebc553d9", - "reflex/components/datadisplay/dataeditor.pyi": "1b762071001161e4fdd1285263c33bb3", - "reflex/components/datadisplay/shiki_code_block.pyi": "87db7639bfa5cd53e1709e1363f93278", + "reflex/components/datadisplay/code.pyi": "e549ccf8d3be9c74fc469812add873de", + "reflex/components/datadisplay/dataeditor.pyi": "d21f979ddc52f78f9d8ecbc95ebc59bb", + "reflex/components/datadisplay/shiki_code_block.pyi": "95a2248975fd4b13403822a2e42efef7", "reflex/components/el/__init__.pyi": "09042a2db5e0637e99b5173430600522", - "reflex/components/el/element.pyi": "06ac2213b062119323291fa66a1ac19e", + "reflex/components/el/element.pyi": "5b5bd985dff50cafbad97eeb2996b0fb", "reflex/components/el/elements/__init__.pyi": "280ed457675f3720e34b560a3f617739", - "reflex/components/el/elements/base.pyi": "6e533348b5e1a88cf62fbb5a38dbd795", - "reflex/components/el/elements/forms.pyi": "2e7ab39bc7295b8594f38a2aa59c9610", - "reflex/components/el/elements/inline.pyi": "33d9d860e75dd8c4769825127ed363bb", - "reflex/components/el/elements/media.pyi": "addd6872281d65d44a484358b895432f", - "reflex/components/el/elements/metadata.pyi": "974a86d9f0662f6fc15a5bb4b3a87862", - "reflex/components/el/elements/other.pyi": "995a4fbf10bfdb7f48808210dfe413bd", - "reflex/components/el/elements/scripts.pyi": "cd5bd53c3a6b016fbb913aff36d63344", - "reflex/components/el/elements/sectioning.pyi": "65aa53b1372598ec1785616cb7016032", - "reflex/components/el/elements/tables.pyi": "e1282d8ddf4efa4c911ca104a907ee88", - "reflex/components/el/elements/typography.pyi": "00088c9c1b68a14e5a41d837e8fdf542", - "reflex/components/gridjs/datatable.pyi": "7fd1dd65ba143d60b7d42d1bb90a179d", - "reflex/components/lucide/icon.pyi": "a5521a8baf8d2d7281e3fdfe6ce7073b", - "reflex/components/markdown/markdown.pyi": "f2d0cbff02e0a26f201287fabe6fb738", - "reflex/components/moment/moment.pyi": "6dd0c7cee5f0f29bc11d830c697d7f92", - "reflex/components/next/base.pyi": "14aafd5b018a4bc9748a3c9980fcfe3e", - "reflex/components/next/image.pyi": "3a0d1970e69144e9c6806e68ab99f181", - "reflex/components/next/link.pyi": "cd913e10205314afe67101d9640e05cb", - "reflex/components/next/video.pyi": "09698418db651917630a7fefeb573fc2", - "reflex/components/plotly/plotly.pyi": "77afe88b405c3eae7058994d53a27946", + "reflex/components/el/elements/base.pyi": "37e6bf1cdfa91cb35e2e71e14eab47b0", + "reflex/components/el/elements/forms.pyi": "eeb2d67c4001f298aeaa357b87c3aa2f", + "reflex/components/el/elements/inline.pyi": "7635236cf7fb232df91f76934411faf5", + "reflex/components/el/elements/media.pyi": "bfcf42e75669e576b2592bea57d515de", + "reflex/components/el/elements/metadata.pyi": "a6bc43936b93fa942b13d20de3863187", + "reflex/components/el/elements/other.pyi": "1a0c081680c03fd239e20b7e9e2562af", + "reflex/components/el/elements/scripts.pyi": "198e81956b09eb09bcb9856490200e1c", + "reflex/components/el/elements/sectioning.pyi": "0a8bd8e9b5e55fbe2b0ee2991ef19517", + "reflex/components/el/elements/tables.pyi": "2076ac4b4fdc5828d83c487bc0109468", + "reflex/components/el/elements/typography.pyi": "2de860327da0aece2463355182f8fd59", + "reflex/components/gridjs/datatable.pyi": "4e49539ef1f9dc7028838a949f34e8de", + "reflex/components/lucide/icon.pyi": "2e080b6bdb523e411b93388869e2e2e4", + "reflex/components/markdown/markdown.pyi": "4e6d4c59bd18417f9e3cac44d25aef27", + "reflex/components/moment/moment.pyi": "191e390c325519dc06a26a006241a268", + "reflex/components/next/base.pyi": "fb613338a9961b649c0a510942b5ea77", + "reflex/components/next/image.pyi": "23436bb61a23c525bf5c66604940889c", + "reflex/components/next/link.pyi": "6cdd6ee1ed0d9027c39e2b8099b536a7", + "reflex/components/next/video.pyi": "01b594b145bccb2270df79e792914144", + "reflex/components/plotly/plotly.pyi": "3d29b6447fc96f437474a5ba2ce477dc", "reflex/components/radix/__init__.pyi": "8d586cbff1d7130d09476ac72ee73400", "reflex/components/radix/primitives/__init__.pyi": "fe8715decf3e9ae471b56bba14e42cb3", - "reflex/components/radix/primitives/accordion.pyi": "b1482766c3c99ab40c2f446598fdb6a7", - "reflex/components/radix/primitives/base.pyi": "8b1dbf0b75cb29e873d611b83c9e4156", - "reflex/components/radix/primitives/drawer.pyi": "b6f8b17e1d0064d5609915546c722a81", - "reflex/components/radix/primitives/form.pyi": "79ddb679e0b3df814439ce993fcf355e", - "reflex/components/radix/primitives/progress.pyi": "c62a0c44e0d440701174fcca93bf8fbe", - "reflex/components/radix/primitives/slider.pyi": "c27e1a1180442e2e6e9d727560e8068c", + "reflex/components/radix/primitives/accordion.pyi": "1b2c94923fd20df8450b8a2887e7b3ed", + "reflex/components/radix/primitives/base.pyi": "37f923bf6476bb7e159e984df7c1d6ab", + "reflex/components/radix/primitives/drawer.pyi": "0aaaceed3457b179919b81618e9d3018", + "reflex/components/radix/primitives/form.pyi": "84b02eb4ddc13904ca3f339365164bae", + "reflex/components/radix/primitives/progress.pyi": "78e124e9fedefb58452f23f791200be1", + "reflex/components/radix/primitives/slider.pyi": "59cd03d41414bd4cc2e1995a3c4e9a98", "reflex/components/radix/themes/__init__.pyi": "a15f9464ad99f248249ffa8e6deea4cf", - "reflex/components/radix/themes/base.pyi": "a3c3c3b72fd3d8f1e38990e5c461b682", - "reflex/components/radix/themes/color_mode.pyi": "435a51382eab6111aae1b26e79e9a473", + "reflex/components/radix/themes/base.pyi": "7095c0f13d5cf741d35a86218603cea0", + "reflex/components/radix/themes/color_mode.pyi": "cc764eb8a379187bcd3956a8033515fe", "reflex/components/radix/themes/components/__init__.pyi": "87bb9ffff641928562da1622d2ca5993", - "reflex/components/radix/themes/components/alert_dialog.pyi": "8e1dde62450296310a116ed066bd51e3", - "reflex/components/radix/themes/components/aspect_ratio.pyi": "1845813a034adfc1f5db8e0f6ffc1118", - "reflex/components/radix/themes/components/avatar.pyi": "b591cb8b31d5a9aea5413120a6a744d9", - "reflex/components/radix/themes/components/badge.pyi": "5e8f49fd9ff10c756d9afa54bfd3fd10", - "reflex/components/radix/themes/components/button.pyi": "201448dcdf735f24d8bd21112039c1ca", - "reflex/components/radix/themes/components/callout.pyi": "e2b5828f271a2d790e88bb965d0fcded", - "reflex/components/radix/themes/components/card.pyi": "fe42e0cbdf9eb34341f4bbba8a586b34", - "reflex/components/radix/themes/components/checkbox.pyi": "78bc26eabd6468a44f5139449a2c6208", - "reflex/components/radix/themes/components/checkbox_cards.pyi": "cc43c568aa42ffa3e693e5cd1acba156", - "reflex/components/radix/themes/components/checkbox_group.pyi": "e36603b9ea5f161070c5a0235c4411fa", - "reflex/components/radix/themes/components/context_menu.pyi": "cdf546723a84c99412d91ca63d4bb2df", - "reflex/components/radix/themes/components/data_list.pyi": "768e4c9222d37d90228309166a1c6ab3", - "reflex/components/radix/themes/components/dialog.pyi": "b51cb34dc6c90ccd07a2f9fc97eaf1c1", - "reflex/components/radix/themes/components/dropdown_menu.pyi": "34807c4ab4665932da664ab68dab0edf", - "reflex/components/radix/themes/components/hover_card.pyi": "cfa947d1edec4b17dc6f227783ca1cbc", - "reflex/components/radix/themes/components/icon_button.pyi": "560cc3a95a8f1a396c8c5fb916b0ee8b", - "reflex/components/radix/themes/components/inset.pyi": "828f3d3a5b8f7fd07597069c01aaa0a0", - "reflex/components/radix/themes/components/popover.pyi": "c953a42260a3b261eec772dba716d951", - "reflex/components/radix/themes/components/progress.pyi": "c880c6bb9803d47048f656dfa66a7c15", - "reflex/components/radix/themes/components/radio.pyi": "36fa5585440685a7d2dff40b50502840", - "reflex/components/radix/themes/components/radio_cards.pyi": "e9a0f27119322e6148946ae178edb7a9", - "reflex/components/radix/themes/components/radio_group.pyi": "ea3180940390e4b6eaf10670be5bc2fe", - "reflex/components/radix/themes/components/scroll_area.pyi": "83892be0b2c902d2147cbdb5e19310ab", - "reflex/components/radix/themes/components/segmented_control.pyi": "7be200991becc54cd885465656e2dfef", - "reflex/components/radix/themes/components/select.pyi": "655a5c2182a16121440e5ddbba2079d8", - "reflex/components/radix/themes/components/separator.pyi": "58a95aca75a556d349eb56f898bde680", - "reflex/components/radix/themes/components/skeleton.pyi": "d91615706e5efb81d97755decbbf5ae3", - "reflex/components/radix/themes/components/slider.pyi": "b87ee08b7edfe41eddf3d3c1cb71124e", - "reflex/components/radix/themes/components/spinner.pyi": "80766a7324b582221edb66ec46da0acb", - "reflex/components/radix/themes/components/switch.pyi": "f8256d2b50d15ab163649cfb05229750", - "reflex/components/radix/themes/components/table.pyi": "560ce8d920e03b450fe6b938f5f0fea0", - "reflex/components/radix/themes/components/tabs.pyi": "96ac1082651d2adc2a60a3af6e90c17f", - "reflex/components/radix/themes/components/text_area.pyi": "418d3df53eeca0723d83a93d81f16b12", - "reflex/components/radix/themes/components/text_field.pyi": "cdf0e08f5af0a5fce6b31787001f1dc3", - "reflex/components/radix/themes/components/tooltip.pyi": "6cd225ba10140e925752c74404336f27", + "reflex/components/radix/themes/components/alert_dialog.pyi": "da5f6d1964de97699475f36900dd8600", + "reflex/components/radix/themes/components/aspect_ratio.pyi": "e9aea8ef0fa5a836025d330b8c57eb5f", + "reflex/components/radix/themes/components/avatar.pyi": "f916df93eba7cac5b0cc965b87b44346", + "reflex/components/radix/themes/components/badge.pyi": "563530aec38d6876501e02a742b1fa1c", + "reflex/components/radix/themes/components/button.pyi": "cca75329c397ccd1de87d8152267ec08", + "reflex/components/radix/themes/components/callout.pyi": "8c6f287e51496211fbe288bf08c39b03", + "reflex/components/radix/themes/components/card.pyi": "a9cc503df3c48829707133cdc92aa949", + "reflex/components/radix/themes/components/checkbox.pyi": "b78678c703cc1077b61e00826c4d980c", + "reflex/components/radix/themes/components/checkbox_cards.pyi": "f403ba28ef114b0ba383a9da163f4646", + "reflex/components/radix/themes/components/checkbox_group.pyi": "4a4304303ec3e472b27033d1e4e7aff6", + "reflex/components/radix/themes/components/context_menu.pyi": "ed247dbad20b776ef7e84103959d2145", + "reflex/components/radix/themes/components/data_list.pyi": "02801c3469d4791b6e4bf81d3423ea4f", + "reflex/components/radix/themes/components/dialog.pyi": "1ad7fa0f8870b054043fb173cf7f7b0b", + "reflex/components/radix/themes/components/dropdown_menu.pyi": "ea706472643df6002fa9a406e9f07fda", + "reflex/components/radix/themes/components/hover_card.pyi": "8cdd1ace5804e7ed228fa74aeb565a0c", + "reflex/components/radix/themes/components/icon_button.pyi": "434b49b2a3785dcd08d2195fa509ca17", + "reflex/components/radix/themes/components/inset.pyi": "8baaf94a1e93fbc8821e798fe43e3a33", + "reflex/components/radix/themes/components/popover.pyi": "af71f2cbeb1b78ef3298e8e8a18dee65", + "reflex/components/radix/themes/components/progress.pyi": "05f654e57684a3aa9da9705c51ba0855", + "reflex/components/radix/themes/components/radio.pyi": "b53b2ac19b7bd2f5b060263242d50f49", + "reflex/components/radix/themes/components/radio_cards.pyi": "88aede2b5e1798aed3e46844c365fc61", + "reflex/components/radix/themes/components/radio_group.pyi": "78bab4a733b71d07118e3dfaaca78c04", + "reflex/components/radix/themes/components/scroll_area.pyi": "17ec4bcdf4a676c44ae4c78cff55dee6", + "reflex/components/radix/themes/components/segmented_control.pyi": "28d2f82b3ede4fadbb0d10bbae27dfe6", + "reflex/components/radix/themes/components/select.pyi": "37eeed2e6b9bef221c95a7cbd025825a", + "reflex/components/radix/themes/components/separator.pyi": "6114ecfac62066a7d7852e7a8b151e30", + "reflex/components/radix/themes/components/skeleton.pyi": "3d36c3f06acc08f6cafd081581a54d0d", + "reflex/components/radix/themes/components/slider.pyi": "980c1923daf7f7fe8017dfdb16cff76f", + "reflex/components/radix/themes/components/spinner.pyi": "c77fe930dd1199566c1af87892773421", + "reflex/components/radix/themes/components/switch.pyi": "343394fafb76b0404db4b14476585400", + "reflex/components/radix/themes/components/table.pyi": "8182636894f3614021085977d9c137b5", + "reflex/components/radix/themes/components/tabs.pyi": "b8174587123f3a91bffcc5aff9b2c8fe", + "reflex/components/radix/themes/components/text_area.pyi": "9f47d56ace353d3828280d10882e23e6", + "reflex/components/radix/themes/components/text_field.pyi": "ab77baabba267136d34c0cb0771f2722", + "reflex/components/radix/themes/components/tooltip.pyi": "6317337c8ffd694e0bf1795c69b0e604", "reflex/components/radix/themes/layout/__init__.pyi": "9a52c5b283c864be70b51a8fd6120392", - "reflex/components/radix/themes/layout/base.pyi": "e9a5c1f376e66653ebcf5d2315f990f8", - "reflex/components/radix/themes/layout/box.pyi": "5a3c2339d74cc062358ec32b2c2c138c", - "reflex/components/radix/themes/layout/center.pyi": "29bde2c21a190ba7d7a382a1157f5aa7", - "reflex/components/radix/themes/layout/container.pyi": "4020c3dca660027b84d11cc4198393c4", - "reflex/components/radix/themes/layout/flex.pyi": "f814281a5635ad43dd1df23f8e356c66", - "reflex/components/radix/themes/layout/grid.pyi": "6062188367a2c253f014f916197c963d", - "reflex/components/radix/themes/layout/list.pyi": "804f7a36c103cd7a3e362d40a58e8d39", - "reflex/components/radix/themes/layout/section.pyi": "41895910072e023ed0fef6a8ad956046", - "reflex/components/radix/themes/layout/spacer.pyi": "029eb0eaa731bcdff7c496e0437e22b1", - "reflex/components/radix/themes/layout/stack.pyi": "3b0da99b00c826d087ed89fc67c595c1", + "reflex/components/radix/themes/layout/base.pyi": "71934715b95cf677a79f8edb01209ba7", + "reflex/components/radix/themes/layout/box.pyi": "c5bcdcb7dd12e9a0e93b75ae9b3994ba", + "reflex/components/radix/themes/layout/center.pyi": "3031951d02347bf3cc7193ad614a0bbd", + "reflex/components/radix/themes/layout/container.pyi": "6dae0e49852122dfde1676351da29318", + "reflex/components/radix/themes/layout/flex.pyi": "26cc246595e32eefe6a4086a12dd5bb0", + "reflex/components/radix/themes/layout/grid.pyi": "dd7f5386d7b1dc268ad4de12154c6b85", + "reflex/components/radix/themes/layout/list.pyi": "20452aba8b9070395d4ce52b505a4616", + "reflex/components/radix/themes/layout/section.pyi": "28e7ea38e30a7b2b8a32b830f5651700", + "reflex/components/radix/themes/layout/spacer.pyi": "b22099a7e172f961449a9d9f79a9c342", + "reflex/components/radix/themes/layout/stack.pyi": "55a3f5d8200213113671a9526336b10f", "reflex/components/radix/themes/typography/__init__.pyi": "ef0ba71353dcac1f3546de45f8721bae", - "reflex/components/radix/themes/typography/blockquote.pyi": "8ed6f1c5aa86743d1fb9488334af64fe", - "reflex/components/radix/themes/typography/code.pyi": "85e869bb61e3e0da9c244aea78e14193", - "reflex/components/radix/themes/typography/heading.pyi": "5a3b0b8e44bda0fce22c6b1a1f25e68e", - "reflex/components/radix/themes/typography/link.pyi": "45965d95b9f9b76f8f4a3084a5430194", - "reflex/components/radix/themes/typography/text.pyi": "e6aa0ca43ebbd42701a3c72c0312032e", - "reflex/components/react_player/audio.pyi": "972975ed0ba3e1dc4a867da20b11ae8e", - "reflex/components/react_player/react_player.pyi": "63ffffbc24907103f797dcfd85894107", - "reflex/components/react_player/video.pyi": "35ce5ad62e8bff17d9c09d27c362f8dc", + "reflex/components/radix/themes/typography/blockquote.pyi": "a326dbbbcc9e18b169b890f5ca65c948", + "reflex/components/radix/themes/typography/code.pyi": "47924c83992d00d4b6591239699567c9", + "reflex/components/radix/themes/typography/heading.pyi": "ef62b00dd291c878694e6f0ca76aabee", + "reflex/components/radix/themes/typography/link.pyi": "6e77ce1e2aed7b9d32d03b9490fbf1dd", + "reflex/components/radix/themes/typography/text.pyi": "8cac5c3e5b0100f22abf6b514b64f632", + "reflex/components/react_player/audio.pyi": "6e4090f9cb3cde651d6690627ed994ff", + "reflex/components/react_player/react_player.pyi": "70c98e2e8893d7bc8f889c1f86e80a5b", + "reflex/components/react_player/video.pyi": "d77968489205a1e1e0aba52c5401381d", "reflex/components/recharts/__init__.pyi": "a52c9055e37c6ee25ded15688d45e8a5", - "reflex/components/recharts/cartesian.pyi": "34b15e8f5125b5a8145e3e04ed6418e4", - "reflex/components/recharts/charts.pyi": "b3d35de9cea86307ad2ab7d69ff2d06b", - "reflex/components/recharts/general.pyi": "5548fc494c29063c262ca7a7ef51dce8", - "reflex/components/recharts/polar.pyi": "8fb87fd69c9edf55998f11ea8ada76fb", - "reflex/components/recharts/recharts.pyi": "157acc830323075ffaf4f68d495d1787", - "reflex/components/sonner/toast.pyi": "0b6dc33413f30fdd043b89ec3c8c3f39", - "reflex/components/suneditor/editor.pyi": "284aa914b9bffe840db67ee68192eaf7", - "reflex/experimental/layout.pyi": "6398e779743963ef3e03396696b8ddfb" + "reflex/components/recharts/cartesian.pyi": "95548440902dd4e356359009abf59371", + "reflex/components/recharts/charts.pyi": "8f568c3c5d79f5bd66a32babf4cd91ec", + "reflex/components/recharts/general.pyi": "ba7d3ad8836ee79efe6db00b119470ae", + "reflex/components/recharts/polar.pyi": "b7c130eaacd6892a8b499b26a24df76a", + "reflex/components/recharts/recharts.pyi": "041dc0bee1254b858261699ba50eea0b", + "reflex/components/sonner/toast.pyi": "a3832c9229703fa4a89e86b9f4753eee", + "reflex/components/suneditor/editor.pyi": "57653e4673ac4045da5ebb6c875e6f92", + "reflex/experimental/layout.pyi": "2e09a7d3535d72155a4ecdecc865f3ba" } diff --git a/reflex/.templates/jinja/web/pages/utils.js.jinja2 b/reflex/.templates/jinja/web/pages/utils.js.jinja2 index ce96f1d4d27..14c62f18dd8 100644 --- a/reflex/.templates/jinja/web/pages/utils.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/utils.js.jinja2 @@ -26,10 +26,12 @@ jsx({{ component.name }},{{ render_props(component.props) }},{{ component.conten {# Args: #} {# component: component dictionary #} {% macro render_tag(component) %} -jsx({% if component.name|length %}{{ component.name }}{% else %}Fragment{% endif %}, +jsx( +{% if component.name|length %}{{ component.name }}{% else %}Fragment{% endif %}, {{ render_props(component.props) }}, {% if component.contents|length %}{{ component.contents }},{% endif %} -{% for child in component.children %}{% if child is mapping or child|length %}{{ render(child) }},{% endif %}{% endfor %}) +{% for child in component.children %}{% if child is mapping or child|length %}{{ render(child) }},{% endif %}{% endfor %} +) {%- endmacro %} @@ -52,7 +54,7 @@ jsx({% if component.name|length %}{{ component.name }}{% else %}Fragment{% endif {# Rendering props of a component. #} {# Args: #} {# component: component dictionary #} -{% macro render_props(props) %}{ {% if props|length %}{{ props|join(",") }}{% endif %} }{% endmacro %} +{% macro render_props(props) %}{{ "{" }}{% if props|length %}{{ props|join(",") }}{% endif %}{{ "}" }}{% endmacro %} {# Rendering Match component. #} {# Args: #} diff --git a/reflex/components/base/bare.py b/reflex/components/base/bare.py index b3d050b52ad..8b3012f1a6f 100644 --- a/reflex/components/base/bare.py +++ b/reflex/components/base/bare.py @@ -2,6 +2,7 @@ from __future__ import annotations +import json from typing import Any, Iterator, Sequence from reflex.components.component import BaseComponent, Component, ComponentStyle @@ -170,9 +171,9 @@ def _get_all_refs(self) -> set[str]: def _render(self) -> Tag: if isinstance(self.contents, Var): if isinstance(self.contents, (BooleanVar, ObjectVar)): - return Tagless(contents=f"{{{self.contents.to_string()!s}}}") - return Tagless(contents=f"{{{self.contents!s}}}") - return Tagless(contents=str(self.contents)) + return Tagless(contents=f"{self.contents.to_string()!s}") + return Tagless(contents=f"{self.contents!s}") + return Tagless(contents=f'"{json.dumps(self.contents)}"') def _add_style_recursive( self, style: ComponentStyle, theme: Component | None = None diff --git a/reflex/components/component.py b/reflex/components/component.py index cde6cadf43f..41cf5942750 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -280,6 +280,9 @@ class Component(BaseComponent, ABC): # The alias for the tag. alias: str | None = pydantic.v1.Field(default_factory=lambda: None) + # Whether the component is a global scope tag. True for tags like `html`, `head`, `body`. + _is_tag_in_global_scope: bool = pydantic.PrivateAttr(default_factory=lambda: False) + # Whether the import is default or named. is_default: bool | None = pydantic.v1.Field(default_factory=lambda: False) @@ -678,9 +681,14 @@ def _render(self, props: dict[str, Any] | None = None) -> Tag: Returns: The tag to render. """ + # Create the base tag. + name = (self.tag if not self.alias else self.alias) or "" + if self._is_tag_in_global_scope and self.library is None: + name = '"' + name + '"' + # Create the base tag. tag = Tag( - name=(self.tag if not self.alias else self.alias) or "", + name=name, special_props=self.special_props, ) @@ -2579,12 +2587,12 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) -> special_props = [] for prop_str in tag["props"]: - if "=" not in prop_str: + if ":" not in prop_str: special_props.append(Var(prop_str).to(ObjectVar)) continue - prop = prop_str.index("=") + prop = prop_str.index(":") key = prop_str[:prop] - value = prop_str[prop + 2 : -1] + value = prop_str[prop + 1 :] props[key] = value props = Var.create({Var.create(k): Var(v) for k, v in props.items()}) @@ -2592,19 +2600,11 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) -> for prop in special_props: props = props.merge(prop) - contents = tag["contents"][1:-1] if tag["contents"] else None + contents = tag["contents"] if tag["contents"] else None raw_tag_name = tag.get("name") tag_name = Var(raw_tag_name or "Fragment") - tag_name = ( - Var.create(raw_tag_name) - if raw_tag_name - and raw_tag_name.split(".")[0] not in imported_names - and raw_tag_name.lower() == raw_tag_name - else tag_name - ) - return FunctionStringVar.create( "jsx", ).call( diff --git a/reflex/components/core/upload.py b/reflex/components/core/upload.py index a1aec9163e0..4791ff61fd8 100644 --- a/reflex/components/core/upload.py +++ b/reflex/components/core/upload.py @@ -324,7 +324,7 @@ def create(cls, *children, **props) -> Component: upload = Input.create(type="file") upload.special_props = [ Var( - _js_expr=f"{{...{input_props_unique_name}()}}", + _js_expr=f"{input_props_unique_name}()", _var_type=None, _var_data=var_data, ) @@ -338,7 +338,7 @@ def create(cls, *children, **props) -> Component: ) zone.special_props = [ Var( - _js_expr=f"{{...{root_props_unique_name}()}}", + _js_expr=f"{root_props_unique_name}()", _var_type=None, _var_data=var_data, ) diff --git a/reflex/components/el/element.py b/reflex/components/el/element.py index c9a58b1f6f1..5b0f913b4e0 100644 --- a/reflex/components/el/element.py +++ b/reflex/components/el/element.py @@ -1,11 +1,15 @@ """Base class definition for raw HTML elements.""" +import pydantic + from reflex.components.component import Component class Element(Component): """The base class for all raw HTML elements.""" + _is_tag_in_global_scope = pydantic.PrivateAttr(default_factory=lambda: True) + def __eq__(self, other: object): """Two elements are equal if they have the same tag. diff --git a/reflex/components/el/elements/metadata.py b/reflex/components/el/elements/metadata.py index 98aeaeecb55..bc961ce14da 100644 --- a/reflex/components/el/elements/metadata.py +++ b/reflex/components/el/elements/metadata.py @@ -89,7 +89,7 @@ class StyleEl(Element): media: Var[str] - special_props: list[Var] = [Var(_js_expr="suppressHydrationWarning")] + suppress_hydration_warning: Var[bool] = Var.create(True) base = Base.create diff --git a/reflex/components/markdown/markdown.py b/reflex/components/markdown/markdown.py index 54395cf9a27..811c5b62808 100644 --- a/reflex/components/markdown/markdown.py +++ b/reflex/components/markdown/markdown.py @@ -17,8 +17,8 @@ # Special vars used in the component map. _CHILDREN = Var(_js_expr="children", _var_type=str) -_PROPS = Var(_js_expr="...props") -_PROPS_IN_TAG = Var(_js_expr="{...props}") +_PROPS = Var(_js_expr="props") +_PROPS_SPREAD = Var(_js_expr="...props") _MOCK_ARG = Var(_js_expr="", _var_type=str) _LANGUAGE = Var(_js_expr="_language", _var_type=str) @@ -127,7 +127,7 @@ def get_fn_args(cls) -> Sequence[str]: Returns: The function arguments as a list of strings. """ - return ["node", _CHILDREN._js_expr, _PROPS._js_expr] + return ["node", _CHILDREN._js_expr, _PROPS_SPREAD._js_expr] @classmethod def get_fn_body(cls) -> Var: @@ -317,7 +317,7 @@ def _get_inline_code_fn_var(self) -> Var: "inline", "className", _CHILDREN._js_expr, - _PROPS._js_expr, + _PROPS_SPREAD._js_expr, ), fn_body=Var(_js_expr=formatted_code), explicit_return=True, @@ -341,7 +341,7 @@ def get_component(self, tag: str, **props) -> Component: if tag not in self.component_map: raise ValueError(f"No markdown component found for tag: {tag}.") - special_props = [_PROPS_IN_TAG] + special_props = [_PROPS] children = [ _CHILDREN if tag != "codeblock" @@ -358,9 +358,8 @@ def get_component(self, tag: str, **props) -> Component: special_props = [] # If the children are set as a prop, don't pass them as children. - children_prop = props.pop("children", None) + children_prop = props.get("children") if children_prop is not None: - special_props.append(Var(_js_expr=f"children={{{children_prop!s}}}")) children = [] # Get the component. component = self.component_map[tag](*children, **props).set( diff --git a/reflex/components/plotly/plotly.py b/reflex/components/plotly/plotly.py index bf1ab8fc11a..5cc382497a5 100644 --- a/reflex/components/plotly/plotly.py +++ b/reflex/components/plotly/plotly.py @@ -252,7 +252,7 @@ def _render(self): ) else: # Spread the figure dict over props, nothing to merge. - tag.special_props.append(Var(_js_expr=f"{{...{figure!s}}}")) + tag.special_props.append(Var(_js_expr=f"{figure!s}")) return tag diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 9078b89ea46..1d7ffcabb4c 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -436,12 +436,19 @@ def format_props(*single_props, **key_value_props) -> list[str]: from reflex.vars.base import LiteralVar, Var return [ - ( - f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}" + ":".join( + [ + str(name if "-" not in name else LiteralVar.create(name)), + str( + format_prop( + prop if isinstance(prop, Var) else LiteralVar.create(prop) + ) + ), + ] ) for name, prop in sorted(key_value_props.items()) if prop is not None - ] + [(f"{LiteralVar.create(prop)!s}") for prop in single_props] + ] + [(f"...{LiteralVar.create(prop)!s}") for prop in single_props] def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]: diff --git a/tests/units/components/base/test_bare.py b/tests/units/components/base/test_bare.py index 178820cffb7..6ae1e4db643 100644 --- a/tests/units/components/base/test_bare.py +++ b/tests/units/components/base/test_bare.py @@ -9,10 +9,10 @@ @pytest.mark.parametrize( "contents,expected", [ - ("hello", '{"hello"}'), - ("{}", '{"{}"}'), - (None, '{""}'), - (STATE_VAR, "{default_state.name}"), + ("hello", '"hello"'), + ("{}", '"{}"'), + (None, '""'), + (STATE_VAR, "default_state.name"), ], ) def test_fstrings(contents, expected): diff --git a/tests/units/components/base/test_link.py b/tests/units/components/base/test_link.py index 7713330c4f6..025533f4bb0 100644 --- a/tests/units/components/base/test_link.py +++ b/tests/units/components/base/test_link.py @@ -3,13 +3,13 @@ def test_raw_link(): raw_link = RawLink.create("https://example.com").render() - assert raw_link["name"] == "link" - assert raw_link["children"][0]["contents"] == '{"https://example.com"}' + assert raw_link["name"] == '"link"' + assert raw_link["children"][0]["contents"] == '"https://example.com"' def test_script_tag(): script_tag = ScriptTag.create("console.log('Hello, world!');").render() - assert script_tag["name"] == "script" + assert script_tag["name"] == '"script"' assert ( - script_tag["children"][0]["contents"] == "{\"console.log('Hello, world!');\"}" + script_tag["children"][0]["contents"] == "\"console.log('Hello, world!');\"" ) diff --git a/tests/units/components/base/test_script.py b/tests/units/components/base/test_script.py index e9c40188bab..2db63130746 100644 --- a/tests/units/components/base/test_script.py +++ b/tests/units/components/base/test_script.py @@ -14,7 +14,7 @@ def test_script_inline(): assert render_dict["name"] == "Script" assert not render_dict["contents"] assert len(render_dict["children"]) == 1 - assert render_dict["children"][0]["contents"] == '{"let x = 42"}' + assert render_dict["children"][0]["contents"] == '"let x = 42"' def test_script_src(): @@ -24,7 +24,7 @@ def test_script_src(): assert render_dict["name"] == "Script" assert not render_dict["contents"] assert not render_dict["children"] - assert 'src={"foo.js"}' in render_dict["props"] + assert 'src:"foo.js"' in render_dict["props"] def test_script_neither(): @@ -62,14 +62,14 @@ def test_script_event_handler(): ) render_dict = component.render() assert ( - f'onReady={{((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_ready", ({{ }}), ({{ }})))], args, ({{ }}))))}}' + f'onReady:((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_ready", ({{ }}), ({{ }})))], args, ({{ }}))))' in render_dict["props"] ) assert ( - f'onLoad={{((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_load", ({{ }}), ({{ }})))], args, ({{ }}))))}}' + f'onLoad:((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_load", ({{ }}), ({{ }})))], args, ({{ }}))))' in render_dict["props"] ) assert ( - f'onError={{((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_error", ({{ }}), ({{ }})))], args, ({{ }}))))}}' + f'onError:((...args) => (addEvents([(Event("{EvState.get_full_name()}.on_error", ({{ }}), ({{ }})))], args, ({{ }}))))' in render_dict["props"] ) diff --git a/tests/units/components/core/test_cond.py b/tests/units/components/core/test_cond.py index 57bf2bf0819..fb999d9eca6 100644 --- a/tests/units/components/core/test_cond.py +++ b/tests/units/components/core/test_cond.py @@ -57,7 +57,7 @@ def test_validate_cond(cond_state: BaseState): [true_value_text] = true_value["children"] assert true_value_text["name"] == "RadixThemesText" - assert true_value_text["children"][0]["contents"] == '{"cond is True"}' + assert true_value_text["children"][0]["contents"] == '"cond is True"' # false value false_value = condition["false_value"] @@ -65,7 +65,7 @@ def test_validate_cond(cond_state: BaseState): [false_value_text] = false_value["children"] assert false_value_text["name"] == "RadixThemesText" - assert false_value_text["children"][0]["contents"] == '{"cond is False"}' + assert false_value_text["children"][0]["contents"] == '"cond is False"' @pytest.mark.parametrize( diff --git a/tests/units/components/core/test_foreach.py b/tests/units/components/core/test_foreach.py index d72fa9350e4..4e9e51c476c 100644 --- a/tests/units/components/core/test_foreach.py +++ b/tests/units/components/core/test_foreach.py @@ -282,7 +282,7 @@ def test_foreach_component_styles(): ) ) component._add_style_recursive({box: {"color": "red"}}) - assert 'css={({ ["color"] : "red" })}' in str(component) + assert 'css:({ ["color"] : "red" })' in str(component) def test_foreach_component_state(): diff --git a/tests/units/components/core/test_html.py b/tests/units/components/core/test_html.py index bebb2587d91..83349b57a15 100644 --- a/tests/units/components/core/test_html.py +++ b/tests/units/components/core/test_html.py @@ -19,7 +19,7 @@ def test_html_create(): assert str(html.dangerouslySetInnerHTML) == '({ ["__html"] : "

Hello !

" })' # pyright: ignore [reportAttributeAccessIssue] assert ( str(html) - == '
Hello !

" })}/>' + == 'jsx("div",{className:"rx-Html",dangerouslySetInnerHTML:({ ["__html"] : "

Hello !

" })},)\n' ) @@ -37,5 +37,5 @@ class TestState(State): ) assert ( str(html) - == f'
' # pyright: ignore [reportAttributeAccessIssue] + == f'jsx("div",{{className:"rx-Html",dangerouslySetInnerHTML:{html.dangerouslySetInnerHTML!s}}},)\n' ) diff --git a/tests/units/components/core/test_match.py b/tests/units/components/core/test_match.py index 811ca780ab0..2b25ec180f3 100644 --- a/tests/units/components/core/test_match.py +++ b/tests/units/components/core/test_match.py @@ -1,3 +1,4 @@ +import re from typing import Mapping, Sequence, Tuple import pytest @@ -47,7 +48,7 @@ def test_match_components(): assert match_cases[0][0]._var_type is int first_return_value_render = match_cases[0][1] assert first_return_value_render["name"] == "RadixThemesText" - assert first_return_value_render["children"][0]["contents"] == '{"first value"}' + assert first_return_value_render["children"][0]["contents"] == '"first value"' assert match_cases[1][0]._js_expr == "2" assert match_cases[1][0]._var_type is int @@ -55,36 +56,36 @@ def test_match_components(): assert match_cases[1][1]._var_type is int second_return_value_render = match_cases[1][2] assert second_return_value_render["name"] == "RadixThemesText" - assert second_return_value_render["children"][0]["contents"] == '{"second value"}' + assert second_return_value_render["children"][0]["contents"] == '"second value"' assert match_cases[2][0]._js_expr == "[1, 2]" assert match_cases[2][0]._var_type == Sequence[int] third_return_value_render = match_cases[2][1] assert third_return_value_render["name"] == "RadixThemesText" - assert third_return_value_render["children"][0]["contents"] == '{"third value"}' + assert third_return_value_render["children"][0]["contents"] == '"third value"' assert match_cases[3][0]._js_expr == '"random"' assert match_cases[3][0]._var_type is str fourth_return_value_render = match_cases[3][1] assert fourth_return_value_render["name"] == "RadixThemesText" - assert fourth_return_value_render["children"][0]["contents"] == '{"fourth value"}' + assert fourth_return_value_render["children"][0]["contents"] == '"fourth value"' assert match_cases[4][0]._js_expr == '({ ["foo"] : "bar" })' assert match_cases[4][0]._var_type == Mapping[str, str] fifth_return_value_render = match_cases[4][1] assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == '{"fifth value"}' + assert fifth_return_value_render["children"][0]["contents"] == '"fifth value"' assert match_cases[5][0]._js_expr == f"({MatchState.get_name()}.num + 1)" assert match_cases[5][0]._var_type is int fifth_return_value_render = match_cases[5][1] assert fifth_return_value_render["name"] == "RadixThemesText" - assert fifth_return_value_render["children"][0]["contents"] == '{"sixth value"}' + assert fifth_return_value_render["children"][0]["contents"] == '"sixth value"' default = match_child["default"] assert default["name"] == "RadixThemesText" - assert default["children"][0]["contents"] == '{"default value"}' + assert default["children"][0]["contents"] == '"default value"' @pytest.mark.parametrize( @@ -264,7 +265,7 @@ def test_match_case_tuple_elements(match_case): ([1, 2], rx.text("third value")), rx.text("default value"), ), - 'Match cases should have the same return types. Case 3 with return value ` {"first value"} ` ' + 'Match cases should have the same return types. Case 3 with return value `jsx( RadixThemesText, {as:"p"}, "first value" ,)` ' "of type is not ", ), ], @@ -276,7 +277,7 @@ def test_match_different_return_types(cases: Tuple, error_msg: str): cases: The match cases. error_msg: Expected error message. """ - with pytest.raises(MatchTypeError, match=error_msg): + with pytest.raises(MatchTypeError, match=re.escape(error_msg)): Match.create(MatchState.value, *cases) diff --git a/tests/units/components/datadisplay/test_dataeditor.py b/tests/units/components/datadisplay/test_dataeditor.py index 63b156e7488..6b0d3ac6103 100644 --- a/tests/units/components/datadisplay/test_dataeditor.py +++ b/tests/units/components/datadisplay/test_dataeditor.py @@ -4,8 +4,8 @@ def test_dataeditor(): editor_wrapper = DataEditor.create().render() editor = editor_wrapper["children"][0] - assert editor_wrapper["name"] == "div" + assert editor_wrapper["name"] == '"div"' assert editor_wrapper["props"] == [ - 'css={({ ["width"] : "100%", ["height"] : "100%" })}' + 'css:({ ["width"] : "100%", ["height"] : "100%" })' ] assert editor["name"] == "DataEditor" diff --git a/tests/units/components/datadisplay/test_datatable.py b/tests/units/components/datadisplay/test_datatable.py index 2dece464afa..2b47669222d 100644 --- a/tests/units/components/datadisplay/test_datatable.py +++ b/tests/units/components/datadisplay/test_datatable.py @@ -47,8 +47,8 @@ def test_validate_data_table(data_table_state: rx.State, expected): expected = f"{state_name}.{expected}" if expected else state_name assert data_table_dict["props"] == [ - f"columns={{{expected}.columns}}", - f"data={{{expected}.data}}", + f"columns:{expected}.columns", + f"data:{expected}.data", ] diff --git a/tests/units/components/el/test_svg.py b/tests/units/components/el/test_svg.py index 29aaa96dd8f..e104c4e15b2 100644 --- a/tests/units/components/el/test_svg.py +++ b/tests/units/components/el/test_svg.py @@ -16,59 +16,59 @@ def test_circle(): circle = Circle.create().render() - assert circle["name"] == "circle" + assert circle["name"] == '"circle"' def test_defs(): defs = Defs.create().render() - assert defs["name"] == "defs" + assert defs["name"] == '"defs"' def test_ellipse(): ellipse = Ellipse.create().render() - assert ellipse["name"] == "ellipse" + assert ellipse["name"] == '"ellipse"' def test_line(): line = Line.create().render() - assert line["name"] == "line" + assert line["name"] == '"line"' def test_linear_gradient(): linear_gradient = LinearGradient.create().render() - assert linear_gradient["name"] == "linearGradient" + assert linear_gradient["name"] == '"linearGradient"' def test_path(): path = Path.create().render() - assert path["name"] == "path" + assert path["name"] == '"path"' def test_polygon(): polygon = Polygon.create().render() - assert polygon["name"] == "polygon" + assert polygon["name"] == '"polygon"' def test_radial_gradient(): radial_gradient = RadialGradient.create().render() - assert radial_gradient["name"] == "radialGradient" + assert radial_gradient["name"] == '"radialGradient"' def test_rect(): rect = Rect.create().render() - assert rect["name"] == "rect" + assert rect["name"] == '"rect"' def test_svg(): svg = Svg.create().render() - assert svg["name"] == "svg" + assert svg["name"] == '"svg"' def test_text(): text = Text.create().render() - assert text["name"] == "text" + assert text["name"] == '"text"' def test_stop(): stop = Stop.create().render() - assert stop["name"] == "stop" + assert stop["name"] == '"stop"' diff --git a/tests/units/components/forms/test_form.py b/tests/units/components/forms/test_form.py index 4c05b4fe14b..6b3d4a06001 100644 --- a/tests/units/components/forms/test_form.py +++ b/tests/units/components/forms/test_form.py @@ -11,7 +11,7 @@ def test_render_on_submit(): ) f = Form.create(on_submit=submit_it) exp_submit_name = f"handleSubmit_{f.handle_submit_unique_name}" # pyright: ignore [reportAttributeAccessIssue] - assert f"onSubmit={{{exp_submit_name}}}" in f.render()["props"] + assert f"onSubmit:{exp_submit_name}" in f.render()["props"] def test_render_no_on_submit(): diff --git a/tests/units/components/markdown/test_markdown.py b/tests/units/components/markdown/test_markdown.py index 15d662ef64b..6eb71b6704d 100644 --- a/tests/units/components/markdown/test_markdown.py +++ b/tests/units/components/markdown/test_markdown.py @@ -148,7 +148,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe ( "code", {}, - r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; if (_language) { if (!["abap", "abnf", "actionscript", "ada", "agda", "al", "antlr4", "apacheconf", "apex", "apl", "applescript", "aql", "arduino", "arff", "asciidoc", "asm6502", "asmatmel", "aspnet", "autohotkey", "autoit", "avisynth", "avro-idl", "bash", "basic", "batch", "bbcode", "bicep", "birb", "bison", "bnf", "brainfuck", "brightscript", "bro", "bsl", "c", "cfscript", "chaiscript", "cil", "clike", "clojure", "cmake", "cobol", "coffeescript", "concurnas", "coq", "core", "cpp", "crystal", "csharp", "cshtml", "csp", "css", "css-extras", "csv", "cypher", "d", "dart", "dataweave", "dax", "dhall", "diff", "django", "dns-zone-file", "docker", "dot", "ebnf", "editorconfig", "eiffel", "ejs", "elixir", "elm", "erb", "erlang", "etlua", "excel-formula", "factor", "false", "firestore-security-rules", "flow", "fortran", "fsharp", "ftl", "gap", "gcode", "gdscript", "gedcom", "gherkin", "git", "glsl", "gml", "gn", "go", "go-module", "graphql", "groovy", "haml", "handlebars", "haskell", "haxe", "hcl", "hlsl", "hoon", "hpkp", "hsts", "http", "ichigojam", "icon", "icu-message-format", "idris", "iecst", "ignore", "index", "inform7", "ini", "io", "j", "java", "javadoc", "javadoclike", "javascript", "javastacktrace", "jexl", "jolie", "jq", "js-extras", "js-templates", "jsdoc", "json", "json5", "jsonp", "jsstacktrace", "jsx", "julia", "keepalived", "keyman", "kotlin", "kumir", "kusto", "latex", "latte", "less", "lilypond", "liquid", "lisp", "livescript", "llvm", "log", "lolcode", "lua", "magma", "makefile", "markdown", "markup", "markup-templating", "matlab", "maxscript", "mel", "mermaid", "mizar", "mongodb", "monkey", "moonscript", "n1ql", "n4js", "nand2tetris-hdl", "naniscript", "nasm", "neon", "nevod", "nginx", "nim", "nix", "nsis", "objectivec", "ocaml", "opencl", "openqasm", "oz", "parigp", "parser", "pascal", "pascaligo", "pcaxis", "peoplecode", "perl", "php", "php-extras", "phpdoc", "plsql", "powerquery", "powershell", "processing", "prolog", "promql", "properties", "protobuf", "psl", "pug", "puppet", "pure", "purebasic", "purescript", "python", "q", "qml", "qore", "qsharp", "r", "racket", "reason", "regex", "rego", "renpy", "rest", "rip", "roboconf", "robotframework", "ruby", "rust", "sas", "sass", "scala", "scheme", "scss", "shell-session", "smali", "smalltalk", "smarty", "sml", "solidity", "solution-file", "soy", "sparql", "splunk-spl", "sqf", "sql", "squirrel", "stan", "stylus", "swift", "systemd", "t4-cs", "t4-templating", "t4-vb", "tap", "tcl", "textile", "toml", "tremor", "tsx", "tt2", "turtle", "twig", "typescript", "typoscript", "unrealscript", "uorazor", "uri", "v", "vala", "vbnet", "velocity", "verilog", "vhdl", "vim", "visual-basic", "warpscript", "wasm", "web-idl", "wiki", "wolfram", "wren", "xeora", "xml-doc", "xojo", "xquery", "yaml", "yang", "zig"].includes(_language)) { console.warn(`Language \`${_language}\` is not supported for code blocks inside of markdown.`); _language = ''; } else { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Language ${_language} is not supported for code blocks inside of markdown: `, error); } })(); } } ; return inline ? ( {children} ) : ( ); })""", + r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; if (_language) { if (!["abap", "abnf", "actionscript", "ada", "agda", "al", "antlr4", "apacheconf", "apex", "apl", "applescript", "aql", "arduino", "arff", "asciidoc", "asm6502", "asmatmel", "aspnet", "autohotkey", "autoit", "avisynth", "avro-idl", "bash", "basic", "batch", "bbcode", "bicep", "birb", "bison", "bnf", "brainfuck", "brightscript", "bro", "bsl", "c", "cfscript", "chaiscript", "cil", "clike", "clojure", "cmake", "cobol", "coffeescript", "concurnas", "coq", "core", "cpp", "crystal", "csharp", "cshtml", "csp", "css", "css-extras", "csv", "cypher", "d", "dart", "dataweave", "dax", "dhall", "diff", "django", "dns-zone-file", "docker", "dot", "ebnf", "editorconfig", "eiffel", "ejs", "elixir", "elm", "erb", "erlang", "etlua", "excel-formula", "factor", "false", "firestore-security-rules", "flow", "fortran", "fsharp", "ftl", "gap", "gcode", "gdscript", "gedcom", "gherkin", "git", "glsl", "gml", "gn", "go", "go-module", "graphql", "groovy", "haml", "handlebars", "haskell", "haxe", "hcl", "hlsl", "hoon", "hpkp", "hsts", "http", "ichigojam", "icon", "icu-message-format", "idris", "iecst", "ignore", "index", "inform7", "ini", "io", "j", "java", "javadoc", "javadoclike", "javascript", "javastacktrace", "jexl", "jolie", "jq", "js-extras", "js-templates", "jsdoc", "json", "json5", "jsonp", "jsstacktrace", "jsx", "julia", "keepalived", "keyman", "kotlin", "kumir", "kusto", "latex", "latte", "less", "lilypond", "liquid", "lisp", "livescript", "llvm", "log", "lolcode", "lua", "magma", "makefile", "markdown", "markup", "markup-templating", "matlab", "maxscript", "mel", "mermaid", "mizar", "mongodb", "monkey", "moonscript", "n1ql", "n4js", "nand2tetris-hdl", "naniscript", "nasm", "neon", "nevod", "nginx", "nim", "nix", "nsis", "objectivec", "ocaml", "opencl", "openqasm", "oz", "parigp", "parser", "pascal", "pascaligo", "pcaxis", "peoplecode", "perl", "php", "php-extras", "phpdoc", "plsql", "powerquery", "powershell", "processing", "prolog", "promql", "properties", "protobuf", "psl", "pug", "puppet", "pure", "purebasic", "purescript", "python", "q", "qml", "qore", "qsharp", "r", "racket", "reason", "regex", "rego", "renpy", "rest", "rip", "roboconf", "robotframework", "ruby", "rust", "sas", "sass", "scala", "scheme", "scss", "shell-session", "smali", "smalltalk", "smarty", "sml", "solidity", "solution-file", "soy", "sparql", "splunk-spl", "sqf", "sql", "squirrel", "stan", "stylus", "swift", "systemd", "t4-cs", "t4-templating", "t4-vb", "tap", "tcl", "textile", "toml", "tremor", "tsx", "tt2", "turtle", "twig", "typescript", "typoscript", "unrealscript", "uorazor", "uri", "v", "vala", "vbnet", "velocity", "verilog", "vhdl", "vim", "visual-basic", "warpscript", "wasm", "web-idl", "wiki", "wolfram", "wren", "xeora", "xml-doc", "xojo", "xquery", "yaml", "yang", "zig"].includes(_language)) { console.warn(`Language \`${_language}\` is not supported for code blocks inside of markdown.`); _language = ''; } else { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Language ${_language} is not supported for code blocks inside of markdown: `, error); } })(); } } ; return inline ? ( jsx(RadixThemesCode,{...props},children,) ) : ( jsx(SyntaxHighlighter,{children:((Array.isArray(children)) ? children.join("\n") : children),css:({ ["marginTop"] : "1em", ["marginBottom"] : "1em" }),customStyle:({ ["marginTop"] : "1em", ["marginBottom"] : "1em" }),language:_language,style:((resolvedColorMode === "light") ? oneLight : oneDark),wrapLongLines:true,...props},) ); })""", ), ( "code", @@ -157,7 +157,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe value, **props ) }, - r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", + r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( jsx(RadixThemesCode,{...props},children,) ) : ( jsx(RadixThemesBox,{css:({ ["pre"] : ({ ["margin"] : "0", ["padding"] : "24px", ["background"] : "transparent", ["overflowX"] : "auto", ["borderRadius"] : "6px" }) }),...props},jsx(ShikiCode,{code:((Array.isArray(children)) ? children.join("\n") : children),decorations:[],language:_language,theme:((resolvedColorMode === "light") ? "one-light" : "one-dark-pro"),transformers:[]},),) ); })""", ), ( "h1", @@ -166,12 +166,12 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe Heading.create(value, as_="h1", size="6", margin_y="0.5em") ) }, - """(({custom_node, custom_children, custom_props}) => ({children}))""", + """(({custom_node, custom_children, custom_props}) => (jsx(CustomMarkdownComponent,{...props},jsx(RadixThemesHeading,{as:"h1",css:({ ["marginTop"] : "0.5em", ["marginBottom"] : "0.5em" }),size:"6"},children,),)))""", ), ( "code", {"codeblock": syntax_highlighter_memoized_component(CodeBlock)}, - r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; if (_language) { if (!["abap", "abnf", "actionscript", "ada", "agda", "al", "antlr4", "apacheconf", "apex", "apl", "applescript", "aql", "arduino", "arff", "asciidoc", "asm6502", "asmatmel", "aspnet", "autohotkey", "autoit", "avisynth", "avro-idl", "bash", "basic", "batch", "bbcode", "bicep", "birb", "bison", "bnf", "brainfuck", "brightscript", "bro", "bsl", "c", "cfscript", "chaiscript", "cil", "clike", "clojure", "cmake", "cobol", "coffeescript", "concurnas", "coq", "core", "cpp", "crystal", "csharp", "cshtml", "csp", "css", "css-extras", "csv", "cypher", "d", "dart", "dataweave", "dax", "dhall", "diff", "django", "dns-zone-file", "docker", "dot", "ebnf", "editorconfig", "eiffel", "ejs", "elixir", "elm", "erb", "erlang", "etlua", "excel-formula", "factor", "false", "firestore-security-rules", "flow", "fortran", "fsharp", "ftl", "gap", "gcode", "gdscript", "gedcom", "gherkin", "git", "glsl", "gml", "gn", "go", "go-module", "graphql", "groovy", "haml", "handlebars", "haskell", "haxe", "hcl", "hlsl", "hoon", "hpkp", "hsts", "http", "ichigojam", "icon", "icu-message-format", "idris", "iecst", "ignore", "index", "inform7", "ini", "io", "j", "java", "javadoc", "javadoclike", "javascript", "javastacktrace", "jexl", "jolie", "jq", "js-extras", "js-templates", "jsdoc", "json", "json5", "jsonp", "jsstacktrace", "jsx", "julia", "keepalived", "keyman", "kotlin", "kumir", "kusto", "latex", "latte", "less", "lilypond", "liquid", "lisp", "livescript", "llvm", "log", "lolcode", "lua", "magma", "makefile", "markdown", "markup", "markup-templating", "matlab", "maxscript", "mel", "mermaid", "mizar", "mongodb", "monkey", "moonscript", "n1ql", "n4js", "nand2tetris-hdl", "naniscript", "nasm", "neon", "nevod", "nginx", "nim", "nix", "nsis", "objectivec", "ocaml", "opencl", "openqasm", "oz", "parigp", "parser", "pascal", "pascaligo", "pcaxis", "peoplecode", "perl", "php", "php-extras", "phpdoc", "plsql", "powerquery", "powershell", "processing", "prolog", "promql", "properties", "protobuf", "psl", "pug", "puppet", "pure", "purebasic", "purescript", "python", "q", "qml", "qore", "qsharp", "r", "racket", "reason", "regex", "rego", "renpy", "rest", "rip", "roboconf", "robotframework", "ruby", "rust", "sas", "sass", "scala", "scheme", "scss", "shell-session", "smali", "smalltalk", "smarty", "sml", "solidity", "solution-file", "soy", "sparql", "splunk-spl", "sqf", "sql", "squirrel", "stan", "stylus", "swift", "systemd", "t4-cs", "t4-templating", "t4-vb", "tap", "tcl", "textile", "toml", "tremor", "tsx", "tt2", "turtle", "twig", "typescript", "typoscript", "unrealscript", "uorazor", "uri", "v", "vala", "vbnet", "velocity", "verilog", "vhdl", "vim", "visual-basic", "warpscript", "wasm", "web-idl", "wiki", "wolfram", "wren", "xeora", "xml-doc", "xojo", "xquery", "yaml", "yang", "zig"].includes(_language)) { console.warn(`Language \`${_language}\` is not supported for code blocks inside of markdown.`); _language = ''; } else { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Language ${_language} is not supported for code blocks inside of markdown: `, error); } })(); } } ; return inline ? ( {children} ) : ( ); })""", + r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; if (_language) { if (!["abap", "abnf", "actionscript", "ada", "agda", "al", "antlr4", "apacheconf", "apex", "apl", "applescript", "aql", "arduino", "arff", "asciidoc", "asm6502", "asmatmel", "aspnet", "autohotkey", "autoit", "avisynth", "avro-idl", "bash", "basic", "batch", "bbcode", "bicep", "birb", "bison", "bnf", "brainfuck", "brightscript", "bro", "bsl", "c", "cfscript", "chaiscript", "cil", "clike", "clojure", "cmake", "cobol", "coffeescript", "concurnas", "coq", "core", "cpp", "crystal", "csharp", "cshtml", "csp", "css", "css-extras", "csv", "cypher", "d", "dart", "dataweave", "dax", "dhall", "diff", "django", "dns-zone-file", "docker", "dot", "ebnf", "editorconfig", "eiffel", "ejs", "elixir", "elm", "erb", "erlang", "etlua", "excel-formula", "factor", "false", "firestore-security-rules", "flow", "fortran", "fsharp", "ftl", "gap", "gcode", "gdscript", "gedcom", "gherkin", "git", "glsl", "gml", "gn", "go", "go-module", "graphql", "groovy", "haml", "handlebars", "haskell", "haxe", "hcl", "hlsl", "hoon", "hpkp", "hsts", "http", "ichigojam", "icon", "icu-message-format", "idris", "iecst", "ignore", "index", "inform7", "ini", "io", "j", "java", "javadoc", "javadoclike", "javascript", "javastacktrace", "jexl", "jolie", "jq", "js-extras", "js-templates", "jsdoc", "json", "json5", "jsonp", "jsstacktrace", "jsx", "julia", "keepalived", "keyman", "kotlin", "kumir", "kusto", "latex", "latte", "less", "lilypond", "liquid", "lisp", "livescript", "llvm", "log", "lolcode", "lua", "magma", "makefile", "markdown", "markup", "markup-templating", "matlab", "maxscript", "mel", "mermaid", "mizar", "mongodb", "monkey", "moonscript", "n1ql", "n4js", "nand2tetris-hdl", "naniscript", "nasm", "neon", "nevod", "nginx", "nim", "nix", "nsis", "objectivec", "ocaml", "opencl", "openqasm", "oz", "parigp", "parser", "pascal", "pascaligo", "pcaxis", "peoplecode", "perl", "php", "php-extras", "phpdoc", "plsql", "powerquery", "powershell", "processing", "prolog", "promql", "properties", "protobuf", "psl", "pug", "puppet", "pure", "purebasic", "purescript", "python", "q", "qml", "qore", "qsharp", "r", "racket", "reason", "regex", "rego", "renpy", "rest", "rip", "roboconf", "robotframework", "ruby", "rust", "sas", "sass", "scala", "scheme", "scss", "shell-session", "smali", "smalltalk", "smarty", "sml", "solidity", "solution-file", "soy", "sparql", "splunk-spl", "sqf", "sql", "squirrel", "stan", "stylus", "swift", "systemd", "t4-cs", "t4-templating", "t4-vb", "tap", "tcl", "textile", "toml", "tremor", "tsx", "tt2", "turtle", "twig", "typescript", "typoscript", "unrealscript", "uorazor", "uri", "v", "vala", "vbnet", "velocity", "verilog", "vhdl", "vim", "visual-basic", "warpscript", "wasm", "web-idl", "wiki", "wolfram", "wren", "xeora", "xml-doc", "xojo", "xquery", "yaml", "yang", "zig"].includes(_language)) { console.warn(`Language \`${_language}\` is not supported for code blocks inside of markdown.`); _language = ''; } else { (async () => { try { const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${_language}`); SyntaxHighlighter.registerLanguage(_language, module.default); } catch (error) { console.error(`Language ${_language} is not supported for code blocks inside of markdown: `, error); } })(); } } ; return inline ? ( jsx(RadixThemesCode,{...props},children,) ) : ( jsx(CodeBlock,{code:((Array.isArray(children)) ? children.join("\n") : children),language:_language,...props},) ); })""", ), ( "code", @@ -180,7 +180,7 @@ def test_create_map_fn_var_subclass(cls, fn_body, fn_args, explicit_return, expe ShikiHighLevelCodeBlock ) }, - r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( {children} ) : ( ); })""", + r"""(({node, inline, className, children, ...props}) => { const match = (className || '').match(/language-(?.*)/); let _language = match ? match[1] : ''; ; return inline ? ( jsx(RadixThemesCode,{...props},children,) ) : ( jsx(CodeBlock,{code:((Array.isArray(children)) ? children.join("\n") : children),language:_language,...props},) ); })""", ), ], ) diff --git a/tests/units/components/test_component.py b/tests/units/components/test_component.py index 50b597b7eda..c3fa3c429eb 100644 --- a/tests/units/components/test_component.py +++ b/tests/units/components/test_component.py @@ -685,14 +685,14 @@ def test_component_create_unallowed_types(children, test_component): "children": [ { "name": "RadixThemesText", - "props": ['as={"p"}'], + "props": ['as:"p"'], "contents": "", "special_props": [], "children": [ { "name": "", "props": [], - "contents": '{"first_text"}', + "contents": '"first_text"', "special_props": [], "children": [], "autofocus": False, @@ -715,7 +715,7 @@ def test_component_create_unallowed_types(children, test_component): { "autofocus": False, "children": [], - "contents": '{"first_text"}', + "contents": '"first_text"', "name": "", "props": [], "special_props": [], @@ -723,7 +723,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ['as={"p"}'], + "props": ['as:"p"'], "special_props": [], }, { @@ -732,7 +732,7 @@ def test_component_create_unallowed_types(children, test_component): { "autofocus": False, "children": [], - "contents": '{"second_text"}', + "contents": '"second_text"', "name": "", "props": [], "special_props": [], @@ -740,7 +740,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ['as={"p"}'], + "props": ['as:"p"'], "special_props": [], }, ], @@ -761,7 +761,7 @@ def test_component_create_unallowed_types(children, test_component): { "autofocus": False, "children": [], - "contents": '{"first_text"}', + "contents": '"first_text"', "name": "", "props": [], "special_props": [], @@ -769,7 +769,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ['as={"p"}'], + "props": ['as:"p"'], "special_props": [], }, { @@ -784,7 +784,7 @@ def test_component_create_unallowed_types(children, test_component): { "autofocus": False, "children": [], - "contents": '{"second_text"}', + "contents": '"second_text"', "name": "", "props": [], "special_props": [], @@ -792,7 +792,7 @@ def test_component_create_unallowed_types(children, test_component): ], "contents": "", "name": "RadixThemesText", - "props": ['as={"p"}'], + "props": ['as:"p"'], "special_props": [], } ], @@ -1162,10 +1162,10 @@ def test_component_with_only_valid_children(fixture, request): @pytest.mark.parametrize( "component,rendered", [ - (rx.text("hi"), '\n\n{"hi"}\n'), + (rx.text("hi"), 'jsx(\nRadixThemesText,\n{as:"p"},\n"hi"\n,)'), ( rx.box(rx.heading("test", size="3")), - '\n\n\n\n{"test"}\n\n', + 'jsx(\nRadixThemesBox,\n{},\njsx(\nRadixThemesHeading,\n{size:"3"},\n"test"\n,),)', ), ], ) @@ -1770,14 +1770,14 @@ class C2(C1): c1 = C1.create(prop1="prop1_1", prop2="prop2_1") rendered_c1 = c1.render() - assert 'renamed_prop1={"prop1_1"}' in rendered_c1["props"] - assert 'renamed_prop2={"prop2_1"}' in rendered_c1["props"] + assert 'renamed_prop1:"prop1_1"' in rendered_c1["props"] + assert 'renamed_prop2:"prop2_1"' in rendered_c1["props"] c2 = C2.create(prop1="prop1_2", prop2="prop2_2", prop3="prop3_2") rendered_c2 = c2.render() - assert 'renamed_prop1={"prop1_2"}' in rendered_c2["props"] - assert 'subclass_prop2={"prop2_2"}' in rendered_c2["props"] - assert 'renamed_prop3={"prop3_2"}' in rendered_c2["props"] + assert 'renamed_prop1:"prop1_2"' in rendered_c2["props"] + assert 'subclass_prop2:"prop2_2"' in rendered_c2["props"] + assert 'renamed_prop3:"prop3_2"' in rendered_c2["props"] def test_custom_component_get_imports(): @@ -2161,7 +2161,7 @@ def add_style(self): # pyright: ignore [reportIncompatibleMethodOverride] assert "useParent" in page._get_all_hooks_internal() assert ( str(page).count( - f'css={{({{ ["fakeParent"] : "parent", ["color"] : "var(--plum-10)", ["fake"] : "text", ["margin"] : ({test_state.get_name()}.num+"%") }})}}' + f'css:({{ ["fakeParent"] : "parent", ["color"] : "var(--plum-10)", ["fake"] : "text", ["margin"] : ({test_state.get_name()}.num+"%") }})' ) == 1 ) @@ -2182,10 +2182,10 @@ def add_style(self): assert len(page.children[0].children) == 1 # Expect the style to be added to the child of the foreach - assert 'css={({ ["color"] : "red" })}' in str(page.children[0].children[0]) + assert 'css:({ ["color"] : "red" })' in str(page.children[0].children[0]) # Expect only one instance of this CSS dict in the rendered page - assert str(page).count('css={({ ["color"] : "red" })}') == 1 + assert str(page).count('css:({ ["color"] : "red" })') == 1 class TriggerState(rx.State): diff --git a/tests/units/components/test_tag.py b/tests/units/components/test_tag.py index c31f9157ee4..b3ff2b8edc7 100644 --- a/tests/units/components/test_tag.py +++ b/tests/units/components/test_tag.py @@ -8,10 +8,10 @@ "props,test_props", [ ({}, []), - ({"key-hypen": 1}, ["key-hypen={1}"]), - ({"key": 1}, ["key={1}"]), - ({"key": "value"}, ['key={"value"}']), - ({"key": True, "key2": "value2"}, ["key={true}", 'key2={"value2"}']), + ({"key-hypen": 1}, ['"key-hypen":1']), + ({"key": 1}, ["key:1"]), + ({"key": "value"}, ['key:"value"']), + ({"key": True, "key2": "value2"}, ["key:true", 'key2:"value2"']), ], ) def test_format_props(props: dict[str, Var], test_props: list): diff --git a/tests/units/test_app.py b/tests/units/test_app.py index 2df12b2518f..354fd56bd42 100644 --- a/tests/units/test_app.py +++ b/tests/units/test_app.py @@ -1370,20 +1370,17 @@ def page(): lines = "".join(app_js_lines) assert ( "function AppWrap({children}) {" - "return (" + ("" if react_strict_mode else "") + "" - '' - "" - "" - "" - "" - "" + "return (" + + ("jsx(StrictMode,{}," if react_strict_mode else "") + + "jsx(RadixThemesBox,{}," + 'jsx(RadixThemesText,{as:"p"},' + "jsx(RadixThemesColorModeProvider,{}," + "jsx(Fragment2,{}," + "jsx(Fragment,{}," + "jsx(MemoizedToastProvider,{},)" + "jsx(Fragment,{}," "{children}" - "" - "" - "" - "" - "" - "" + ("" if react_strict_mode else "") + ",),),),),)" + (")" if react_strict_mode else "") ) in lines diff --git a/tests/units/utils/test_format.py b/tests/units/utils/test_format.py index 776613a21cb..e2387c60d87 100644 --- a/tests/units/utils/test_format.py +++ b/tests/units/utils/test_format.py @@ -457,7 +457,7 @@ def test_format_match( _js_expr=f"(({{node, ...props}}) => )" ), }, - '({ ["h1"] : (({node, ...props}) => ) })', + '({ ["h1"] : (({node, ...props}) => ) })', ), ], ) @@ -475,9 +475,9 @@ def test_format_prop(prop: Var, formatted: str): "single_props,key_value_props,output", [ ( - [Var(_js_expr="{...props}")], + [Var(_js_expr="props")], {"key": 42}, - ["key={42}", "{...props}"], + ["key:42", "...props"], ), ], ) From b5c8e3459d9df415da29759b318cf94f26bfaba6 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:27:54 -0700 Subject: [PATCH 03/16] use v1 for that field --- pyi_hashes.json | 220 +++++++++++------------ reflex/components/component.py | 4 +- reflex/components/el/element.py | 4 +- reflex/utils/pyi_generator.py | 1 + tests/units/components/base/test_link.py | 4 +- tests/units/components/core/test_html.py | 6 +- tests/units/test_app.py | 40 ++--- 7 files changed, 141 insertions(+), 138 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 3e53856c083..403c2491319 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -2,125 +2,125 @@ "reflex/__init__.pyi": "8a6d2350e96659846436792a5c7b772b", "reflex/components/__init__.pyi": "76ba0a12cd3a7ba5ab6341a3ae81551f", "reflex/components/base/__init__.pyi": "e9aaf47be1e1977eacee97b880c8f7de", - "reflex/components/base/app_wrap.pyi": "a0f6cec6b4720a74ec9da07baf93689e", - "reflex/components/base/body.pyi": "31944453e355e0634345bc6367d7becf", - "reflex/components/base/document.pyi": "90f89615087fe6e60f68bf60177d4768", - "reflex/components/base/error_boundary.pyi": "2cf73e45744f167b07c876d75aa95707", - "reflex/components/base/fragment.pyi": "c44c7d12b412b93e21ecd758103a81cc", - "reflex/components/base/head.pyi": "b565801fb04f5be8c3f63b9115330fe3", - "reflex/components/base/link.pyi": "36df1ab367d65ebee66b0edf974b0833", - "reflex/components/base/meta.pyi": "4b384b1bc25120e09573deea6a39de01", - "reflex/components/base/script.pyi": "3e66ec86de09316d72f128878d9db2c0", - "reflex/components/base/strict_mode.pyi": "ccc408f6d640ba553cb545842bd7f33a", + "reflex/components/base/app_wrap.pyi": "387fc7a0c2da8760d9449e2893e44eec", + "reflex/components/base/body.pyi": "2cc870cec4b1c28081dd40467752c2b7", + "reflex/components/base/document.pyi": "30377cdfb02b564f8de29b0473d2346c", + "reflex/components/base/error_boundary.pyi": "c56b591d14a92b99a1e97e04afe167d7", + "reflex/components/base/fragment.pyi": "603ee8e03af88d4a8ff6bc1fbce4e022", + "reflex/components/base/head.pyi": "893047aa32da553711db8f1345adb6b0", + "reflex/components/base/link.pyi": "396488afa3b7a5b0d0e6c5e89159f857", + "reflex/components/base/meta.pyi": "bc4b4fda6f022a517de339ffdd667e3b", + "reflex/components/base/script.pyi": "530cf8f47eb90082bf65942e8b5d745f", + "reflex/components/base/strict_mode.pyi": "d972e0ff2a6f961e7df90fc27b8bb51b", "reflex/components/core/__init__.pyi": "44bcee7bc4e27e2f4f4707b843acf291", - "reflex/components/core/auto_scroll.pyi": "910fc1962bf7688845f2420b66a7d2f5", - "reflex/components/core/banner.pyi": "b715bee1e2d4fbc13426120d09383b6f", - "reflex/components/core/client_side_routing.pyi": "ffc8b71f3f34fe6b165eefdb85c269ca", - "reflex/components/core/clipboard.pyi": "90120e2a738267b970d1db9d25b26258", - "reflex/components/core/debounce.pyi": "aefd587b00ec73860e1fca5bd9c842cf", - "reflex/components/core/html.pyi": "63fb3751eafb9165bfbdff57b19801df", - "reflex/components/core/sticky.pyi": "f2678e6425d15dcfaf1a957399f71ed3", - "reflex/components/core/upload.pyi": "3cb7b941f50f796771e959a557089105", + "reflex/components/core/auto_scroll.pyi": "d3012d2a4ccaab8dfebf9aa484020f59", + "reflex/components/core/banner.pyi": "48d0eb86ae09e806ebe20d0edcc3cdb3", + "reflex/components/core/client_side_routing.pyi": "9be638a2b0e00b8181697e5dd6b45e4e", + "reflex/components/core/clipboard.pyi": "af76b623d593df3b16162033c597f920", + "reflex/components/core/debounce.pyi": "76d857eb814bc64625860a5f43e8b230", + "reflex/components/core/html.pyi": "b12117b42ef79ee90b6b4dec50baeb86", + "reflex/components/core/sticky.pyi": "c65131cf7c2312c68e1fddaa0cc27150", + "reflex/components/core/upload.pyi": "6fb89607ec8f8c1971f0dbd3453901eb", "reflex/components/datadisplay/__init__.pyi": "cf087efa8b3960decc6b231cc986cfa9", - "reflex/components/datadisplay/code.pyi": "e549ccf8d3be9c74fc469812add873de", - "reflex/components/datadisplay/dataeditor.pyi": "d21f979ddc52f78f9d8ecbc95ebc59bb", - "reflex/components/datadisplay/shiki_code_block.pyi": "95a2248975fd4b13403822a2e42efef7", + "reflex/components/datadisplay/code.pyi": "3d8f0ab4c2f123d7f80d15c7ebc553d9", + "reflex/components/datadisplay/dataeditor.pyi": "1b762071001161e4fdd1285263c33bb3", + "reflex/components/datadisplay/shiki_code_block.pyi": "87db7639bfa5cd53e1709e1363f93278", "reflex/components/el/__init__.pyi": "09042a2db5e0637e99b5173430600522", - "reflex/components/el/element.pyi": "5b5bd985dff50cafbad97eeb2996b0fb", + "reflex/components/el/element.pyi": "6d739982d5d7842892745ef520887bb9", "reflex/components/el/elements/__init__.pyi": "280ed457675f3720e34b560a3f617739", - "reflex/components/el/elements/base.pyi": "37e6bf1cdfa91cb35e2e71e14eab47b0", - "reflex/components/el/elements/forms.pyi": "eeb2d67c4001f298aeaa357b87c3aa2f", - "reflex/components/el/elements/inline.pyi": "7635236cf7fb232df91f76934411faf5", - "reflex/components/el/elements/media.pyi": "bfcf42e75669e576b2592bea57d515de", - "reflex/components/el/elements/metadata.pyi": "a6bc43936b93fa942b13d20de3863187", - "reflex/components/el/elements/other.pyi": "1a0c081680c03fd239e20b7e9e2562af", - "reflex/components/el/elements/scripts.pyi": "198e81956b09eb09bcb9856490200e1c", - "reflex/components/el/elements/sectioning.pyi": "0a8bd8e9b5e55fbe2b0ee2991ef19517", - "reflex/components/el/elements/tables.pyi": "2076ac4b4fdc5828d83c487bc0109468", - "reflex/components/el/elements/typography.pyi": "2de860327da0aece2463355182f8fd59", - "reflex/components/gridjs/datatable.pyi": "4e49539ef1f9dc7028838a949f34e8de", - "reflex/components/lucide/icon.pyi": "2e080b6bdb523e411b93388869e2e2e4", - "reflex/components/markdown/markdown.pyi": "4e6d4c59bd18417f9e3cac44d25aef27", - "reflex/components/moment/moment.pyi": "191e390c325519dc06a26a006241a268", - "reflex/components/next/base.pyi": "fb613338a9961b649c0a510942b5ea77", - "reflex/components/next/image.pyi": "23436bb61a23c525bf5c66604940889c", - "reflex/components/next/link.pyi": "6cdd6ee1ed0d9027c39e2b8099b536a7", - "reflex/components/next/video.pyi": "01b594b145bccb2270df79e792914144", - "reflex/components/plotly/plotly.pyi": "3d29b6447fc96f437474a5ba2ce477dc", + "reflex/components/el/elements/base.pyi": "6e533348b5e1a88cf62fbb5a38dbd795", + "reflex/components/el/elements/forms.pyi": "2e7ab39bc7295b8594f38a2aa59c9610", + "reflex/components/el/elements/inline.pyi": "33d9d860e75dd8c4769825127ed363bb", + "reflex/components/el/elements/media.pyi": "addd6872281d65d44a484358b895432f", + "reflex/components/el/elements/metadata.pyi": "a5b9b30c4649e88aa26a1a5609fc86ef", + "reflex/components/el/elements/other.pyi": "995a4fbf10bfdb7f48808210dfe413bd", + "reflex/components/el/elements/scripts.pyi": "cd5bd53c3a6b016fbb913aff36d63344", + "reflex/components/el/elements/sectioning.pyi": "65aa53b1372598ec1785616cb7016032", + "reflex/components/el/elements/tables.pyi": "e1282d8ddf4efa4c911ca104a907ee88", + "reflex/components/el/elements/typography.pyi": "00088c9c1b68a14e5a41d837e8fdf542", + "reflex/components/gridjs/datatable.pyi": "7fd1dd65ba143d60b7d42d1bb90a179d", + "reflex/components/lucide/icon.pyi": "a5521a8baf8d2d7281e3fdfe6ce7073b", + "reflex/components/markdown/markdown.pyi": "70c84b8340bf2bc94c2230f1d319ba27", + "reflex/components/moment/moment.pyi": "6dd0c7cee5f0f29bc11d830c697d7f92", + "reflex/components/next/base.pyi": "14aafd5b018a4bc9748a3c9980fcfe3e", + "reflex/components/next/image.pyi": "3a0d1970e69144e9c6806e68ab99f181", + "reflex/components/next/link.pyi": "cd913e10205314afe67101d9640e05cb", + "reflex/components/next/video.pyi": "09698418db651917630a7fefeb573fc2", + "reflex/components/plotly/plotly.pyi": "77afe88b405c3eae7058994d53a27946", "reflex/components/radix/__init__.pyi": "8d586cbff1d7130d09476ac72ee73400", "reflex/components/radix/primitives/__init__.pyi": "fe8715decf3e9ae471b56bba14e42cb3", - "reflex/components/radix/primitives/accordion.pyi": "1b2c94923fd20df8450b8a2887e7b3ed", - "reflex/components/radix/primitives/base.pyi": "37f923bf6476bb7e159e984df7c1d6ab", - "reflex/components/radix/primitives/drawer.pyi": "0aaaceed3457b179919b81618e9d3018", - "reflex/components/radix/primitives/form.pyi": "84b02eb4ddc13904ca3f339365164bae", - "reflex/components/radix/primitives/progress.pyi": "78e124e9fedefb58452f23f791200be1", - "reflex/components/radix/primitives/slider.pyi": "59cd03d41414bd4cc2e1995a3c4e9a98", + "reflex/components/radix/primitives/accordion.pyi": "b1482766c3c99ab40c2f446598fdb6a7", + "reflex/components/radix/primitives/base.pyi": "8b1dbf0b75cb29e873d611b83c9e4156", + "reflex/components/radix/primitives/drawer.pyi": "b6f8b17e1d0064d5609915546c722a81", + "reflex/components/radix/primitives/form.pyi": "79ddb679e0b3df814439ce993fcf355e", + "reflex/components/radix/primitives/progress.pyi": "c62a0c44e0d440701174fcca93bf8fbe", + "reflex/components/radix/primitives/slider.pyi": "c27e1a1180442e2e6e9d727560e8068c", "reflex/components/radix/themes/__init__.pyi": "a15f9464ad99f248249ffa8e6deea4cf", - "reflex/components/radix/themes/base.pyi": "7095c0f13d5cf741d35a86218603cea0", - "reflex/components/radix/themes/color_mode.pyi": "cc764eb8a379187bcd3956a8033515fe", + "reflex/components/radix/themes/base.pyi": "a3c3c3b72fd3d8f1e38990e5c461b682", + "reflex/components/radix/themes/color_mode.pyi": "435a51382eab6111aae1b26e79e9a473", "reflex/components/radix/themes/components/__init__.pyi": "87bb9ffff641928562da1622d2ca5993", - "reflex/components/radix/themes/components/alert_dialog.pyi": "da5f6d1964de97699475f36900dd8600", - "reflex/components/radix/themes/components/aspect_ratio.pyi": "e9aea8ef0fa5a836025d330b8c57eb5f", - "reflex/components/radix/themes/components/avatar.pyi": "f916df93eba7cac5b0cc965b87b44346", - "reflex/components/radix/themes/components/badge.pyi": "563530aec38d6876501e02a742b1fa1c", - "reflex/components/radix/themes/components/button.pyi": "cca75329c397ccd1de87d8152267ec08", - "reflex/components/radix/themes/components/callout.pyi": "8c6f287e51496211fbe288bf08c39b03", - "reflex/components/radix/themes/components/card.pyi": "a9cc503df3c48829707133cdc92aa949", - "reflex/components/radix/themes/components/checkbox.pyi": "b78678c703cc1077b61e00826c4d980c", - "reflex/components/radix/themes/components/checkbox_cards.pyi": "f403ba28ef114b0ba383a9da163f4646", - "reflex/components/radix/themes/components/checkbox_group.pyi": "4a4304303ec3e472b27033d1e4e7aff6", - "reflex/components/radix/themes/components/context_menu.pyi": "ed247dbad20b776ef7e84103959d2145", - "reflex/components/radix/themes/components/data_list.pyi": "02801c3469d4791b6e4bf81d3423ea4f", - "reflex/components/radix/themes/components/dialog.pyi": "1ad7fa0f8870b054043fb173cf7f7b0b", - "reflex/components/radix/themes/components/dropdown_menu.pyi": "ea706472643df6002fa9a406e9f07fda", - "reflex/components/radix/themes/components/hover_card.pyi": "8cdd1ace5804e7ed228fa74aeb565a0c", - "reflex/components/radix/themes/components/icon_button.pyi": "434b49b2a3785dcd08d2195fa509ca17", - "reflex/components/radix/themes/components/inset.pyi": "8baaf94a1e93fbc8821e798fe43e3a33", - "reflex/components/radix/themes/components/popover.pyi": "af71f2cbeb1b78ef3298e8e8a18dee65", - "reflex/components/radix/themes/components/progress.pyi": "05f654e57684a3aa9da9705c51ba0855", - "reflex/components/radix/themes/components/radio.pyi": "b53b2ac19b7bd2f5b060263242d50f49", - "reflex/components/radix/themes/components/radio_cards.pyi": "88aede2b5e1798aed3e46844c365fc61", - "reflex/components/radix/themes/components/radio_group.pyi": "78bab4a733b71d07118e3dfaaca78c04", - "reflex/components/radix/themes/components/scroll_area.pyi": "17ec4bcdf4a676c44ae4c78cff55dee6", - "reflex/components/radix/themes/components/segmented_control.pyi": "28d2f82b3ede4fadbb0d10bbae27dfe6", - "reflex/components/radix/themes/components/select.pyi": "37eeed2e6b9bef221c95a7cbd025825a", - "reflex/components/radix/themes/components/separator.pyi": "6114ecfac62066a7d7852e7a8b151e30", - "reflex/components/radix/themes/components/skeleton.pyi": "3d36c3f06acc08f6cafd081581a54d0d", - "reflex/components/radix/themes/components/slider.pyi": "980c1923daf7f7fe8017dfdb16cff76f", - "reflex/components/radix/themes/components/spinner.pyi": "c77fe930dd1199566c1af87892773421", - "reflex/components/radix/themes/components/switch.pyi": "343394fafb76b0404db4b14476585400", - "reflex/components/radix/themes/components/table.pyi": "8182636894f3614021085977d9c137b5", - "reflex/components/radix/themes/components/tabs.pyi": "b8174587123f3a91bffcc5aff9b2c8fe", - "reflex/components/radix/themes/components/text_area.pyi": "9f47d56ace353d3828280d10882e23e6", - "reflex/components/radix/themes/components/text_field.pyi": "ab77baabba267136d34c0cb0771f2722", - "reflex/components/radix/themes/components/tooltip.pyi": "6317337c8ffd694e0bf1795c69b0e604", + "reflex/components/radix/themes/components/alert_dialog.pyi": "8e1dde62450296310a116ed066bd51e3", + "reflex/components/radix/themes/components/aspect_ratio.pyi": "1845813a034adfc1f5db8e0f6ffc1118", + "reflex/components/radix/themes/components/avatar.pyi": "b591cb8b31d5a9aea5413120a6a744d9", + "reflex/components/radix/themes/components/badge.pyi": "5e8f49fd9ff10c756d9afa54bfd3fd10", + "reflex/components/radix/themes/components/button.pyi": "201448dcdf735f24d8bd21112039c1ca", + "reflex/components/radix/themes/components/callout.pyi": "e2b5828f271a2d790e88bb965d0fcded", + "reflex/components/radix/themes/components/card.pyi": "fe42e0cbdf9eb34341f4bbba8a586b34", + "reflex/components/radix/themes/components/checkbox.pyi": "78bc26eabd6468a44f5139449a2c6208", + "reflex/components/radix/themes/components/checkbox_cards.pyi": "cc43c568aa42ffa3e693e5cd1acba156", + "reflex/components/radix/themes/components/checkbox_group.pyi": "e36603b9ea5f161070c5a0235c4411fa", + "reflex/components/radix/themes/components/context_menu.pyi": "cdf546723a84c99412d91ca63d4bb2df", + "reflex/components/radix/themes/components/data_list.pyi": "768e4c9222d37d90228309166a1c6ab3", + "reflex/components/radix/themes/components/dialog.pyi": "b51cb34dc6c90ccd07a2f9fc97eaf1c1", + "reflex/components/radix/themes/components/dropdown_menu.pyi": "34807c4ab4665932da664ab68dab0edf", + "reflex/components/radix/themes/components/hover_card.pyi": "cfa947d1edec4b17dc6f227783ca1cbc", + "reflex/components/radix/themes/components/icon_button.pyi": "560cc3a95a8f1a396c8c5fb916b0ee8b", + "reflex/components/radix/themes/components/inset.pyi": "828f3d3a5b8f7fd07597069c01aaa0a0", + "reflex/components/radix/themes/components/popover.pyi": "c953a42260a3b261eec772dba716d951", + "reflex/components/radix/themes/components/progress.pyi": "c880c6bb9803d47048f656dfa66a7c15", + "reflex/components/radix/themes/components/radio.pyi": "36fa5585440685a7d2dff40b50502840", + "reflex/components/radix/themes/components/radio_cards.pyi": "e9a0f27119322e6148946ae178edb7a9", + "reflex/components/radix/themes/components/radio_group.pyi": "ea3180940390e4b6eaf10670be5bc2fe", + "reflex/components/radix/themes/components/scroll_area.pyi": "83892be0b2c902d2147cbdb5e19310ab", + "reflex/components/radix/themes/components/segmented_control.pyi": "7be200991becc54cd885465656e2dfef", + "reflex/components/radix/themes/components/select.pyi": "655a5c2182a16121440e5ddbba2079d8", + "reflex/components/radix/themes/components/separator.pyi": "58a95aca75a556d349eb56f898bde680", + "reflex/components/radix/themes/components/skeleton.pyi": "d91615706e5efb81d97755decbbf5ae3", + "reflex/components/radix/themes/components/slider.pyi": "b87ee08b7edfe41eddf3d3c1cb71124e", + "reflex/components/radix/themes/components/spinner.pyi": "80766a7324b582221edb66ec46da0acb", + "reflex/components/radix/themes/components/switch.pyi": "f8256d2b50d15ab163649cfb05229750", + "reflex/components/radix/themes/components/table.pyi": "560ce8d920e03b450fe6b938f5f0fea0", + "reflex/components/radix/themes/components/tabs.pyi": "96ac1082651d2adc2a60a3af6e90c17f", + "reflex/components/radix/themes/components/text_area.pyi": "418d3df53eeca0723d83a93d81f16b12", + "reflex/components/radix/themes/components/text_field.pyi": "cdf0e08f5af0a5fce6b31787001f1dc3", + "reflex/components/radix/themes/components/tooltip.pyi": "6cd225ba10140e925752c74404336f27", "reflex/components/radix/themes/layout/__init__.pyi": "9a52c5b283c864be70b51a8fd6120392", - "reflex/components/radix/themes/layout/base.pyi": "71934715b95cf677a79f8edb01209ba7", - "reflex/components/radix/themes/layout/box.pyi": "c5bcdcb7dd12e9a0e93b75ae9b3994ba", - "reflex/components/radix/themes/layout/center.pyi": "3031951d02347bf3cc7193ad614a0bbd", - "reflex/components/radix/themes/layout/container.pyi": "6dae0e49852122dfde1676351da29318", - "reflex/components/radix/themes/layout/flex.pyi": "26cc246595e32eefe6a4086a12dd5bb0", - "reflex/components/radix/themes/layout/grid.pyi": "dd7f5386d7b1dc268ad4de12154c6b85", - "reflex/components/radix/themes/layout/list.pyi": "20452aba8b9070395d4ce52b505a4616", - "reflex/components/radix/themes/layout/section.pyi": "28e7ea38e30a7b2b8a32b830f5651700", - "reflex/components/radix/themes/layout/spacer.pyi": "b22099a7e172f961449a9d9f79a9c342", - "reflex/components/radix/themes/layout/stack.pyi": "55a3f5d8200213113671a9526336b10f", + "reflex/components/radix/themes/layout/base.pyi": "e9a5c1f376e66653ebcf5d2315f990f8", + "reflex/components/radix/themes/layout/box.pyi": "5a3c2339d74cc062358ec32b2c2c138c", + "reflex/components/radix/themes/layout/center.pyi": "29bde2c21a190ba7d7a382a1157f5aa7", + "reflex/components/radix/themes/layout/container.pyi": "4020c3dca660027b84d11cc4198393c4", + "reflex/components/radix/themes/layout/flex.pyi": "f814281a5635ad43dd1df23f8e356c66", + "reflex/components/radix/themes/layout/grid.pyi": "6062188367a2c253f014f916197c963d", + "reflex/components/radix/themes/layout/list.pyi": "804f7a36c103cd7a3e362d40a58e8d39", + "reflex/components/radix/themes/layout/section.pyi": "41895910072e023ed0fef6a8ad956046", + "reflex/components/radix/themes/layout/spacer.pyi": "029eb0eaa731bcdff7c496e0437e22b1", + "reflex/components/radix/themes/layout/stack.pyi": "3b0da99b00c826d087ed89fc67c595c1", "reflex/components/radix/themes/typography/__init__.pyi": "ef0ba71353dcac1f3546de45f8721bae", - "reflex/components/radix/themes/typography/blockquote.pyi": "a326dbbbcc9e18b169b890f5ca65c948", - "reflex/components/radix/themes/typography/code.pyi": "47924c83992d00d4b6591239699567c9", - "reflex/components/radix/themes/typography/heading.pyi": "ef62b00dd291c878694e6f0ca76aabee", - "reflex/components/radix/themes/typography/link.pyi": "6e77ce1e2aed7b9d32d03b9490fbf1dd", - "reflex/components/radix/themes/typography/text.pyi": "8cac5c3e5b0100f22abf6b514b64f632", - "reflex/components/react_player/audio.pyi": "6e4090f9cb3cde651d6690627ed994ff", - "reflex/components/react_player/react_player.pyi": "70c98e2e8893d7bc8f889c1f86e80a5b", - "reflex/components/react_player/video.pyi": "d77968489205a1e1e0aba52c5401381d", + "reflex/components/radix/themes/typography/blockquote.pyi": "8ed6f1c5aa86743d1fb9488334af64fe", + "reflex/components/radix/themes/typography/code.pyi": "85e869bb61e3e0da9c244aea78e14193", + "reflex/components/radix/themes/typography/heading.pyi": "5a3b0b8e44bda0fce22c6b1a1f25e68e", + "reflex/components/radix/themes/typography/link.pyi": "45965d95b9f9b76f8f4a3084a5430194", + "reflex/components/radix/themes/typography/text.pyi": "e6aa0ca43ebbd42701a3c72c0312032e", + "reflex/components/react_player/audio.pyi": "972975ed0ba3e1dc4a867da20b11ae8e", + "reflex/components/react_player/react_player.pyi": "63ffffbc24907103f797dcfd85894107", + "reflex/components/react_player/video.pyi": "35ce5ad62e8bff17d9c09d27c362f8dc", "reflex/components/recharts/__init__.pyi": "a52c9055e37c6ee25ded15688d45e8a5", - "reflex/components/recharts/cartesian.pyi": "95548440902dd4e356359009abf59371", - "reflex/components/recharts/charts.pyi": "8f568c3c5d79f5bd66a32babf4cd91ec", - "reflex/components/recharts/general.pyi": "ba7d3ad8836ee79efe6db00b119470ae", - "reflex/components/recharts/polar.pyi": "b7c130eaacd6892a8b499b26a24df76a", - "reflex/components/recharts/recharts.pyi": "041dc0bee1254b858261699ba50eea0b", - "reflex/components/sonner/toast.pyi": "a3832c9229703fa4a89e86b9f4753eee", - "reflex/components/suneditor/editor.pyi": "57653e4673ac4045da5ebb6c875e6f92", - "reflex/experimental/layout.pyi": "2e09a7d3535d72155a4ecdecc865f3ba" + "reflex/components/recharts/cartesian.pyi": "34b15e8f5125b5a8145e3e04ed6418e4", + "reflex/components/recharts/charts.pyi": "b3d35de9cea86307ad2ab7d69ff2d06b", + "reflex/components/recharts/general.pyi": "5548fc494c29063c262ca7a7ef51dce8", + "reflex/components/recharts/polar.pyi": "8fb87fd69c9edf55998f11ea8ada76fb", + "reflex/components/recharts/recharts.pyi": "157acc830323075ffaf4f68d495d1787", + "reflex/components/sonner/toast.pyi": "0b6dc33413f30fdd043b89ec3c8c3f39", + "reflex/components/suneditor/editor.pyi": "284aa914b9bffe840db67ee68192eaf7", + "reflex/experimental/layout.pyi": "6398e779743963ef3e03396696b8ddfb" } diff --git a/reflex/components/component.py b/reflex/components/component.py index 41cf5942750..4237ac79166 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -281,7 +281,9 @@ class Component(BaseComponent, ABC): alias: str | None = pydantic.v1.Field(default_factory=lambda: None) # Whether the component is a global scope tag. True for tags like `html`, `head`, `body`. - _is_tag_in_global_scope: bool = pydantic.PrivateAttr(default_factory=lambda: False) + _is_tag_in_global_scope: bool = pydantic.v1.PrivateAttr( + default_factory=lambda: False + ) # Whether the import is default or named. is_default: bool | None = pydantic.v1.Field(default_factory=lambda: False) diff --git a/reflex/components/el/element.py b/reflex/components/el/element.py index 5b0f913b4e0..65facb319e2 100644 --- a/reflex/components/el/element.py +++ b/reflex/components/el/element.py @@ -1,6 +1,6 @@ """Base class definition for raw HTML elements.""" -import pydantic +import pydantic.v1 from reflex.components.component import Component @@ -8,7 +8,7 @@ class Element(Component): """The base class for all raw HTML elements.""" - _is_tag_in_global_scope = pydantic.PrivateAttr(default_factory=lambda: True) + _is_tag_in_global_scope = pydantic.v1.PrivateAttr(default_factory=lambda: True) def __eq__(self, other: object): """Two elements are equal if they have the same tag. diff --git a/reflex/utils/pyi_generator.py b/reflex/utils/pyi_generator.py index 6a8f71a94a9..70a867a2233 100644 --- a/reflex/utils/pyi_generator.py +++ b/reflex/utils/pyi_generator.py @@ -49,6 +49,7 @@ "tag", "is_default", "special_props", + "_is_tag_in_global_scope", "_invalid_children", "_memoization_mode", "_rename_props", diff --git a/tests/units/components/base/test_link.py b/tests/units/components/base/test_link.py index 025533f4bb0..3c1260e1293 100644 --- a/tests/units/components/base/test_link.py +++ b/tests/units/components/base/test_link.py @@ -10,6 +10,4 @@ def test_raw_link(): def test_script_tag(): script_tag = ScriptTag.create("console.log('Hello, world!');").render() assert script_tag["name"] == '"script"' - assert ( - script_tag["children"][0]["contents"] == "\"console.log('Hello, world!');\"" - ) + assert script_tag["children"][0]["contents"] == "\"console.log('Hello, world!');\"" diff --git a/tests/units/components/core/test_html.py b/tests/units/components/core/test_html.py index 83349b57a15..611753fca1d 100644 --- a/tests/units/components/core/test_html.py +++ b/tests/units/components/core/test_html.py @@ -31,11 +31,13 @@ class TestState(State): html = Html.create(f"

Hello {TestState.myvar}!

") + html_dangerouslySetInnerHTML = html.dangerouslySetInnerHTML # pyright: ignore [reportAttributeAccessIssue] + assert ( - str(html.dangerouslySetInnerHTML) # pyright: ignore [reportAttributeAccessIssue] + str(html_dangerouslySetInnerHTML) == f'({{ ["__html"] : ("

Hello "+{TestState.myvar!s}+"!

") }})' ) assert ( str(html) - == f'jsx("div",{{className:"rx-Html",dangerouslySetInnerHTML:{html.dangerouslySetInnerHTML!s}}},)\n' + == f'jsx("div",{{className:"rx-Html",dangerouslySetInnerHTML:{html_dangerouslySetInnerHTML!s}}},)\n' ) diff --git a/tests/units/test_app.py b/tests/units/test_app.py index 354fd56bd42..30a9319c3d0 100644 --- a/tests/units/test_app.py +++ b/tests/units/test_app.py @@ -1301,24 +1301,23 @@ def test_app_wrap_compile_theme( line.strip() for line in app_js_contents.splitlines() if line.strip() ] lines = "".join(app_js_lines) - assert ( + expected = ( "function AppWrap({children}) {" "return (" - + ("" if react_strict_mode else "") - + "" - "" - "" - "" - "" - "{children}" - "" - "" - "" - "" - + ("" if react_strict_mode else "") - + ")" + + ("jsx(StrictMode,{}," if react_strict_mode else "") + + "jsx(RadixThemesColorModeProvider,{}," + "jsx(RadixThemesTheme,{accentColor:\"plum\",css:{...theme.styles.global[':root'], ...theme.styles.global.body}}," + "jsx(Fragment,{}," + "jsx(MemoizedToastProvider,{},)," + "jsx(Fragment,{}," + "children," + ")," + ")," + ")," + ")" + (",)" if react_strict_mode else "") + ")" "}" - ) in lines + ) + assert expected in lines @pytest.mark.parametrize( @@ -1368,7 +1367,7 @@ def page(): line.strip() for line in app_js_contents.splitlines() if line.strip() ] lines = "".join(app_js_lines) - assert ( + expected = ( "function AppWrap({children}) {" "return (" + ("jsx(StrictMode,{}," if react_strict_mode else "") @@ -1377,11 +1376,12 @@ def page(): "jsx(RadixThemesColorModeProvider,{}," "jsx(Fragment2,{}," "jsx(Fragment,{}," - "jsx(MemoizedToastProvider,{},)" + "jsx(MemoizedToastProvider,{},)," "jsx(Fragment,{}," - "{children}" - ",),),),),)" + (")" if react_strict_mode else "") - ) in lines + "children" + ",),),),),)" + (",)" if react_strict_mode else "") + ) + assert expected in lines def test_app_state_determination(): From 0e62aaf7a8c85996c08904ebb25bdbca226666dd Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:32:25 -0700 Subject: [PATCH 04/16] jsx --- reflex/compiler/compiler.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index 6d4a42aaa65..c21cac21af0 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -37,8 +37,10 @@ def _compile_document_root(root: Component) -> str: Returns: The compiled document root. """ + document_root_imports = root._get_all_imports() + document_root_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) return templates.DOCUMENT_ROOT.render( - imports=utils.compile_imports(root._get_all_imports()), + imports=utils.compile_imports(document_root_imports), document=root.render(), ) @@ -75,8 +77,11 @@ def _compile_app(app_root: Component) -> str: ("utils_state", f"$/{constants.Dirs.UTILS}/state"), ] + app_root_imports = app_root._get_all_imports() + app_root_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + return templates.APP_ROOT.render( - imports=utils.compile_imports(app_root._get_all_imports()), + imports=utils.compile_imports(app_root_imports), custom_codes=app_root._get_all_custom_code(), hooks=app_root._get_all_hooks(), window_libraries=window_libraries, @@ -144,6 +149,7 @@ def _compile_page( The compiled component. """ imports = component._get_all_imports() + imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) imports = utils.compile_imports(imports) # Compile the code to render the component. @@ -326,7 +332,7 @@ def _compile_components( """ imports = { "react": [ImportVar(tag="memo")], - f"$/{constants.Dirs.STATE_PATH}": [ImportVar(tag="E"), ImportVar(tag="isTrue")], + f"$/{constants.Dirs.STATE_PATH}": [ImportVar(tag="isTrue")], } component_renders = [] From ec915e1d77afe6d3617a156188380c235b6262f7 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:43:45 -0700 Subject: [PATCH 05/16] make it compile --- pyi_hashes.json | 4 ++-- reflex/compiler/compiler.py | 3 +++ reflex/components/base/body.py | 6 ++---- reflex/components/base/meta.py | 14 +++++--------- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 403c2491319..0698f6bc696 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -3,13 +3,13 @@ "reflex/components/__init__.pyi": "76ba0a12cd3a7ba5ab6341a3ae81551f", "reflex/components/base/__init__.pyi": "e9aaf47be1e1977eacee97b880c8f7de", "reflex/components/base/app_wrap.pyi": "387fc7a0c2da8760d9449e2893e44eec", - "reflex/components/base/body.pyi": "2cc870cec4b1c28081dd40467752c2b7", + "reflex/components/base/body.pyi": "2d16002f24c8ee0007b46ff2bf1f2c78", "reflex/components/base/document.pyi": "30377cdfb02b564f8de29b0473d2346c", "reflex/components/base/error_boundary.pyi": "c56b591d14a92b99a1e97e04afe167d7", "reflex/components/base/fragment.pyi": "603ee8e03af88d4a8ff6bc1fbce4e022", "reflex/components/base/head.pyi": "893047aa32da553711db8f1345adb6b0", "reflex/components/base/link.pyi": "396488afa3b7a5b0d0e6c5e89159f857", - "reflex/components/base/meta.pyi": "bc4b4fda6f022a517de339ffdd667e3b", + "reflex/components/base/meta.pyi": "da52c3212fac6b50560863146a7afcc3", "reflex/components/base/script.pyi": "530cf8f47eb90082bf65942e8b5d745f", "reflex/components/base/strict_mode.pyi": "d972e0ff2a6f961e7df90fc27b8bb51b", "reflex/components/core/__init__.pyi": "44bcee7bc4e27e2f4f4707b843acf291", diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index c21cac21af0..4d7202f0c50 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -342,6 +342,8 @@ def _compile_components( component_renders.append(component_render) imports = utils.merge_imports(imports, component_imports) + imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + dynamic_imports = { comp_import: None for comp_render in component_renders @@ -434,6 +436,7 @@ def get_shared_components_recursive(component: BaseComponent): all_imports.pop( f"$/{constants.Dirs.UTILS}/{constants.PageNames.STATEFUL_COMPONENTS}", None ) + all_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) return templates.STATEFUL_COMPONENTS.render( imports=utils.compile_imports(all_imports), diff --git a/reflex/components/base/body.py b/reflex/components/base/body.py index ee38cb5d407..2327aa2d366 100644 --- a/reflex/components/base/body.py +++ b/reflex/components/base/body.py @@ -1,9 +1,7 @@ """Display the page body.""" -from reflex.components.component import Component +from reflex.components.el import elements -class Body(Component): +class Body(elements.Body): """A body component.""" - - tag = "body" diff --git a/reflex/components/base/meta.py b/reflex/components/base/meta.py index 174a7567f9f..9f61b81ce53 100644 --- a/reflex/components/base/meta.py +++ b/reflex/components/base/meta.py @@ -3,14 +3,12 @@ from __future__ import annotations from reflex.components.base.bare import Bare -from reflex.components.component import Component +from reflex.components.el import elements -class Title(Component): +class Title(elements.Title): """A component that displays the title of the current page.""" - tag = "title" - def render(self) -> dict: """Render the title component. @@ -26,11 +24,9 @@ def render(self) -> dict: return super().render() -class Meta(Component): +class Meta(elements.Meta): """A component that displays metadata for the current page.""" - tag = "meta" - # The description of character encoding. char_set: str | None = None @@ -47,14 +43,14 @@ class Meta(Component): http_equiv: str | None = None -class Description(Meta): +class Description(elements.Meta): """A component that displays the title of the current page.""" # The type of the description. name: str | None = "description" -class Image(Meta): +class Image(elements.Meta): """A component that displays the title of the current page.""" # The type of the image. From d4454a7417b10ae2a9708a3a2c6fea018925fad6 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:48:59 -0700 Subject: [PATCH 06/16] why do we have those??? --- pyi_hashes.json | 2 +- reflex/components/base/link.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 0698f6bc696..482f3de2ee9 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -8,7 +8,7 @@ "reflex/components/base/error_boundary.pyi": "c56b591d14a92b99a1e97e04afe167d7", "reflex/components/base/fragment.pyi": "603ee8e03af88d4a8ff6bc1fbce4e022", "reflex/components/base/head.pyi": "893047aa32da553711db8f1345adb6b0", - "reflex/components/base/link.pyi": "396488afa3b7a5b0d0e6c5e89159f857", + "reflex/components/base/link.pyi": "e96179dc7823f354fb73a6c03e31028c", "reflex/components/base/meta.pyi": "da52c3212fac6b50560863146a7afcc3", "reflex/components/base/script.pyi": "530cf8f47eb90082bf65942e8b5d745f", "reflex/components/base/strict_mode.pyi": "d972e0ff2a6f961e7df90fc27b8bb51b", diff --git a/reflex/components/base/link.py b/reflex/components/base/link.py index 3ea34f2122b..c5c9222fd13 100644 --- a/reflex/components/base/link.py +++ b/reflex/components/base/link.py @@ -1,10 +1,10 @@ """Display the title of the current page.""" -from reflex.components.component import Component +from reflex.components.el.elements.base import BaseHTML from reflex.vars.base import Var -class RawLink(Component): +class RawLink(BaseHTML): """A component that displays the title of the current page.""" tag = "link" @@ -16,7 +16,7 @@ class RawLink(Component): rel: Var[str] -class ScriptTag(Component): +class ScriptTag(BaseHTML): """A script tag with the specified type and source.""" tag = "script" From 911451f62780f9787c15bac0a718eca2621bc1b5 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 16:59:39 -0700 Subject: [PATCH 07/16] huh? --- pyi_hashes.json | 2 +- reflex/compiler/compiler.py | 3 ++- reflex/components/radix/themes/layout/list.py | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 482f3de2ee9..a26d1ec95a6 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -101,7 +101,7 @@ "reflex/components/radix/themes/layout/container.pyi": "4020c3dca660027b84d11cc4198393c4", "reflex/components/radix/themes/layout/flex.pyi": "f814281a5635ad43dd1df23f8e356c66", "reflex/components/radix/themes/layout/grid.pyi": "6062188367a2c253f014f916197c963d", - "reflex/components/radix/themes/layout/list.pyi": "804f7a36c103cd7a3e362d40a58e8d39", + "reflex/components/radix/themes/layout/list.pyi": "46e4ff60b0251dec55a7748835b33452", "reflex/components/radix/themes/layout/section.pyi": "41895910072e023ed0fef6a8ad956046", "reflex/components/radix/themes/layout/spacer.pyi": "029eb0eaa731bcdff7c496e0437e22b1", "reflex/components/radix/themes/layout/stack.pyi": "3b0da99b00c826d087ed89fc67c595c1", diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index 4d7202f0c50..31728dbdfa9 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -436,7 +436,8 @@ def get_shared_components_recursive(component: BaseComponent): all_imports.pop( f"$/{constants.Dirs.UTILS}/{constants.PageNames.STATEFUL_COMPONENTS}", None ) - all_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + if rendered_components: + all_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) return templates.STATEFUL_COMPONENTS.render( imports=utils.compile_imports(all_imports), diff --git a/reflex/components/radix/themes/layout/list.py b/reflex/components/radix/themes/layout/list.py index a2288722dc6..83c275309f9 100644 --- a/reflex/components/radix/themes/layout/list.py +++ b/reflex/components/radix/themes/layout/list.py @@ -4,8 +4,9 @@ from typing import Any, Iterable, Literal -from reflex.components.component import Component, ComponentNamespace +from reflex.components.component import ComponentNamespace from reflex.components.core.foreach import Foreach +from reflex.components.el.elements.base import BaseHTML from reflex.components.el.elements.typography import Li, Ol, Ul from reflex.components.lucide.icon import Icon from reflex.components.markdown.markdown import MarkdownComponentMap @@ -37,7 +38,7 @@ ] -class BaseList(Component, MarkdownComponentMap): +class BaseList(BaseHTML, MarkdownComponentMap): """Base class for ordered and unordered lists.""" tag = "ul" From ae5da2c1a8cff6654e216382ae7faea9b9468a23 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 14 Apr 2025 17:16:29 -0700 Subject: [PATCH 08/16] make the .js files real js files --- .../reflex/radix_themes_color_mode_provider.js | 14 +++++++------- reflex/.templates/web/components/shiki/code.js | 9 +++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js b/reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js index 0849403be8c..25a5a5b68b0 100644 --- a/reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +++ b/reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js @@ -1,5 +1,5 @@ import { useTheme } from "next-themes"; -import { useRef, useEffect, useState } from "react"; +import { useRef, useEffect, useState, createElement } from "react"; import { ColorModeContext, defaultColorMode, @@ -50,11 +50,11 @@ export default function RadixThemesColorModeProvider({ children }) { } setTheme(mode); }; - return ( - - {children} - + return createElement( + ColorModeContext, + { + value: { rawColorMode, resolvedColorMode, toggleColorMode, setColorMode }, + }, + children, ); } diff --git a/reflex/.templates/web/components/shiki/code.js b/reflex/.templates/web/components/shiki/code.js index b2e369fd6af..8d721dd8a29 100644 --- a/reflex/.templates/web/components/shiki/code.js +++ b/reflex/.templates/web/components/shiki/code.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState, createElement } from "react"; import { codeToHtml } from "shiki"; /** @@ -33,7 +33,8 @@ export function Code({ } fetchCode(); }, [code, language, theme, transformers, decorations]); - return ( -
- ); + return createElement("div", { + dangerouslySetInnerHTML: { __html: codeResult }, + ...divProps, + }); } From f88c6a009b636943d300425931f82cd58008e3be Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:20:52 -0700 Subject: [PATCH 09/16] _apply_common_imports --- reflex/compiler/compiler.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index 10d5fbb216e..cf574933514 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -30,6 +30,13 @@ from reflex.vars.base import LiteralVar, Var +def _apply_common_imports( + imports: dict[str, list[ImportVar]], +): + imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + imports.setdefault("react", []).append(ImportVar("Fragment")) + + def _compile_document_root(root: Component) -> str: """Compile the document root. @@ -40,7 +47,7 @@ def _compile_document_root(root: Component) -> str: The compiled document root. """ document_root_imports = root._get_all_imports() - document_root_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + _apply_common_imports(document_root_imports) return templates.DOCUMENT_ROOT.render( imports=utils.compile_imports(document_root_imports), document=root.render(), @@ -77,7 +84,7 @@ def _compile_app(app_root: Component) -> str: ] app_root_imports = app_root._get_all_imports() - app_root_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + _apply_common_imports(app_root_imports) return templates.APP_ROOT.render( imports=utils.compile_imports(app_root_imports), @@ -148,7 +155,7 @@ def _compile_page( The compiled component. """ imports = component._get_all_imports() - imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + _apply_common_imports(imports) imports = utils.compile_imports(imports) # Compile the code to render the component. @@ -341,7 +348,7 @@ def _compile_components( component_renders.append(component_render) imports = utils.merge_imports(imports, component_imports) - imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + _apply_common_imports(imports) dynamic_imports = { comp_import: None @@ -436,7 +443,7 @@ def get_shared_components_recursive(component: BaseComponent): f"$/{constants.Dirs.UTILS}/{constants.PageNames.STATEFUL_COMPONENTS}", None ) if rendered_components: - all_imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + _apply_common_imports(all_imports) return templates.STATEFUL_COMPONENTS.render( imports=utils.compile_imports(all_imports), From f5071bff313f3d4d8613d9759947ae449eef2e44 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:21:42 -0700 Subject: [PATCH 10/16] no more fragment import there --- reflex/components/component.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/reflex/components/component.py b/reflex/components/component.py index 57d85b4144e..65638e66e52 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -2654,13 +2654,6 @@ def _cached_get_all_var_data(self) -> VarData | None: VarData( imports=self._var_value._get_all_imports(), ), - VarData( - imports={ - "react": [ - ImportVar(tag="Fragment"), - ], - } - ), ) def __hash__(self) -> int: From e7cc0ecb5a50f04e4648b77911c18483338792a3 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:23:35 -0700 Subject: [PATCH 11/16] make _is_tag_in_global_scope just a classvar --- pyi_hashes.json | 2 +- reflex/components/component.py | 4 +--- reflex/components/el/element.py | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 953f6ebabfd..a9efd420879 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -26,7 +26,7 @@ "reflex/components/datadisplay/dataeditor.pyi": "cb03d732e2fe771a8d46c7bcda671f92", "reflex/components/datadisplay/shiki_code_block.pyi": "87db7639bfa5cd53e1709e1363f93278", "reflex/components/el/__init__.pyi": "09042a2db5e0637e99b5173430600522", - "reflex/components/el/element.pyi": "6d739982d5d7842892745ef520887bb9", + "reflex/components/el/element.pyi": "ea6b33a8545c2c845dc6c30ff1c872a4", "reflex/components/el/elements/__init__.pyi": "280ed457675f3720e34b560a3f617739", "reflex/components/el/elements/base.pyi": "6e533348b5e1a88cf62fbb5a38dbd795", "reflex/components/el/elements/forms.pyi": "161f1ef847e5da8755528a7977fdcf53", diff --git a/reflex/components/component.py b/reflex/components/component.py index 65638e66e52..4bc49cd3c30 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -269,9 +269,7 @@ class Component(BaseComponent, ABC): alias: str | None = pydantic.v1.Field(default_factory=lambda: None) # Whether the component is a global scope tag. True for tags like `html`, `head`, `body`. - _is_tag_in_global_scope: bool = pydantic.v1.PrivateAttr( - default_factory=lambda: False - ) + _is_tag_in_global_scope: ClassVar[bool] = False # Whether the import is default or named. is_default: bool | None = pydantic.v1.Field(default_factory=lambda: False) diff --git a/reflex/components/el/element.py b/reflex/components/el/element.py index 65facb319e2..7232ee38f17 100644 --- a/reflex/components/el/element.py +++ b/reflex/components/el/element.py @@ -1,6 +1,6 @@ """Base class definition for raw HTML elements.""" -import pydantic.v1 +from typing import ClassVar from reflex.components.component import Component @@ -8,7 +8,7 @@ class Element(Component): """The base class for all raw HTML elements.""" - _is_tag_in_global_scope = pydantic.v1.PrivateAttr(default_factory=lambda: True) + _is_tag_in_global_scope: ClassVar[bool] = True def __eq__(self, other: object): """Two elements are equal if they have the same tag. From 0fb7678e7b04bcf4c8aa89bb67d469048edf597e Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:26:27 -0700 Subject: [PATCH 12/16] simplify render method for bare --- reflex/components/base/bare.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/reflex/components/base/bare.py b/reflex/components/base/bare.py index 986c52f1fa1..f4c10f0b43b 100644 --- a/reflex/components/base/bare.py +++ b/reflex/components/base/bare.py @@ -2,7 +2,6 @@ from __future__ import annotations -import json from collections.abc import Iterator, Sequence from typing import Any @@ -170,11 +169,14 @@ def _get_all_refs(self) -> set[str]: return refs def _render(self) -> Tag: - if isinstance(self.contents, Var): - if isinstance(self.contents, (BooleanVar, ObjectVar)): - return Tagless(contents=f"{self.contents.to_string()!s}") - return Tagless(contents=f"{self.contents!s}") - return Tagless(contents=f'"{json.dumps(self.contents)}"') + contents = ( + Var.create(self.contents) + if not isinstance(self.contents, Var) + else self.contents + ) + if isinstance(contents, (BooleanVar, ObjectVar)): + return Tagless(contents=f"{contents.to_string()!s}") + return Tagless(contents=f"{contents!s}") def _add_style_recursive( self, style: ComponentStyle, theme: Component | None = None From 3855e00b40aa8acbe4128e3ce15e8371425dff56 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:37:56 -0700 Subject: [PATCH 13/16] maybe? --- reflex/compiler/compiler.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index cf574933514..02530ffadc5 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -33,8 +33,14 @@ def _apply_common_imports( imports: dict[str, list[ImportVar]], ): - imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) - imports.setdefault("react", []).append(ImportVar("Fragment")) + if "@emotion/react" in imports: + imports["@emotion/react"].append(ImportVar("css")) + else: + imports["@emotion/react"] = [ImportVar("css")] + if "react" in imports: + imports["react"].append(ImportVar("Fragment")) + else: + imports["react"] = [ImportVar("Fragment")] def _compile_document_root(root: Component) -> str: From 9ca55180d185e6f8e609d69756bd20f25e9439b4 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:42:25 -0700 Subject: [PATCH 14/16] what did i do --- reflex/compiler/compiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index 02530ffadc5..fae0ab47f81 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -34,9 +34,9 @@ def _apply_common_imports( imports: dict[str, list[ImportVar]], ): if "@emotion/react" in imports: - imports["@emotion/react"].append(ImportVar("css")) + imports["@emotion/react"].append(ImportVar("jsx")) else: - imports["@emotion/react"] = [ImportVar("css")] + imports["@emotion/react"] = [ImportVar("jsx")] if "react" in imports: imports["react"].append(ImportVar("Fragment")) else: From 454cc146b2f4fa59e60d5644f6acae2b52163ecd Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 15:55:12 -0700 Subject: [PATCH 15/16] dynamic was the weird guy --- reflex/compiler/compiler.py | 10 ++-------- reflex/components/component.py | 7 ------- reflex/components/dynamic.py | 7 +++++-- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index fae0ab47f81..cf574933514 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -33,14 +33,8 @@ def _apply_common_imports( imports: dict[str, list[ImportVar]], ): - if "@emotion/react" in imports: - imports["@emotion/react"].append(ImportVar("jsx")) - else: - imports["@emotion/react"] = [ImportVar("jsx")] - if "react" in imports: - imports["react"].append(ImportVar("Fragment")) - else: - imports["react"] = [ImportVar("Fragment")] + imports.setdefault("@emotion/react", []).append(ImportVar("jsx")) + imports.setdefault("react", []).append(ImportVar("Fragment")) def _compile_document_root(root: Component) -> str: diff --git a/reflex/components/component.py b/reflex/components/component.py index 4bc49cd3c30..23d487d1502 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -2642,13 +2642,6 @@ def _cached_get_all_var_data(self) -> VarData | None: """ return VarData.merge( self._var_data, - VarData( - imports={ - "@emotion/react": [ - ImportVar(tag="jsx"), - ], - } - ), VarData( imports=self._var_value._get_all_imports(), ), diff --git a/reflex/components/dynamic.py b/reflex/components/dynamic.py index d77a16dfe7e..bb51d4cee9f 100644 --- a/reflex/components/dynamic.py +++ b/reflex/components/dynamic.py @@ -72,7 +72,7 @@ def make_component(component: Component) -> str: The generated code """ # Causes a circular import, so we import here. - from reflex.compiler import templates, utils + from reflex.compiler import compiler, templates, utils from reflex.components.base.bare import Bare component = Bare.create(Var.create(component)) @@ -97,8 +97,11 @@ def make_component(component: Component) -> str: libs_in_window = bundled_libraries + imports = component._get_all_imports() + compiler._apply_common_imports(imports) + imports = {} - for lib, names in component._get_all_imports().items(): + for lib, names in imports.items(): formatted_lib_name = format_library_name(lib) if ( not lib.startswith((".", "/", "$/")) From 469e270e9bec7f99b23b4ac8a86277f890cc53ea Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Tue, 6 May 2025 16:01:56 -0700 Subject: [PATCH 16/16] i was being silly --- reflex/components/dynamic.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reflex/components/dynamic.py b/reflex/components/dynamic.py index bb51d4cee9f..b2498b8418d 100644 --- a/reflex/components/dynamic.py +++ b/reflex/components/dynamic.py @@ -97,11 +97,11 @@ def make_component(component: Component) -> str: libs_in_window = bundled_libraries - imports = component._get_all_imports() - compiler._apply_common_imports(imports) + component_imports = component._get_all_imports() + compiler._apply_common_imports(component_imports) imports = {} - for lib, names in imports.items(): + for lib, names in component_imports.items(): formatted_lib_name = format_library_name(lib) if ( not lib.startswith((".", "/", "$/"))