Bläddra i källkod

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

Masen Furer 1 år sedan
förälder
incheckning
bece5bdb44

+ 6 - 7
integration/test_tailwind.py

@@ -10,14 +10,13 @@ from reflex.testing import AppHarness
 
 
 PARAGRAPH_TEXT = "Tailwind Is Cool"
 PARAGRAPH_TEXT = "Tailwind Is Cool"
 PARAGRAPH_CLASS_NAME = "text-red-500"
 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(
 def TailwindApp(
     tailwind_disabled: bool = False,
     tailwind_disabled: bool = False,
     paragraph_text: str = PARAGRAPH_TEXT,
     paragraph_text: str = PARAGRAPH_TEXT,
     paragraph_class_name: str = PARAGRAPH_CLASS_NAME,
     paragraph_class_name: str = PARAGRAPH_CLASS_NAME,
-    global_paragraph_color: str = GLOBAL_PARAGRAPH_COLOR,
 ):
 ):
     """App with tailwind optionally disabled.
     """App with tailwind optionally disabled.
 
 
@@ -25,7 +24,6 @@ def TailwindApp(
         tailwind_disabled: Whether tailwind is disabled for the app.
         tailwind_disabled: Whether tailwind is disabled for the app.
         paragraph_text: Text for the paragraph.
         paragraph_text: Text for the paragraph.
         paragraph_class_name: Tailwind class_name 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 as rx
     import reflex.components.radix.themes as rdxt
     import reflex.components.radix.themes as rdxt
@@ -38,7 +36,7 @@ def TailwindApp(
             id="p-content",
             id="p-content",
         )
         )
 
 
-    app = rx.App(style={"p": {"color": global_paragraph_color}})
+    app = rx.App(style={"font_family": "monospace"})
     app.add_page(index)
     app.add_page(index)
     if tailwind_disabled:
     if tailwind_disabled:
         config = rx.config.get_config()
         config = rx.config.get_config()
@@ -100,9 +98,10 @@ def test_tailwind_app(tailwind_app: AppHarness, tailwind_disabled: bool):
     assert len(paragraphs) == 3
     assert len(paragraphs) == 3
     for p in paragraphs:
     for p in paragraphs:
         assert tailwind_app.poll_for_content(p, exp_not_equal="") == PARAGRAPH_TEXT
         assert tailwind_app.poll_for_content(p, exp_not_equal="") == PARAGRAPH_TEXT
+        assert p.value_of_css_property("font-family") == "monospace"
         if tailwind_disabled:
         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:
         else:
             # expect "text-red-500" from tailwind utility class
             # 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,
     wait_for_client_redirect,
 )
 )
 from reflex.components.core.upload import UploadFilesProvider
 from reflex.components.core.upload import UploadFilesProvider
+from reflex.components.radix import themes
 from reflex.config import get_config
 from reflex.config import get_config
 from reflex.event import Event, EventHandler, EventSpec
 from reflex.event import Event, EventHandler, EventSpec
 from reflex.middleware import HydrateMiddleware, Middleware
 from reflex.middleware import HydrateMiddleware, Middleware
@@ -129,11 +130,11 @@ class App(Base):
         Union[Component, ComponentCallable]
         Union[Component, ComponentCallable]
     ] = default_overlay_component
     ] = default_overlay_component
 
 
-    # Background tasks that are currently running.
+    # Background tasks that are currently running
     background_tasks: Set[asyncio.Task] = set()
     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):
     def __init__(self, *args, **kwargs):
         """Initialize the app.
         """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.
         The base style for the app.
     """
     """
     # Get the global style from the style dict.
     # 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 the theme.
-    return {
-        "styles": {"global": root_style},
-    }
+    return {"styles": {"global": root_style}}
 
 
 
 
 def get_page_path(path: str) -> str:
 def get_page_path(path: str) -> str:

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

@@ -2,9 +2,10 @@
 
 
 from __future__ import annotations
 from __future__ import annotations
 
 
-from typing import Literal
+from typing import Any, Literal
 
 
 from reflex.components import Component
 from reflex.components import Component
+from reflex.components.tags import Tag
 from reflex.utils import imports
 from reflex.utils import imports
 from reflex.vars import Var
 from reflex.vars import Var
 
 
@@ -154,10 +155,27 @@ class Theme(RadixThemesComponent):
     scaling: Var[LiteralScaling]
     scaling: Var[LiteralScaling]
 
 
     def _get_imports(self) -> imports.ImportDict:
     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):
 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.vars import Var, BaseVar, ComputedVar
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.event import EventChain, EventHandler, EventSpec
 from reflex.style import Style
 from reflex.style import Style
-from typing import Literal
+from typing import Any, Literal
 from reflex.components import Component
 from reflex.components import Component
+from reflex.components.tags import Tag
 from reflex.utils import imports
 from reflex.utils import imports
 from reflex.vars import Var
 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}) {"
         "function AppWrap({children}) {"
         "return ("
         "return ("
         "<RadixThemesColorModeProvider>"
         "<RadixThemesColorModeProvider>"
-        "<RadixThemesTheme accentColor={`plum`}>"
+        "<RadixThemesTheme accentColor={`plum`} css={{...theme.styles.global[':root'], ...theme.styles.global.body}}>"
         "<Fragment>"
         "<Fragment>"
         "{children}"
         "{children}"
         "</Fragment>"
         "</Fragment>"