
* add eradicate rules for commented out code * remove output change * fix pyi messed up indent * fix pyi again * fix layout docstring * fix pyi_generator to remove commented out props from docs * fix pyi_generator and regenerate some pyi * fix double strip * update all pyi * try to fix stuff in pyi_gen * whatever * remove that maybe? i don't know * fix that shit? * fix more shit, idk * better not see you ever again, extra line
298 lines
8.6 KiB
Python
298 lines
8.6 KiB
Python
"""Base classes for radix-themes components."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, Literal
|
|
|
|
from reflex.components import Component
|
|
from reflex.components.core.breakpoints import Responsive
|
|
from reflex.components.tags import Tag
|
|
from reflex.config import get_config
|
|
from reflex.utils.imports import ImportDict, ImportVar
|
|
from reflex.vars.base import Var
|
|
|
|
LiteralAlign = Literal["start", "center", "end", "baseline", "stretch"]
|
|
LiteralJustify = Literal["start", "center", "end", "between"]
|
|
LiteralSpacing = Literal["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
|
LiteralVariant = Literal["classic", "solid", "soft", "surface", "outline", "ghost"]
|
|
LiteralAppearance = Literal["inherit", "light", "dark"]
|
|
LiteralGrayColor = Literal["gray", "mauve", "slate", "sage", "olive", "sand", "auto"]
|
|
LiteralPanelBackground = Literal["solid", "translucent"]
|
|
LiteralRadius = Literal["none", "small", "medium", "large", "full"]
|
|
LiteralScaling = Literal["90%", "95%", "100%", "105%", "110%"]
|
|
LiteralAccentColor = Literal[
|
|
"tomato",
|
|
"red",
|
|
"ruby",
|
|
"crimson",
|
|
"pink",
|
|
"plum",
|
|
"purple",
|
|
"violet",
|
|
"iris",
|
|
"indigo",
|
|
"blue",
|
|
"cyan",
|
|
"teal",
|
|
"jade",
|
|
"green",
|
|
"grass",
|
|
"brown",
|
|
"orange",
|
|
"sky",
|
|
"mint",
|
|
"lime",
|
|
"yellow",
|
|
"amber",
|
|
"gold",
|
|
"bronze",
|
|
"gray",
|
|
]
|
|
|
|
|
|
class CommonMarginProps(Component):
|
|
"""Many radix-themes elements accept shorthand margin props."""
|
|
|
|
# Margin: "0" - "9" # noqa: ERA001
|
|
m: Var[LiteralSpacing]
|
|
|
|
# Margin horizontal: "0" - "9"
|
|
mx: Var[LiteralSpacing]
|
|
|
|
# Margin vertical: "0" - "9"
|
|
my: Var[LiteralSpacing]
|
|
|
|
# Margin top: "0" - "9"
|
|
mt: Var[LiteralSpacing]
|
|
|
|
# Margin right: "0" - "9"
|
|
mr: Var[LiteralSpacing]
|
|
|
|
# Margin bottom: "0" - "9"
|
|
mb: Var[LiteralSpacing]
|
|
|
|
# Margin left: "0" - "9"
|
|
ml: Var[LiteralSpacing]
|
|
|
|
|
|
class CommonPaddingProps(Component):
|
|
"""Many radix-themes elements accept shorthand padding props."""
|
|
|
|
# Padding: "0" - "9" # noqa: ERA001
|
|
p: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding horizontal: "0" - "9"
|
|
px: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding vertical: "0" - "9"
|
|
py: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding top: "0" - "9"
|
|
pt: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding right: "0" - "9"
|
|
pr: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding bottom: "0" - "9"
|
|
pb: Var[Responsive[LiteralSpacing]]
|
|
|
|
# Padding left: "0" - "9"
|
|
pl: Var[Responsive[LiteralSpacing]]
|
|
|
|
|
|
class RadixLoadingProp(Component):
|
|
"""Base class for components that can be in a loading state."""
|
|
|
|
# If set, show an rx.spinner instead of the component children.
|
|
loading: Var[bool]
|
|
|
|
|
|
class RadixThemesComponent(Component):
|
|
"""Base class for all @radix-ui/themes components."""
|
|
|
|
library = "@radix-ui/themes@^3.0.0"
|
|
|
|
# Temporary pin < 3.1.5 until radix-ui/themes#627 is resolved.
|
|
library = library + " && <3.1.5"
|
|
|
|
# "Fake" prop color_scheme is used to avoid shadowing CSS prop "color".
|
|
_rename_props: Dict[str, str] = {"colorScheme": "color"}
|
|
|
|
@classmethod
|
|
def create(
|
|
cls,
|
|
*children,
|
|
**props,
|
|
) -> Component:
|
|
"""Create a new component instance.
|
|
|
|
Will prepend "RadixThemes" to the component tag to avoid conflicts with
|
|
other UI libraries for common names, like Text and Button.
|
|
|
|
Args:
|
|
*children: Child components.
|
|
**props: Component properties.
|
|
|
|
Returns:
|
|
A new component instance.
|
|
"""
|
|
component = super().create(*children, **props)
|
|
if component.library is None:
|
|
component.library = RadixThemesComponent.__fields__["library"].default
|
|
component.alias = "RadixThemes" + (component.tag or type(component).__name__)
|
|
return component
|
|
|
|
@staticmethod
|
|
def _get_app_wrap_components() -> dict[tuple[int, str], Component]:
|
|
return {
|
|
(45, "RadixThemesColorModeProvider"): RadixThemesColorModeProvider.create(),
|
|
}
|
|
|
|
|
|
class RadixThemesTriggerComponent(RadixThemesComponent):
|
|
"""Base class for Trigger, Close, Cancel, and Accept components.
|
|
|
|
These components trigger some action in an overlay component that depends on the
|
|
on_click event, and thus if a child is provided and has on_click specified, it
|
|
will overtake the internal action, unless it is wrapped in some inert component,
|
|
in this case, a Flex.
|
|
"""
|
|
|
|
@classmethod
|
|
def create(cls, *children: Any, **props: Any) -> Component:
|
|
"""Create a new RadixThemesTriggerComponent instance.
|
|
|
|
Args:
|
|
children: The children of the component.
|
|
props: The properties of the component.
|
|
|
|
Returns:
|
|
The new RadixThemesTriggerComponent instance.
|
|
"""
|
|
from .layout.flex import Flex
|
|
|
|
for child in children:
|
|
if "on_click" in getattr(child, "event_triggers", {}):
|
|
children = (Flex.create(*children),)
|
|
break
|
|
return super().create(*children, **props)
|
|
|
|
|
|
class Theme(RadixThemesComponent):
|
|
"""A theme provider for radix components.
|
|
|
|
This should be applied as `App.theme` to apply the theme to all radix
|
|
components in the app with the given settings.
|
|
|
|
It can also be used in a normal page to apply specified properties to all
|
|
child elements as an override of the main theme.
|
|
"""
|
|
|
|
tag = "Theme"
|
|
|
|
# Whether to apply the themes background color to the theme node. Defaults to True.
|
|
has_background: Var[bool]
|
|
|
|
# Override light or dark mode theme: "inherit" | "light" | "dark". Defaults to "inherit".
|
|
appearance: Var[LiteralAppearance]
|
|
|
|
# The color used for default buttons, typography, backgrounds, etc
|
|
accent_color: Var[LiteralAccentColor]
|
|
|
|
# The shade of gray, defaults to "auto".
|
|
gray_color: Var[LiteralGrayColor]
|
|
|
|
# Whether panel backgrounds are translucent: "solid" | "translucent" (default)
|
|
panel_background: Var[LiteralPanelBackground]
|
|
|
|
# Element border radius: "none" | "small" | "medium" | "large" | "full". Defaults to "medium".
|
|
radius: Var[LiteralRadius]
|
|
|
|
# Scale of all theme items: "90%" | "95%" | "100%" | "105%" | "110%". Defaults to "100%"
|
|
scaling: Var[LiteralScaling]
|
|
|
|
@classmethod
|
|
def create(
|
|
cls,
|
|
*children,
|
|
color_mode: LiteralAppearance | None = None,
|
|
theme_panel: bool = False,
|
|
**props,
|
|
) -> Component:
|
|
"""Create a new Radix Theme specification.
|
|
|
|
Args:
|
|
*children: Child components.
|
|
color_mode: Map to appearance prop.
|
|
theme_panel: Whether to include a panel for editing the theme.
|
|
**props: Component properties.
|
|
|
|
Returns:
|
|
A new component instance.
|
|
"""
|
|
if color_mode is not None:
|
|
props["appearance"] = color_mode
|
|
if theme_panel:
|
|
children = [ThemePanel.create(), *children]
|
|
return super().create(*children, **props)
|
|
|
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
"""Add imports for the Theme component.
|
|
|
|
Returns:
|
|
The import dict.
|
|
"""
|
|
_imports: ImportDict = {
|
|
"$/utils/theme.js": [ImportVar(tag="theme", is_default=True)],
|
|
}
|
|
if get_config().tailwind is None:
|
|
# When tailwind is disabled, import the radix-ui styles directly because they will
|
|
# not be included in the tailwind.css file.
|
|
_imports[""] = ImportVar(
|
|
tag="@radix-ui/themes/styles.css",
|
|
install=False,
|
|
)
|
|
return _imports
|
|
|
|
def _render(self, props: dict[str, Any] | None = None) -> Tag:
|
|
tag = super()._render(props)
|
|
tag.add_props(
|
|
css=Var(
|
|
_js_expr="{...theme.styles.global[':root'], ...theme.styles.global.body}"
|
|
),
|
|
)
|
|
tag.remove_props("appearance")
|
|
return tag
|
|
|
|
|
|
class ThemePanel(RadixThemesComponent):
|
|
"""Visual editor for creating and editing themes.
|
|
|
|
Include as a child component of Theme to use in your app.
|
|
"""
|
|
|
|
tag = "ThemePanel"
|
|
|
|
# Whether the panel is open. Defaults to False.
|
|
default_open: Var[bool]
|
|
|
|
def add_imports(self) -> dict[str, str]:
|
|
"""Add imports for the ThemePanel component.
|
|
|
|
Returns:
|
|
The import dict.
|
|
"""
|
|
return {"react": "useEffect"}
|
|
|
|
|
|
class RadixThemesColorModeProvider(Component):
|
|
"""Next-themes integration for radix themes components."""
|
|
|
|
library = "$/components/reflex/radix_themes_color_mode_provider.js"
|
|
tag = "RadixThemesColorModeProvider"
|
|
is_default = True
|
|
|
|
|
|
theme = Theme.create
|
|
theme_panel = ThemePanel.create
|