diff --git a/reflex/app.py b/reflex/app.py index 33d773a6f..40c63372f 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -39,7 +39,11 @@ from reflex.compiler import utils as compiler_utils from reflex.components import connection_modal from reflex.components.base.app_wrap import AppWrap from reflex.components.base.fragment import Fragment -from reflex.components.component import Component, ComponentStyle +from reflex.components.component import ( + Component, + ComponentStyle, + evaluate_style_namespaces, +) from reflex.components.core.client_side_routing import ( Default404Page, wait_for_client_redirect, @@ -682,10 +686,7 @@ class App(Base): # Store the compile results. compile_results = [] - # Compile the pages in parallel. - custom_components = set() - # TODO Anecdotally, processes=2 works 10% faster (cpu_count=12) - all_imports = {} + # Add the app wrappers. app_wrappers: Dict[tuple[int, str], Component] = { # Default app wrap component renders {children} (0, "AppWrap"): AppWrap.create() @@ -694,6 +695,14 @@ class App(Base): # If a theme component was provided, wrap the app with it app_wrappers[(20, "Theme")] = self.theme + # Fix up the style. + self.style = evaluate_style_namespaces(self.style) + + # Track imports and custom components found. + all_imports = {} + custom_components = set() + + # Compile the pages in parallel. with progress, concurrent.futures.ThreadPoolExecutor() as thread_pool: fixed_pages = 7 task = progress.add_task("Compiling:", total=len(self.pages) + fixed_pages) diff --git a/reflex/components/component.py b/reflex/components/component.py index 43b66f52b..5c71216f1 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -7,6 +7,7 @@ import typing from abc import ABC, abstractmethod from functools import lru_cache, wraps from hashlib import md5 +from types import SimpleNamespace from typing import ( Any, Callable, @@ -114,8 +115,38 @@ class BaseComponent(Base, ABC): """ +class ComponentNamespace(SimpleNamespace): + """A namespace to manage components with subcomponents.""" + + def __hash__(self) -> int: + """Get the hash of the namespace. + + + Returns: + The hash of the namespace. + """ + return hash(self.__class__.__name__) + + +def evaluate_style_namespaces(style: ComponentStyle) -> dict: + """Evaluate namespaces in the style. + + Args: + style: The style to evaluate. + + Returns: + The evaluated style. + """ + return { + k.__call__ if isinstance(k, ComponentNamespace) else k: v + for k, v in style.items() + } + + # Map from component to styling. -ComponentStyle = Dict[Union[str, Type[BaseComponent], Callable], Any] +ComponentStyle = Dict[ + Union[str, Type[BaseComponent], Callable, ComponentNamespace], Any +] ComponentChild = Union[types.PrimitiveType, Var, BaseComponent] diff --git a/reflex/components/radix/primitives/accordion.py b/reflex/components/radix/primitives/accordion.py index 24b5cd668..da790b0b2 100644 --- a/reflex/components/radix/primitives/accordion.py +++ b/reflex/components/radix/primitives/accordion.py @@ -2,10 +2,9 @@ from __future__ import annotations -from types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.match import Match from reflex.components.lucide.icon import Icon from reflex.components.radix.primitives.base import RadixPrimitiveComponent @@ -649,7 +648,7 @@ class AccordionContent(AccordionComponent): # } -class Accordion(SimpleNamespace): +class Accordion(ComponentNamespace): """Accordion component.""" content = staticmethod(AccordionContent.create) diff --git a/reflex/components/radix/primitives/accordion.pyi b/reflex/components/radix/primitives/accordion.pyi index f088981a4..e5b94bf7b 100644 --- a/reflex/components/radix/primitives/accordion.pyi +++ b/reflex/components/radix/primitives/accordion.pyi @@ -7,9 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.match import Match from reflex.components.lucide.icon import Icon from reflex.components.radix.primitives.base import RadixPrimitiveComponent @@ -699,7 +698,7 @@ class AccordionContent(AccordionComponent): """ ... -class Accordion(SimpleNamespace): +class Accordion(ComponentNamespace): content = staticmethod(AccordionContent.create) header = staticmethod(AccordionHeader.create) item = staticmethod(AccordionItem.create) diff --git a/reflex/components/radix/primitives/drawer.py b/reflex/components/radix/primitives/drawer.py index b93567858..b268180aa 100644 --- a/reflex/components/radix/primitives/drawer.py +++ b/reflex/components/radix/primitives/drawer.py @@ -3,9 +3,9 @@ # Style based on https://ui.shadcn.com/docs/components/drawer from __future__ import annotations -from types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union +from reflex.components.component import ComponentNamespace from reflex.components.radix.primitives.base import RadixPrimitiveComponent from reflex.components.radix.themes.base import Theme from reflex.constants import EventTriggers @@ -261,7 +261,7 @@ class DrawerDescription(DrawerComponent): return self.style -class Drawer(SimpleNamespace): +class Drawer(ComponentNamespace): """A namespace for Drawer components.""" root = __call__ = staticmethod(DrawerRoot.create) diff --git a/reflex/components/radix/primitives/drawer.pyi b/reflex/components/radix/primitives/drawer.pyi index cf19f4743..ac58d9a7e 100644 --- a/reflex/components/radix/primitives/drawer.pyi +++ b/reflex/components/radix/primitives/drawer.pyi @@ -7,8 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union +from reflex.components.component import ComponentNamespace from reflex.components.radix.primitives.base import RadixPrimitiveComponent from reflex.components.radix.themes.base import Theme from reflex.constants import EventTriggers @@ -789,7 +789,7 @@ class DrawerDescription(DrawerComponent): """ ... -class Drawer(SimpleNamespace): +class Drawer(ComponentNamespace): root = staticmethod(DrawerRoot.create) trigger = staticmethod(DrawerTrigger.create) portal = staticmethod(DrawerPortal.create) diff --git a/reflex/components/radix/primitives/form.py b/reflex/components/radix/primitives/form.py index 8437a41dc..d6b57799a 100644 --- a/reflex/components/radix/primitives/form.py +++ b/reflex/components/radix/primitives/form.py @@ -3,12 +3,11 @@ from __future__ import annotations from hashlib import md5 -from types import SimpleNamespace from typing import Any, Dict, Iterator, Literal from jinja2 import Environment -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.components.text_field import TextFieldInput from reflex.components.tags.tag import Tag from reflex.constants.base import Dirs @@ -297,7 +296,7 @@ class Form(FormRoot): pass -class FormNamespace(SimpleNamespace): +class FormNamespace(ComponentNamespace): """Form components.""" root = staticmethod(FormRoot.create) diff --git a/reflex/components/radix/primitives/form.pyi b/reflex/components/radix/primitives/form.pyi index 247e393df..e80b4214c 100644 --- a/reflex/components/radix/primitives/form.pyi +++ b/reflex/components/radix/primitives/form.pyi @@ -8,10 +8,9 @@ from reflex.vars import Var, BaseVar, ComputedVar from reflex.event import EventChain, EventHandler, EventSpec from reflex.style import Style from hashlib import md5 -from types import SimpleNamespace from typing import Any, Dict, Iterator, Literal from jinja2 import Environment -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.components.text_field import TextFieldInput from reflex.components.tags.tag import Tag from reflex.constants.base import Dirs @@ -826,7 +825,7 @@ class Form(FormRoot): """ ... -class FormNamespace(SimpleNamespace): +class FormNamespace(ComponentNamespace): root = staticmethod(FormRoot.create) control = staticmethod(FormControl.create) field = staticmethod(FormField.create) diff --git a/reflex/components/radix/primitives/progress.py b/reflex/components/radix/primitives/progress.py index 8679a55f0..1b03a8d98 100644 --- a/reflex/components/radix/primitives/progress.py +++ b/reflex/components/radix/primitives/progress.py @@ -2,10 +2,9 @@ from __future__ import annotations -from types import SimpleNamespace from typing import Optional -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.style import Style @@ -74,7 +73,7 @@ class ProgressIndicator(ProgressComponent): ) -class Progress(SimpleNamespace): +class Progress(ComponentNamespace): """High level API for progress bar.""" root = staticmethod(ProgressRoot.create) diff --git a/reflex/components/radix/primitives/progress.pyi b/reflex/components/radix/primitives/progress.pyi index 0fadf594f..61b8d5edd 100644 --- a/reflex/components/radix/primitives/progress.pyi +++ b/reflex/components/radix/primitives/progress.pyi @@ -7,9 +7,8 @@ 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 types import SimpleNamespace from typing import Optional -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.primitives.accordion import DEFAULT_ANIMATION_DURATION from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.style import Style @@ -266,7 +265,7 @@ class ProgressIndicator(ProgressComponent): """ ... -class Progress(SimpleNamespace): +class Progress(ComponentNamespace): root = staticmethod(ProgressRoot.create) indicator = staticmethod(ProgressIndicator.create) diff --git a/reflex/components/radix/primitives/slider.py b/reflex/components/radix/primitives/slider.py index c4e82ba88..94560c3f0 100644 --- a/reflex/components/radix/primitives/slider.py +++ b/reflex/components/radix/primitives/slider.py @@ -2,10 +2,9 @@ from __future__ import annotations -from types import SimpleNamespace from typing import Any, Dict, List, Literal -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.style import Style from reflex.vars import Var @@ -149,7 +148,7 @@ class SliderThumb(SliderComponent): ) -class Slider(SimpleNamespace): +class Slider(ComponentNamespace): """High level API for slider.""" root = staticmethod(SliderRoot.create) diff --git a/reflex/components/radix/primitives/slider.pyi b/reflex/components/radix/primitives/slider.pyi index da2228c90..62940118f 100644 --- a/reflex/components/radix/primitives/slider.pyi +++ b/reflex/components/radix/primitives/slider.pyi @@ -7,9 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.style import Style from reflex.vars import Var @@ -445,7 +444,7 @@ class SliderThumb(SliderComponent): """ ... -class Slider(SimpleNamespace): +class Slider(ComponentNamespace): root = staticmethod(SliderRoot.create) track = staticmethod(SliderTrack.create) range = staticmethod(SliderRange.create) diff --git a/reflex/components/radix/themes/components/alert_dialog.py b/reflex/components/radix/themes/components/alert_dialog.py index 2990c96b0..81b8bb0af 100644 --- a/reflex/components/radix/themes/components/alert_dialog.py +++ b/reflex/components/radix/themes/components/alert_dialog.py @@ -1,8 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -95,7 +95,7 @@ class AlertDialogCancel(RadixThemesComponent): tag = "AlertDialog.Cancel" -class AlertDialog(SimpleNamespace): +class AlertDialog(ComponentNamespace): """AlertDialog components namespace.""" root = staticmethod(AlertDialogRoot.create) diff --git a/reflex/components/radix/themes/components/alert_dialog.pyi b/reflex/components/radix/themes/components/alert_dialog.pyi index 999cfe1aa..5ad8e5436 100644 --- a/reflex/components/radix/themes/components/alert_dialog.pyi +++ b/reflex/components/radix/themes/components/alert_dialog.pyi @@ -7,9 +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 types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import RadixThemesComponent @@ -647,7 +647,7 @@ class AlertDialogCancel(RadixThemesComponent): """ ... -class AlertDialog(SimpleNamespace): +class AlertDialog(ComponentNamespace): root = staticmethod(AlertDialogRoot.create) trigger = staticmethod(AlertDialogTrigger.create) content = staticmethod(AlertDialogContent.create) diff --git a/reflex/components/radix/themes/components/callout.py b/reflex/components/radix/themes/components/callout.py index 23f6de650..5eaf1cac0 100644 --- a/reflex/components/radix/themes/components/callout.py +++ b/reflex/components/radix/themes/components/callout.py @@ -1,11 +1,10 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Literal, Union import reflex as rx from reflex import el -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.lucide.icon import Icon from reflex.vars import Var @@ -81,7 +80,7 @@ class Callout(CalloutRoot): ) -class CalloutNamespace(SimpleNamespace): +class CalloutNamespace(ComponentNamespace): """Callout components namespace.""" root = staticmethod(CalloutRoot.create) diff --git a/reflex/components/radix/themes/components/callout.pyi b/reflex/components/radix/themes/components/callout.pyi index 7f792ee38..c96c59b64 100644 --- a/reflex/components/radix/themes/components/callout.pyi +++ b/reflex/components/radix/themes/components/callout.pyi @@ -7,11 +7,10 @@ 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 types import SimpleNamespace from typing import Literal, Union import reflex as rx from reflex import el -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.lucide.icon import Icon from reflex.vars import Var from ..base import LiteralAccentColor, RadixThemesComponent @@ -715,7 +714,7 @@ class Callout(CalloutRoot): """ ... -class CalloutNamespace(SimpleNamespace): +class CalloutNamespace(ComponentNamespace): root = staticmethod(CalloutRoot.create) icon = staticmethod(CalloutIcon.create) text = staticmethod(CalloutText.create) diff --git a/reflex/components/radix/themes/components/checkbox.py b/reflex/components/radix/themes/components/checkbox.py index 2303b8667..250a1da4c 100644 --- a/reflex/components/radix/themes/components/checkbox.py +++ b/reflex/components/radix/themes/components/checkbox.py @@ -1,9 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import EventTriggers @@ -162,7 +161,7 @@ class HighLevelCheckbox(RadixThemesComponent): ) -class CheckboxNamespace(SimpleNamespace): +class CheckboxNamespace(ComponentNamespace): """Checkbox components namespace.""" __call__ = staticmethod(HighLevelCheckbox.create) diff --git a/reflex/components/radix/themes/components/checkbox.pyi b/reflex/components/radix/themes/components/checkbox.pyi index 2cce04e90..fe0c4d998 100644 --- a/reflex/components/radix/themes/components/checkbox.pyi +++ b/reflex/components/radix/themes/components/checkbox.pyi @@ -7,9 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, Literal -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import EventTriggers @@ -371,7 +370,7 @@ class HighLevelCheckbox(RadixThemesComponent): """ ... -class CheckboxNamespace(SimpleNamespace): +class CheckboxNamespace(ComponentNamespace): @staticmethod def __call__( *children, diff --git a/reflex/components/radix/themes/components/context_menu.py b/reflex/components/radix/themes/components/context_menu.py index acb886ef0..7631d7970 100644 --- a/reflex/components/radix/themes/components/context_menu.py +++ b/reflex/components/radix/themes/components/context_menu.py @@ -1,7 +1,7 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, List, Literal +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -147,7 +147,7 @@ class ContextMenuSeparator(RadixThemesComponent): tag = "ContextMenu.Separator" -class ContextMenu(SimpleNamespace): +class ContextMenu(ComponentNamespace): """Menu representing a set of actions, displayed at the origin of a pointer right-click or long-press.""" root = staticmethod(ContextMenuRoot.create) diff --git a/reflex/components/radix/themes/components/context_menu.pyi b/reflex/components/radix/themes/components/context_menu.pyi index 03fd2c4c4..0f8a0b771 100644 --- a/reflex/components/radix/themes/components/context_menu.pyi +++ b/reflex/components/radix/themes/components/context_menu.pyi @@ -7,8 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import LiteralAccentColor, RadixThemesComponent @@ -826,7 +826,7 @@ class ContextMenuSeparator(RadixThemesComponent): """ ... -class ContextMenu(SimpleNamespace): +class ContextMenu(ComponentNamespace): root = staticmethod(ContextMenuRoot.create) trigger = staticmethod(ContextMenuTrigger.create) content = staticmethod(ContextMenuContent.create) diff --git a/reflex/components/radix/themes/components/dialog.py b/reflex/components/radix/themes/components/dialog.py index 6001ab14e..ebc80b5a3 100644 --- a/reflex/components/radix/themes/components/dialog.py +++ b/reflex/components/radix/themes/components/dialog.py @@ -1,9 +1,9 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -80,7 +80,7 @@ class DialogClose(RadixThemesComponent): tag = "Dialog.Close" -class Dialog(SimpleNamespace): +class Dialog(ComponentNamespace): """Dialog components namespace.""" root = __call__ = staticmethod(DialogRoot.create) diff --git a/reflex/components/radix/themes/components/dialog.pyi b/reflex/components/radix/themes/components/dialog.pyi index ca5939a0a..426b553a8 100644 --- a/reflex/components/radix/themes/components/dialog.pyi +++ b/reflex/components/radix/themes/components/dialog.pyi @@ -7,9 +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 types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import RadixThemesComponent @@ -570,7 +570,7 @@ class DialogClose(RadixThemesComponent): """ ... -class Dialog(SimpleNamespace): +class Dialog(ComponentNamespace): root = staticmethod(DialogRoot.create) trigger = staticmethod(DialogTrigger.create) title = staticmethod(DialogTitle.create) diff --git a/reflex/components/radix/themes/components/dropdown_menu.py b/reflex/components/radix/themes/components/dropdown_menu.py index b2516670a..013684975 100644 --- a/reflex/components/radix/themes/components/dropdown_menu.py +++ b/reflex/components/radix/themes/components/dropdown_menu.py @@ -1,7 +1,7 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, List, Literal, Union +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -272,7 +272,7 @@ class DropdownMenuSeparator(RadixThemesComponent): tag = "DropdownMenu.Separator" -class DropdownMenu(SimpleNamespace): +class DropdownMenu(ComponentNamespace): """DropdownMenu components namespace.""" root = staticmethod(DropdownMenuRoot.create) diff --git a/reflex/components/radix/themes/components/dropdown_menu.pyi b/reflex/components/radix/themes/components/dropdown_menu.pyi index 7f2d840d8..0ece0d499 100644 --- a/reflex/components/radix/themes/components/dropdown_menu.pyi +++ b/reflex/components/radix/themes/components/dropdown_menu.pyi @@ -7,8 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal, Union +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import LiteralAccentColor, RadixThemesComponent @@ -927,7 +927,7 @@ class DropdownMenuSeparator(RadixThemesComponent): """ ... -class DropdownMenu(SimpleNamespace): +class DropdownMenu(ComponentNamespace): root = staticmethod(DropdownMenuRoot.create) trigger = staticmethod(DropdownMenuTrigger.create) content = staticmethod(DropdownMenuContent.create) diff --git a/reflex/components/radix/themes/components/hover_card.py b/reflex/components/radix/themes/components/hover_card.py index ab3fdcea3..aee639302 100644 --- a/reflex/components/radix/themes/components/hover_card.py +++ b/reflex/components/radix/themes/components/hover_card.py @@ -1,8 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -64,7 +64,7 @@ class HoverCardContent(el.Div, RadixThemesComponent): avoid_collisions: Var[bool] -class HoverCard(SimpleNamespace): +class HoverCard(ComponentNamespace): """For sighted users to preview content available behind a link.""" root = __call__ = staticmethod(HoverCardRoot.create) diff --git a/reflex/components/radix/themes/components/hover_card.pyi b/reflex/components/radix/themes/components/hover_card.pyi index d732ce561..b67efe97e 100644 --- a/reflex/components/radix/themes/components/hover_card.pyi +++ b/reflex/components/radix/themes/components/hover_card.pyi @@ -7,9 +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 types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import RadixThemesComponent @@ -337,7 +337,7 @@ class HoverCardContent(el.Div, RadixThemesComponent): """ ... -class HoverCard(SimpleNamespace): +class HoverCard(ComponentNamespace): root = staticmethod(HoverCardRoot.create) trigger = staticmethod(HoverCardTrigger.create) content = staticmethod(HoverCardContent.create) diff --git a/reflex/components/radix/themes/components/popover.py b/reflex/components/radix/themes/components/popover.py index 5132e0aea..97250fc0e 100644 --- a/reflex/components/radix/themes/components/popover.py +++ b/reflex/components/radix/themes/components/popover.py @@ -1,8 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -86,7 +86,7 @@ class PopoverClose(RadixThemesComponent): tag = "Popover.Close" -class Popover(SimpleNamespace): +class Popover(ComponentNamespace): """Floating element for displaying rich content, triggered by a button.""" root = staticmethod(PopoverRoot.create) diff --git a/reflex/components/radix/themes/components/popover.pyi b/reflex/components/radix/themes/components/popover.pyi index e81f03be2..d60597785 100644 --- a/reflex/components/radix/themes/components/popover.pyi +++ b/reflex/components/radix/themes/components/popover.pyi @@ -7,9 +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 types import SimpleNamespace from typing import Any, Dict, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import RadixThemesComponent @@ -437,7 +437,7 @@ class PopoverClose(RadixThemesComponent): """ ... -class Popover(SimpleNamespace): +class Popover(ComponentNamespace): root = staticmethod(PopoverRoot.create) trigger = staticmethod(PopoverTrigger.create) content = staticmethod(PopoverContent.create) diff --git a/reflex/components/radix/themes/components/radio_group.py b/reflex/components/radix/themes/components/radio_group.py index 61d700ec9..ad7a0f10a 100644 --- a/reflex/components/radix/themes/components/radio_group.py +++ b/reflex/components/radix/themes/components/radio_group.py @@ -1,10 +1,9 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union import reflex as rx -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import EventTriggers @@ -189,7 +188,7 @@ class HighLevelRadioGroup(RadixThemesComponent): ) -class RadioGroup(SimpleNamespace): +class RadioGroup(ComponentNamespace): """RadioGroup components namespace.""" root = staticmethod(RadioGroupRoot.create) diff --git a/reflex/components/radix/themes/components/radio_group.pyi b/reflex/components/radix/themes/components/radio_group.pyi index 782c8ca8c..0fec881ba 100644 --- a/reflex/components/radix/themes/components/radio_group.pyi +++ b/reflex/components/radix/themes/components/radio_group.pyi @@ -7,10 +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 types import SimpleNamespace from typing import Any, Dict, List, Literal, Optional, Union import reflex as rx -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import EventTriggers @@ -451,7 +450,7 @@ class HighLevelRadioGroup(RadixThemesComponent): """ ... -class RadioGroup(SimpleNamespace): +class RadioGroup(ComponentNamespace): root = staticmethod(RadioGroupRoot.create) item = staticmethod(RadioGroupItem.create) diff --git a/reflex/components/radix/themes/components/select.py b/reflex/components/radix/themes/components/select.py index 3545852e9..9331f0b3e 100644 --- a/reflex/components/radix/themes/components/select.py +++ b/reflex/components/radix/themes/components/select.py @@ -1,9 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, List, Literal, Union import reflex as rx -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -236,7 +235,7 @@ class HighLevelSelect(SelectRoot): ) -class Select(SimpleNamespace): +class Select(ComponentNamespace): """Select components namespace.""" root = staticmethod(SelectRoot.create) diff --git a/reflex/components/radix/themes/components/select.pyi b/reflex/components/radix/themes/components/select.pyi index b93c7c0d6..f0a002b77 100644 --- a/reflex/components/radix/themes/components/select.pyi +++ b/reflex/components/radix/themes/components/select.pyi @@ -7,10 +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 types import SimpleNamespace from typing import Any, Dict, List, Literal, Union import reflex as rx -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent @@ -967,7 +966,7 @@ class HighLevelSelect(SelectRoot): """ ... -class Select(SimpleNamespace): +class Select(ComponentNamespace): root = staticmethod(SelectRoot.create) trigger = staticmethod(SelectTrigger.create) content = staticmethod(SelectContent.create) diff --git a/reflex/components/radix/themes/components/table.py b/reflex/components/radix/themes/components/table.py index aa032f318..a2b3bada3 100644 --- a/reflex/components/radix/themes/components/table.py +++ b/reflex/components/radix/themes/components/table.py @@ -1,8 +1,8 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import List, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.vars import Var from ..base import ( @@ -111,7 +111,7 @@ class TableRowHeaderCell(el.Th, RadixThemesComponent): ] -class Table(SimpleNamespace): +class Table(ComponentNamespace): """Table components namespace.""" root = staticmethod(TableRoot.create) diff --git a/reflex/components/radix/themes/components/table.pyi b/reflex/components/radix/themes/components/table.pyi index 73b9fa7e2..5220601ce 100644 --- a/reflex/components/radix/themes/components/table.pyi +++ b/reflex/components/radix/themes/components/table.pyi @@ -7,9 +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 types import SimpleNamespace from typing import List, Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.vars import Var from ..base import RadixThemesComponent @@ -1066,7 +1066,7 @@ class TableRowHeaderCell(el.Th, RadixThemesComponent): """ ... -class Table(SimpleNamespace): +class Table(ComponentNamespace): root = staticmethod(TableRoot.create) header = staticmethod(TableHeader.create) body = staticmethod(TableBody.create) diff --git a/reflex/components/radix/themes/components/tabs.py b/reflex/components/radix/themes/components/tabs.py index 18ce4726b..b0a169741 100644 --- a/reflex/components/radix/themes/components/tabs.py +++ b/reflex/components/radix/themes/components/tabs.py @@ -1,7 +1,7 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, List, Literal +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var @@ -71,7 +71,7 @@ class TabsContent(RadixThemesComponent): value: Var[str] -class Tabs(SimpleNamespace): +class Tabs(ComponentNamespace): """Set of content sections to be displayed one at a time.""" root = __call__ = staticmethod(TabsRoot.create) diff --git a/reflex/components/radix/themes/components/tabs.pyi b/reflex/components/radix/themes/components/tabs.pyi index af4c66db3..87b8df31d 100644 --- a/reflex/components/radix/themes/components/tabs.pyi +++ b/reflex/components/radix/themes/components/tabs.pyi @@ -7,8 +7,8 @@ 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 types import SimpleNamespace from typing import Any, Dict, List, Literal +from reflex.components.component import ComponentNamespace from reflex.constants import EventTriggers from reflex.vars import Var from ..base import RadixThemesComponent @@ -352,7 +352,7 @@ class TabsContent(RadixThemesComponent): """ ... -class Tabs(SimpleNamespace): +class Tabs(ComponentNamespace): root = staticmethod(TabsRoot.create) list = staticmethod(TabsList.create) trigger = staticmethod(TabsTrigger.create) diff --git a/reflex/components/radix/themes/components/text_field.py b/reflex/components/radix/themes/components/text_field.py index 8f25e75aa..74b88fd27 100644 --- a/reflex/components/radix/themes/components/text_field.py +++ b/reflex/components/radix/themes/components/text_field.py @@ -1,10 +1,9 @@ """Interactive components provided by @radix-ui/themes.""" -from types import SimpleNamespace from typing import Any, Dict, Literal from reflex.components import el -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.debounce import DebounceInput from reflex.constants import EventTriggers from reflex.vars import Var @@ -159,7 +158,7 @@ class Input(RadixThemesComponent): } -class TextField(SimpleNamespace): +class TextField(ComponentNamespace): """TextField components namespace.""" root = staticmethod(TextFieldRoot.create) diff --git a/reflex/components/radix/themes/components/text_field.pyi b/reflex/components/radix/themes/components/text_field.pyi index c6f88b2e9..24239f93d 100644 --- a/reflex/components/radix/themes/components/text_field.pyi +++ b/reflex/components/radix/themes/components/text_field.pyi @@ -7,10 +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 types import SimpleNamespace from typing import Any, Dict, Literal from reflex.components import el -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.debounce import DebounceInput from reflex.constants import EventTriggers from reflex.vars import Var @@ -888,7 +887,7 @@ class Input(RadixThemesComponent): ... def get_event_triggers(self) -> Dict[str, Any]: ... -class TextField(SimpleNamespace): +class TextField(ComponentNamespace): root = staticmethod(TextFieldRoot.create) input = staticmethod(TextFieldInput.create) slot = staticmethod(TextFieldSlot.create) diff --git a/reflex/components/radix/themes/layout/list.py b/reflex/components/radix/themes/layout/list.py index 0de3b7dcc..8d458910b 100644 --- a/reflex/components/radix/themes/layout/list.py +++ b/reflex/components/radix/themes/layout/list.py @@ -1,9 +1,8 @@ """List components.""" -from types import SimpleNamespace from typing import Iterable, Literal, Optional, Union -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.foreach import Foreach from reflex.components.el.elements.typography import Li from reflex.style import Style @@ -142,7 +141,7 @@ class ListItem(Li): ... -class List(SimpleNamespace): +class List(ComponentNamespace): """List components.""" item = ListItem.create diff --git a/reflex/components/radix/themes/layout/list.pyi b/reflex/components/radix/themes/layout/list.pyi index f28c6223b..4ee3f65dd 100644 --- a/reflex/components/radix/themes/layout/list.pyi +++ b/reflex/components/radix/themes/layout/list.pyi @@ -7,9 +7,8 @@ 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 types import SimpleNamespace from typing import Iterable, Literal, Optional, Union -from reflex.components.component import Component +from reflex.components.component import Component, ComponentNamespace from reflex.components.core.foreach import Foreach from reflex.components.el.elements.typography import Li from reflex.style import Style @@ -1014,7 +1013,7 @@ class ListItem(Li): """ ... -class List(SimpleNamespace): +class List(ComponentNamespace): item = ListItem.create ordered = OrderedList.create unordered = UnorderedList.create diff --git a/reflex/components/radix/themes/typography/text.py b/reflex/components/radix/themes/typography/text.py index 7657301a2..96512fe58 100644 --- a/reflex/components/radix/themes/typography/text.py +++ b/reflex/components/radix/themes/typography/text.py @@ -5,10 +5,10 @@ https://www.radix-ui.com/themes/docs/theme/typography from __future__ import annotations -from types import SimpleNamespace from typing import Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.vars import Var from ..base import ( @@ -107,7 +107,7 @@ class Strong(el.Strong, RadixThemesComponent): tag = "Strong" -class TextNamespace(SimpleNamespace): +class TextNamespace(ComponentNamespace): """Checkbox components namespace.""" __call__ = staticmethod(Text.create) diff --git a/reflex/components/radix/themes/typography/text.pyi b/reflex/components/radix/themes/typography/text.pyi index 277ee1407..054b331d9 100644 --- a/reflex/components/radix/themes/typography/text.pyi +++ b/reflex/components/radix/themes/typography/text.pyi @@ -7,9 +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 types import SimpleNamespace from typing import Literal from reflex import el +from reflex.components.component import ComponentNamespace from reflex.vars import Var from ..base import LiteralAccentColor, RadixThemesComponent from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight @@ -1138,7 +1138,7 @@ class Strong(el.Strong, RadixThemesComponent): """ ... -class TextNamespace(SimpleNamespace): +class TextNamespace(ComponentNamespace): em = staticmethod(Em.create) kbd = staticmethod(Kbd.create) quote = staticmethod(Quote.create) diff --git a/tests/test_style.py b/tests/test_style.py index cbe2b2ac1..ccc7b6569 100644 --- a/tests/test_style.py +++ b/tests/test_style.py @@ -6,6 +6,7 @@ import pytest import reflex as rx from reflex import style +from reflex.components.component import evaluate_style_namespaces from reflex.style import Style from reflex.vars import Var @@ -494,3 +495,11 @@ def test_style_via_component_with_state( assert comp.style._var_data == expected_get_style["css"]._var_data # Assert that style values are equal. compare_dict_of_var(comp._get_style(), expected_get_style) + + +def test_evaluate_style_namespaces(): + """Test that namespaces get converted to component create functions.""" + style_dict = {rx.text: {"color": "blue"}} + assert rx.text.__call__ not in style_dict + style_dict = evaluate_style_namespaces(style_dict) # type: ignore + assert rx.text.__call__ in style_dict