瀏覽代碼

[REF-1632] Apply `rx.App` styles to Radix Themes root `div` (#2481)

Masen Furer 1 年之前
父節點
當前提交
bece5bdb44

+ 6 - 7
integration/test_tailwind.py

@@ -10,14 +10,13 @@ from reflex.testing import AppHarness
 
 PARAGRAPH_TEXT = "Tailwind Is Cool"
 PARAGRAPH_CLASS_NAME = "text-red-500"
-GLOBAL_PARAGRAPH_COLOR = "rgba(0, 0, 242, 1)"
+TEXT_RED_500_COLOR = "rgba(239, 68, 68, 1)"
 
 
 def TailwindApp(
     tailwind_disabled: bool = False,
     paragraph_text: str = PARAGRAPH_TEXT,
     paragraph_class_name: str = PARAGRAPH_CLASS_NAME,
-    global_paragraph_color: str = GLOBAL_PARAGRAPH_COLOR,
 ):
     """App with tailwind optionally disabled.
 
@@ -25,7 +24,6 @@ def TailwindApp(
         tailwind_disabled: Whether tailwind is disabled for the app.
         paragraph_text: Text for the paragraph.
         paragraph_class_name: Tailwind class_name for the paragraph.
-        global_paragraph_color: Color for the paragraph set in global app styles.
     """
     import reflex as rx
     import reflex.components.radix.themes as rdxt
@@ -38,7 +36,7 @@ def TailwindApp(
             id="p-content",
         )
 
-    app = rx.App(style={"p": {"color": global_paragraph_color}})
+    app = rx.App(style={"font_family": "monospace"})
     app.add_page(index)
     if tailwind_disabled:
         config = rx.config.get_config()
@@ -100,9 +98,10 @@ def test_tailwind_app(tailwind_app: AppHarness, tailwind_disabled: bool):
     assert len(paragraphs) == 3
     for p in paragraphs:
         assert tailwind_app.poll_for_content(p, exp_not_equal="") == PARAGRAPH_TEXT
+        assert p.value_of_css_property("font-family") == "monospace"
         if tailwind_disabled:
-            # expect "blue" color from global stylesheet, not "text-red-500" from tailwind utility class
-            assert p.value_of_css_property("color") == GLOBAL_PARAGRAPH_COLOR
+            # expect default color, not "text-red-500" from tailwind utility class
+            assert p.value_of_css_property("color") != TEXT_RED_500_COLOR
         else:
             # expect "text-red-500" from tailwind utility class
-            assert p.value_of_css_property("color") == "rgba(239, 68, 68, 1)"
+            assert p.value_of_css_property("color") == TEXT_RED_500_COLOR

+ 4 - 3
reflex/app.py

@@ -44,6 +44,7 @@ from reflex.components.core.client_side_routing import (
     wait_for_client_redirect,
 )
 from reflex.components.core.upload import UploadFilesProvider
+from reflex.components.radix import themes
 from reflex.config import get_config
 from reflex.event import Event, EventHandler, EventSpec
 from reflex.middleware import HydrateMiddleware, Middleware
@@ -129,11 +130,11 @@ class App(Base):
         Union[Component, ComponentCallable]
     ] = default_overlay_component
 
-    # Background tasks that are currently running.
+    # Background tasks that are currently running
     background_tasks: Set[asyncio.Task] = set()
 
-    # The radix theme for the entire app.
-    theme: Optional[Component]
+    # The radix theme for the entire app
+    theme: Optional[Component] = themes.theme(accent_color="blue")
 
     def __init__(self, *args, **kwargs):
         """Initialize the app.

+ 12 - 11
reflex/compiler/utils.py

@@ -290,20 +290,21 @@ def create_theme(style: ComponentStyle) -> dict:
         The base style for the app.
     """
     # Get the global style from the style dict.
-    global_style = Style({k: v for k, v in style.items() if not isinstance(k, type)})
+    style_rules = Style({k: v for k, v in style.items() if not isinstance(k, type)})
 
-    # Root styles.
-    root_style = Style({k: v for k, v in global_style.items() if k.startswith("::")})
-
-    # Body styles.
-    root_style["body"] = Style(
-        {k: v for k, v in global_style.items() if k not in root_style}
-    )
+    root_style = {
+        # Root styles.
+        ":root": Style(
+            {f"*{k}": v for k, v in style_rules.items() if k.startswith(":")}
+        ),
+        # Body styles.
+        "body": Style(
+            {k: v for k, v in style_rules.items() if not k.startswith(":")},
+        ),
+    }
 
     # Return the theme.
-    return {
-        "styles": {"global": root_style},
-    }
+    return {"styles": {"global": root_style}}
 
 
 def get_page_path(path: str) -> str:

+ 23 - 5
reflex/components/radix/themes/base.py

@@ -2,9 +2,10 @@
 
 from __future__ import annotations
 
-from typing import Literal
+from typing import Any, Literal
 
 from reflex.components import Component
+from reflex.components.tags import Tag
 from reflex.utils import imports
 from reflex.vars import Var
 
@@ -154,10 +155,27 @@ class Theme(RadixThemesComponent):
     scaling: Var[LiteralScaling]
 
     def _get_imports(self) -> imports.ImportDict:
-        return {
-            **super()._get_imports(),
-            "": [imports.ImportVar(tag="@radix-ui/themes/styles.css", install=False)],
-        }
+        return imports.merge_imports(
+            super()._get_imports(),
+            {
+                "": [
+                    imports.ImportVar(tag="@radix-ui/themes/styles.css", install=False)
+                ],
+                "/utils/theme.js": [
+                    imports.ImportVar(tag="theme", is_default=True),
+                ],
+            },
+        )
+
+    def _render(self, props: dict[str, Any] | None = None) -> Tag:
+        tag = super()._render(props)
+        tag.add_props(
+            css=Var.create(
+                "{{...theme.styles.global[':root'], ...theme.styles.global.body}}",
+                _var_is_local=False,
+            ),
+        )
+        return tag
 
 
 class ThemePanel(RadixThemesComponent):

+ 2 - 1
reflex/components/radix/themes/base.pyi

@@ -7,8 +7,9 @@ from typing import Any, Dict, Literal, Optional, Union, overload
 from reflex.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
-from typing import Literal
+from typing import Any, Literal
 from reflex.components import Component
+from reflex.components.tags import Tag
 from reflex.utils import imports
 from reflex.vars import Var
 

+ 1 - 1
tests/test_app.py

@@ -1222,7 +1222,7 @@ def test_app_wrap_compile_theme(compilable_app):
         "function AppWrap({children}) {"
         "return ("
         "<RadixThemesColorModeProvider>"
-        "<RadixThemesTheme accentColor={`plum`}>"
+        "<RadixThemesTheme accentColor={`plum`} css={{...theme.styles.global[':root'], ...theme.styles.global.body}}>"
         "<Fragment>"
         "{children}"
         "</Fragment>"