add_style api (#3202)
This commit is contained in:
parent
d68792f7b3
commit
57476966f3
@ -833,9 +833,7 @@ class App(Base):
|
|||||||
|
|
||||||
for _route, component in self.pages.items():
|
for _route, component in self.pages.items():
|
||||||
# Merge the component style with the app style.
|
# Merge the component style with the app style.
|
||||||
component._add_style_recursive(self.style)
|
component._add_style_recursive(self.style, self.theme)
|
||||||
|
|
||||||
component.apply_theme(self.theme)
|
|
||||||
|
|
||||||
# Add component._get_all_imports() to all_imports.
|
# Add component._get_all_imports() to all_imports.
|
||||||
all_imports.update(component._get_all_imports())
|
all_imports.update(component._get_all_imports())
|
||||||
|
@ -263,9 +263,18 @@ def _compile_stateful_components(
|
|||||||
# Reset this flag to render the actual component.
|
# Reset this flag to render the actual component.
|
||||||
component.rendered_as_shared = False
|
component.rendered_as_shared = False
|
||||||
|
|
||||||
|
# Include dynamic imports in the shared component.
|
||||||
|
if dynamic_imports := component._get_all_dynamic_imports():
|
||||||
|
rendered_components.update(
|
||||||
|
{dynamic_import: None for dynamic_import in dynamic_imports}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Include custom code in the shared component.
|
||||||
rendered_components.update(
|
rendered_components.update(
|
||||||
{code: None for code in component._get_all_custom_code()},
|
{code: None for code in component._get_all_custom_code()},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Include all imports in the shared component.
|
||||||
all_import_dicts.append(component._get_all_imports())
|
all_import_dicts.append(component._get_all_imports())
|
||||||
|
|
||||||
# Indicate that this component now imports from the shared file.
|
# Indicate that this component now imports from the shared file.
|
||||||
|
@ -608,6 +608,8 @@ class Component(BaseComponent, ABC):
|
|||||||
def _apply_theme(self, theme: Optional[Component]):
|
def _apply_theme(self, theme: Optional[Component]):
|
||||||
"""Apply the theme to this component.
|
"""Apply the theme to this component.
|
||||||
|
|
||||||
|
Deprecated. Use add_style instead.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
theme: The theme to apply.
|
theme: The theme to apply.
|
||||||
"""
|
"""
|
||||||
@ -779,44 +781,119 @@ class Component(BaseComponent, ABC):
|
|||||||
|
|
||||||
return cls(children=children, **props)
|
return cls(children=children, **props)
|
||||||
|
|
||||||
def _add_style(self, style: dict):
|
def add_style(self) -> Style | None:
|
||||||
"""Add additional style to the component.
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Downstream components can override this method to return a style dict
|
||||||
|
that will be applied to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style to add.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _add_style(self) -> Style:
|
||||||
|
"""Call add_style for all bases in the MRO.
|
||||||
|
|
||||||
|
Downstream components should NOT override. Use add_style instead.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style to add.
|
||||||
|
"""
|
||||||
|
styles = []
|
||||||
|
vars = []
|
||||||
|
|
||||||
|
# Walk the MRO to call all `add_style` methods.
|
||||||
|
for base in self._iter_parent_classes_with_method("add_style"):
|
||||||
|
s = base.add_style(self) # type: ignore
|
||||||
|
if s is not None:
|
||||||
|
styles.append(s)
|
||||||
|
vars.append(s._var_data)
|
||||||
|
|
||||||
|
_style = Style()
|
||||||
|
for s in reversed(styles):
|
||||||
|
_style.update(s)
|
||||||
|
|
||||||
|
_style._var_data = VarData.merge(*vars)
|
||||||
|
return _style
|
||||||
|
|
||||||
|
def _get_component_style(self, styles: ComponentStyle) -> Style | None:
|
||||||
|
"""Get the style to the component from `App.style`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
style: A style dict to apply.
|
styles: The style to apply.
|
||||||
"""
|
|
||||||
self.style.update(style)
|
|
||||||
|
|
||||||
def _add_style_recursive(self, style: ComponentStyle) -> Component:
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
component_style = None
|
||||||
|
if type(self) in styles:
|
||||||
|
component_style = Style(styles[type(self)])
|
||||||
|
if self.create in styles:
|
||||||
|
component_style = Style(styles[self.create])
|
||||||
|
return component_style
|
||||||
|
|
||||||
|
def _add_style_recursive(
|
||||||
|
self, style: ComponentStyle, theme: Optional[Component] = None
|
||||||
|
) -> Component:
|
||||||
"""Add additional style to the component and its children.
|
"""Add additional style to the component and its children.
|
||||||
|
|
||||||
|
Apply order is as follows (with the latest overriding the earliest):
|
||||||
|
1. Default style from `_add_style`/`add_style`.
|
||||||
|
2. User-defined style from `App.style`.
|
||||||
|
3. User-defined style from `Component.style`.
|
||||||
|
4. style dict and css props passed to the component instance.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
style: A dict from component to styling.
|
style: A dict from component to styling.
|
||||||
|
theme: The theme to apply. (for retro-compatibility with deprecated _apply_theme API)
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
UserWarning: If `_add_style` has been overridden.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The component with the additional style.
|
The component with the additional style.
|
||||||
"""
|
"""
|
||||||
component_style = None
|
# 1. Default style from `_add_style`/`add_style`.
|
||||||
if type(self) in style:
|
if type(self)._add_style != Component._add_style:
|
||||||
# Extract the style for this component.
|
raise UserWarning(
|
||||||
component_style = Style(style[type(self)])
|
"Do not override _add_style directly. Use add_style instead."
|
||||||
if self.create in style:
|
)
|
||||||
component_style = Style(style[self.create])
|
new_style = self._add_style()
|
||||||
if component_style is not None:
|
style_vars = [new_style._var_data]
|
||||||
# Only add style props that are not overridden.
|
|
||||||
component_style = {
|
|
||||||
k: v for k, v in component_style.items() if k not in self.style
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add the style to the component.
|
# 2. User-defined style from `App.style`.
|
||||||
self._add_style(component_style)
|
component_style = self._get_component_style(style)
|
||||||
|
if component_style:
|
||||||
|
new_style.update(component_style)
|
||||||
|
style_vars.append(component_style._var_data)
|
||||||
|
|
||||||
|
# 3. User-defined style from `Component.style`.
|
||||||
|
# Apply theme for retro-compatibility with deprecated _apply_theme API
|
||||||
|
if type(self)._apply_theme != Component._apply_theme:
|
||||||
|
console.deprecate(
|
||||||
|
f"{self.__class__.__name__}._apply_theme",
|
||||||
|
reason="use add_style instead",
|
||||||
|
deprecation_version="0.5.0",
|
||||||
|
removal_version="0.6.0",
|
||||||
|
)
|
||||||
|
self._apply_theme(theme)
|
||||||
|
|
||||||
|
# 4. style dict and css props passed to the component instance.
|
||||||
|
new_style.update(self.style)
|
||||||
|
style_vars.append(self.style._var_data)
|
||||||
|
|
||||||
|
new_style._var_data = VarData.merge(*style_vars)
|
||||||
|
|
||||||
|
# Assign the new style
|
||||||
|
self.style = new_style
|
||||||
|
|
||||||
# Recursively add style to the children.
|
# Recursively add style to the children.
|
||||||
for child in self.children:
|
for child in self.children:
|
||||||
# Skip BaseComponent and StatefulComponent children.
|
# Skip BaseComponent and StatefulComponent children.
|
||||||
if not isinstance(child, Component):
|
if not isinstance(child, Component):
|
||||||
continue
|
continue
|
||||||
child._add_style_recursive(style)
|
child._add_style_recursive(style, theme)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _get_style(self) -> dict:
|
def _get_style(self) -> dict:
|
||||||
|
@ -102,15 +102,6 @@ class Cond(MemoizationLeaf):
|
|||||||
_IS_TRUE_IMPORT,
|
_IS_TRUE_IMPORT,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
"""Apply the theme to this component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
theme: The theme to apply.
|
|
||||||
"""
|
|
||||||
self.comp1.apply_theme(theme) # type: ignore
|
|
||||||
self.comp2.apply_theme(theme) # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def cond(condition: Any, c1: Component, c2: Any) -> Component:
|
def cond(condition: Any, c1: Component, c2: Any) -> Component:
|
||||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from typing import Any, Callable, Iterable, Optional
|
from typing import Any, Callable, Iterable
|
||||||
|
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
@ -23,17 +23,6 @@ class Foreach(Component):
|
|||||||
# A function from the render args to the component.
|
# A function from the render args to the component.
|
||||||
render_fn: Callable = Fragment.create
|
render_fn: Callable = Fragment.create
|
||||||
|
|
||||||
# The theme if set.
|
|
||||||
theme: Optional[Component] = None
|
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
"""Apply the theme to this component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
theme: The theme to apply.
|
|
||||||
"""
|
|
||||||
self.theme = theme
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, iterable: Var[Iterable], render_fn: Callable, **props) -> Foreach:
|
def create(cls, iterable: Var[Iterable], render_fn: Callable, **props) -> Foreach:
|
||||||
"""Create a foreach component.
|
"""Create a foreach component.
|
||||||
@ -97,10 +86,6 @@ class Foreach(Component):
|
|||||||
tag = self._render()
|
tag = self._render()
|
||||||
component = tag.render_component()
|
component = tag.render_component()
|
||||||
|
|
||||||
# Apply the theme to the children.
|
|
||||||
if self.theme is not None:
|
|
||||||
component.apply_theme(self.theme)
|
|
||||||
|
|
||||||
return dict(
|
return dict(
|
||||||
tag.add_props(
|
tag.add_props(
|
||||||
**self.event_triggers,
|
**self.event_triggers,
|
||||||
|
@ -273,18 +273,3 @@ class Match(MemoizationLeaf):
|
|||||||
super()._get_imports(),
|
super()._get_imports(),
|
||||||
getattr(self.cond._var_data, "imports", {}),
|
getattr(self.cond._var_data, "imports", {}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
"""Apply the theme to this component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
theme: The theme to apply.
|
|
||||||
"""
|
|
||||||
# apply theme to return components.
|
|
||||||
for match_case in self.match_cases:
|
|
||||||
if isinstance(match_case[-1], Component):
|
|
||||||
match_case[-1].apply_theme(theme)
|
|
||||||
|
|
||||||
# apply theme to default component
|
|
||||||
if isinstance(self.default, Component):
|
|
||||||
self.default.apply_theme(theme)
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""A code component."""
|
"""A code component."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Dict, Literal, Optional, Union
|
from typing import Dict, Literal, Optional, Union
|
||||||
|
|
||||||
@ -491,8 +493,9 @@ class CodeBlock(Component):
|
|||||||
else:
|
else:
|
||||||
return code_block
|
return code_block
|
||||||
|
|
||||||
def _add_style(self, style):
|
def add_style(self) -> Style | None:
|
||||||
self.custom_style.update(style) # type: ignore
|
"""Add style to the component."""
|
||||||
|
self.custom_style.update(self.style)
|
||||||
|
|
||||||
def _render(self):
|
def _render(self):
|
||||||
out = super()._render()
|
out = super()._render()
|
||||||
|
@ -1111,5 +1111,6 @@ class CodeBlock(Component):
|
|||||||
The text component.
|
The text component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def convert_theme_name(theme) -> str: ...
|
def convert_theme_name(theme) -> str: ...
|
||||||
|
@ -18,7 +18,6 @@ from reflex.components.radix.themes.typography.heading import Heading
|
|||||||
from reflex.components.radix.themes.typography.link import Link
|
from reflex.components.radix.themes.typography.link import Link
|
||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.components.tags.tag import Tag
|
from reflex.components.tags.tag import Tag
|
||||||
from reflex.style import Style
|
|
||||||
from reflex.utils import console, imports, types
|
from reflex.utils import console, imports, types
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
@ -230,7 +229,8 @@ class Markdown(Component):
|
|||||||
component = self.component_map[tag](*children, **props).set(
|
component = self.component_map[tag](*children, **props).set(
|
||||||
special_props=special_props
|
special_props=special_props
|
||||||
)
|
)
|
||||||
component._add_style(Style(self.custom_styles.get(tag, {})))
|
component.style.update(self.custom_styles.get(tag, {}))
|
||||||
|
|
||||||
return component
|
return component
|
||||||
|
|
||||||
def format_component(self, tag: str, **props) -> str:
|
def format_component(self, tag: str, **props) -> str:
|
||||||
|
@ -22,7 +22,6 @@ from reflex.components.radix.themes.typography.heading import Heading
|
|||||||
from reflex.components.radix.themes.typography.link import Link
|
from reflex.components.radix.themes.typography.link import Link
|
||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.components.tags.tag import Tag
|
from reflex.components.tags.tag import Tag
|
||||||
from reflex.style import Style
|
|
||||||
from reflex.utils import console, imports, types
|
from reflex.utils import console, imports, types
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
@ -5,303 +5,43 @@ from __future__ import annotations
|
|||||||
from typing import Any, Dict, List, Literal, Optional, Union
|
from typing import Any, Dict, List, Literal, Optional, Union
|
||||||
|
|
||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import Component, ComponentNamespace
|
||||||
from reflex.components.core.match import Match
|
from reflex.components.core.colors import color
|
||||||
from reflex.components.lucide.icon import Icon
|
from reflex.components.lucide.icon import Icon
|
||||||
from reflex.components.radix.primitives.base import RadixPrimitiveComponent
|
from reflex.components.radix.primitives.base import RadixPrimitiveComponent
|
||||||
from reflex.components.radix.themes.base import LiteralAccentColor
|
from reflex.components.radix.themes.base import LiteralAccentColor
|
||||||
from reflex.style import (
|
from reflex.style import Style
|
||||||
Style,
|
|
||||||
convert_dict_to_style_and_format_emotion,
|
|
||||||
format_as_emotion,
|
|
||||||
)
|
|
||||||
from reflex.utils import imports
|
from reflex.utils import imports
|
||||||
from reflex.vars import BaseVar, Var, VarData, get_uuid_string_var
|
from reflex.vars import Var, get_uuid_string_var
|
||||||
|
|
||||||
LiteralAccordionType = Literal["single", "multiple"]
|
LiteralAccordionType = Literal["single", "multiple"]
|
||||||
LiteralAccordionDir = Literal["ltr", "rtl"]
|
LiteralAccordionDir = Literal["ltr", "rtl"]
|
||||||
LiteralAccordionOrientation = Literal["vertical", "horizontal"]
|
LiteralAccordionOrientation = Literal["vertical", "horizontal"]
|
||||||
LiteralAccordionRootVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
|
LiteralAccordionVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
|
||||||
LiteralAccordionRootColorScheme = Literal["primary", "accent"]
|
|
||||||
|
|
||||||
DEFAULT_ANIMATION_DURATION = 250
|
DEFAULT_ANIMATION_DURATION = 250
|
||||||
|
|
||||||
|
|
||||||
def get_theme_accordion_root(variant: Var[str], color_scheme: Var[str]) -> BaseVar:
|
|
||||||
"""Get the theme for the accordion root component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
variant: The variant of the accordion.
|
|
||||||
color_scheme: The color of the accordion.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The theme for the accordion root component.
|
|
||||||
"""
|
|
||||||
return Match.create( # type: ignore
|
|
||||||
variant,
|
|
||||||
(
|
|
||||||
"soft",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"border_radius": "6px",
|
|
||||||
"background_color": f"var(--{color_scheme}-3)",
|
|
||||||
"box_shadow": "0 2px 10px var(--black-a1)",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"outline",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"border_radius": "6px",
|
|
||||||
"border": f"1px solid var(--{color_scheme}-6)",
|
|
||||||
"box_shadow": "0 2px 10px var(--black-a1)",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"surface",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"border_radius": "6px",
|
|
||||||
"border": f"1px solid var(--{color_scheme}-6)",
|
|
||||||
"background_color": f"var(--{color_scheme}-3)",
|
|
||||||
"box_shadow": "0 2px 10px var(--black-a1)",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"ghost",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"border_radius": "6px",
|
|
||||||
"background_color": "none",
|
|
||||||
"box_shadow": "None",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"border_radius": "6px",
|
|
||||||
"background_color": f"var(--{color_scheme}-9)",
|
|
||||||
"box_shadow": "0 2px 10px var(--black-a4)",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
# defaults to classic
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_theme_accordion_item():
|
|
||||||
"""Get the theme for the accordion item component.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The theme for the accordion item component.
|
|
||||||
"""
|
|
||||||
return convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"overflow": "hidden",
|
|
||||||
"width": "100%",
|
|
||||||
"margin_top": "1px",
|
|
||||||
"&:first-child": {
|
|
||||||
"margin_top": 0,
|
|
||||||
"border_top_left_radius": "4px",
|
|
||||||
"border_top_right_radius": "4px",
|
|
||||||
},
|
|
||||||
"&:last-child": {
|
|
||||||
"border_bottom_left_radius": "4px",
|
|
||||||
"border_bottom_right_radius": "4px",
|
|
||||||
},
|
|
||||||
"&:focus-within": {
|
|
||||||
"position": "relative",
|
|
||||||
"z_index": 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_theme_accordion_header() -> dict[str, str]:
|
|
||||||
"""Get the theme for the accordion header component.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The theme for the accordion header component.
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
"display": "flex",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_theme_accordion_trigger(variant: str | Var, color_scheme: str | Var) -> BaseVar:
|
|
||||||
"""Get the theme for the accordion trigger component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
variant: The variant of the accordion.
|
|
||||||
color_scheme: The color of the accordion.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The theme for the accordion trigger component.
|
|
||||||
"""
|
|
||||||
return Match.create( # type: ignore
|
|
||||||
variant,
|
|
||||||
(
|
|
||||||
"soft",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"color": f"var(--{color_scheme}-11)",
|
|
||||||
"&:hover": {
|
|
||||||
"background_color": f"var(--{color_scheme}-4)",
|
|
||||||
},
|
|
||||||
"& > .AccordionChevron": {
|
|
||||||
"color": f"var(--{color_scheme}-11)",
|
|
||||||
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
},
|
|
||||||
"&[data-state='open'] > .AccordionChevron": {
|
|
||||||
"transform": "rotate(180deg)",
|
|
||||||
},
|
|
||||||
"font_family": "inherit",
|
|
||||||
"width": "100%",
|
|
||||||
"padding": "0 20px",
|
|
||||||
"height": "45px",
|
|
||||||
"flex": 1,
|
|
||||||
"display": "flex",
|
|
||||||
"align_items": "center",
|
|
||||||
"justify_content": "space-between",
|
|
||||||
"font_size": "15px",
|
|
||||||
"line_height": 1,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"outline",
|
|
||||||
"surface",
|
|
||||||
"ghost",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"color": f"var(--{color_scheme}-11)",
|
|
||||||
"&:hover": {
|
|
||||||
"background_color": f"var(--{color_scheme}-4)",
|
|
||||||
},
|
|
||||||
"& > .AccordionChevron": {
|
|
||||||
"color": f"var(--{color_scheme}-11)",
|
|
||||||
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
},
|
|
||||||
"&[data-state='open'] > .AccordionChevron": {
|
|
||||||
"transform": "rotate(180deg)",
|
|
||||||
},
|
|
||||||
"font_family": "inherit",
|
|
||||||
"width": "100%",
|
|
||||||
"padding": "0 20px",
|
|
||||||
"height": "45px",
|
|
||||||
"flex": 1,
|
|
||||||
"display": "flex",
|
|
||||||
"align_items": "center",
|
|
||||||
"justify_content": "space-between",
|
|
||||||
"font_size": "15px",
|
|
||||||
"line_height": 1,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
# defaults to classic
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"color": f"var(--{color_scheme}-9-contrast)",
|
|
||||||
"box_shadow": f"var(--{color_scheme}-11)",
|
|
||||||
"&:hover": {
|
|
||||||
"background_color": f"var(--{color_scheme}-10)",
|
|
||||||
},
|
|
||||||
"& > .AccordionChevron": {
|
|
||||||
"color": f"var(--{color_scheme}-9-contrast)",
|
|
||||||
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
},
|
|
||||||
"&[data-state='open'] > .AccordionChevron": {
|
|
||||||
"transform": "rotate(180deg)",
|
|
||||||
},
|
|
||||||
"font_family": "inherit",
|
|
||||||
"width": "100%",
|
|
||||||
"padding": "0 20px",
|
|
||||||
"height": "45px",
|
|
||||||
"flex": 1,
|
|
||||||
"display": "flex",
|
|
||||||
"align_items": "center",
|
|
||||||
"justify_content": "space-between",
|
|
||||||
"font_size": "15px",
|
|
||||||
"line_height": 1,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_theme_accordion_content(variant: str | Var, color_scheme: str | Var) -> BaseVar:
|
|
||||||
"""Get the theme for the accordion content component.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
variant: The variant of the accordion.
|
|
||||||
color_scheme: The color of the accordion.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The theme for the accordion content component.
|
|
||||||
"""
|
|
||||||
return Match.create( # type: ignore
|
|
||||||
variant,
|
|
||||||
(
|
|
||||||
"outline",
|
|
||||||
"ghost",
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"overflow": "hidden",
|
|
||||||
"font_size": "10px",
|
|
||||||
"color": f"var(--{color_scheme}-11)",
|
|
||||||
"padding": "15px 20px",
|
|
||||||
"&[data-state='open']": {
|
|
||||||
"animation": Var.create(
|
|
||||||
f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
_var_is_string=True,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"&[data-state='closed']": {
|
|
||||||
"animation": Var.create(
|
|
||||||
f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
_var_is_string=True,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"overflow": "hidden",
|
|
||||||
"font_size": "10px",
|
|
||||||
"color": Match.create(
|
|
||||||
variant,
|
|
||||||
("classic", f"var(--{color_scheme}-9-contrast)"),
|
|
||||||
f"var(--{color_scheme}-11)",
|
|
||||||
),
|
|
||||||
"background_color": Match.create(
|
|
||||||
variant,
|
|
||||||
("classic", f"var(--{color_scheme}-9)"),
|
|
||||||
f"var(--{color_scheme}-3)",
|
|
||||||
),
|
|
||||||
"padding": "15px 20px",
|
|
||||||
"&[data-state='open']": {
|
|
||||||
"animation": Var.create(
|
|
||||||
f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
_var_is_string=True,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"&[data-state='closed']": {
|
|
||||||
"animation": Var.create(
|
|
||||||
f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms cubic-bezier(0.87, 0, 0.13, 1)",
|
|
||||||
_var_is_string=True,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AccordionComponent(RadixPrimitiveComponent):
|
class AccordionComponent(RadixPrimitiveComponent):
|
||||||
"""Base class for all @radix-ui/accordion components."""
|
"""Base class for all @radix-ui/accordion components."""
|
||||||
|
|
||||||
library = "@radix-ui/react-accordion@^1.1.2"
|
library = "@radix-ui/react-accordion@^1.1.2"
|
||||||
|
|
||||||
|
# The color scheme of the component.
|
||||||
|
color_scheme: Var[LiteralAccentColor]
|
||||||
|
|
||||||
|
# The variant of the component.
|
||||||
|
variant: Var[LiteralAccordionVariant] = Var.create_safe("classic")
|
||||||
|
|
||||||
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component."""
|
||||||
|
if self.color_scheme is not None:
|
||||||
|
self.custom_attrs["data-accent-color"] = self.color_scheme
|
||||||
|
|
||||||
|
self.custom_attrs["data-variant"] = self.variant
|
||||||
|
|
||||||
|
def _exclude_props(self) -> list[str]:
|
||||||
|
return ["color_scheme", "variant"]
|
||||||
|
|
||||||
|
|
||||||
class AccordionRoot(AccordionComponent):
|
class AccordionRoot(AccordionComponent):
|
||||||
"""An accordion component."""
|
"""An accordion component."""
|
||||||
@ -332,16 +72,7 @@ class AccordionRoot(AccordionComponent):
|
|||||||
orientation: Var[LiteralAccordionOrientation]
|
orientation: Var[LiteralAccordionOrientation]
|
||||||
|
|
||||||
# The variant of the accordion.
|
# The variant of the accordion.
|
||||||
variant: Var[LiteralAccordionRootVariant] = "classic" # type: ignore
|
variant: Var[LiteralAccordionVariant] = Var.create_safe("classic")
|
||||||
|
|
||||||
# The color scheme of the accordion.
|
|
||||||
color_scheme: Var[LiteralAccentColor] # type: ignore
|
|
||||||
|
|
||||||
# dynamic themes of the accordion generated at compile time.
|
|
||||||
_dynamic_themes: Var[dict] = Var.create({}) # type: ignore
|
|
||||||
|
|
||||||
# The var_data associated with the component.
|
|
||||||
_var_data: VarData = VarData() # type: ignore
|
|
||||||
|
|
||||||
_valid_children: List[str] = ["AccordionItem"]
|
_valid_children: List[str] = ["AccordionItem"]
|
||||||
|
|
||||||
@ -356,81 +87,12 @@ class AccordionRoot(AccordionComponent):
|
|||||||
Returns:
|
Returns:
|
||||||
The Accordion root Component.
|
The Accordion root Component.
|
||||||
"""
|
"""
|
||||||
comp = super().create(*children, **props)
|
for child in children:
|
||||||
|
if isinstance(child, AccordionItem):
|
||||||
|
child.color_scheme = props.get("color_scheme") # type: ignore
|
||||||
|
child.variant = props.get("variant") # type: ignore
|
||||||
|
|
||||||
if comp.color_scheme is not None and not comp.color_scheme._var_state: # type: ignore
|
return super().create(*children, **props)
|
||||||
# mark the vars of color string literals as strings so they can be formatted properly when performing a var operation.
|
|
||||||
comp.color_scheme._var_is_string = True # type: ignore
|
|
||||||
|
|
||||||
if comp.variant is not None and not comp.variant._var_state: # type: ignore
|
|
||||||
# mark the vars of variant string literals as strings so they are formatted properly in the match condition.
|
|
||||||
comp.variant._var_is_string = True # type: ignore
|
|
||||||
|
|
||||||
return comp
|
|
||||||
|
|
||||||
def _get_style(self) -> dict:
|
|
||||||
"""Get the style for the component.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The dictionary of the component style as value and the style notation as key.
|
|
||||||
"""
|
|
||||||
return {"css": self._dynamic_themes._merge(format_as_emotion(self.style))} # type: ignore
|
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
global_color_scheme = getattr(theme, "accent_color", None)
|
|
||||||
|
|
||||||
if global_color_scheme is None and self.color_scheme is None:
|
|
||||||
raise ValueError(
|
|
||||||
"`color_scheme` cannot be None. Either set the `color_scheme` prop on the accordion "
|
|
||||||
"component or set the `accent_color` prop in your global theme."
|
|
||||||
)
|
|
||||||
|
|
||||||
# prepare the color_scheme var to be used in an f-string(strip off the wrapping curly brace)
|
|
||||||
color_scheme = Var.create(
|
|
||||||
self.color_scheme if self.color_scheme is not None else global_color_scheme
|
|
||||||
)._replace( # type: ignore
|
|
||||||
_var_is_string=False
|
|
||||||
)
|
|
||||||
|
|
||||||
accordion_theme_root = get_theme_accordion_root(
|
|
||||||
variant=self.variant, color_scheme=color_scheme
|
|
||||||
)
|
|
||||||
accordion_theme_content = get_theme_accordion_content(
|
|
||||||
variant=self.variant, color_scheme=color_scheme
|
|
||||||
)
|
|
||||||
accordion_theme_trigger = get_theme_accordion_trigger(
|
|
||||||
variant=self.variant, color_scheme=color_scheme
|
|
||||||
)
|
|
||||||
|
|
||||||
# extract var_data from dynamic themes.
|
|
||||||
self._var_data = (
|
|
||||||
self._var_data.merge( # type: ignore
|
|
||||||
accordion_theme_trigger._var_data,
|
|
||||||
accordion_theme_content._var_data,
|
|
||||||
accordion_theme_root._var_data,
|
|
||||||
)
|
|
||||||
or self._var_data
|
|
||||||
)
|
|
||||||
|
|
||||||
self._dynamic_themes = Var.create( # type: ignore
|
|
||||||
convert_dict_to_style_and_format_emotion(
|
|
||||||
{
|
|
||||||
"& .AccordionItem": get_theme_accordion_item(),
|
|
||||||
"& .AccordionHeader": get_theme_accordion_header(),
|
|
||||||
"& .AccordionTrigger": accordion_theme_trigger,
|
|
||||||
"& .AccordionContent": accordion_theme_content,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)._merge( # type: ignore
|
|
||||||
accordion_theme_root
|
|
||||||
)
|
|
||||||
|
|
||||||
def _get_imports(self):
|
|
||||||
return imports.merge_imports(
|
|
||||||
super()._get_imports(),
|
|
||||||
self._var_data.imports if self._var_data else {},
|
|
||||||
{"@emotion/react": [imports.ImportVar(tag="keyframes")]},
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_event_triggers(self) -> Dict[str, Any]:
|
def get_event_triggers(self) -> Dict[str, Any]:
|
||||||
"""Get the events triggers signatures for the component.
|
"""Get the events triggers signatures for the component.
|
||||||
@ -443,28 +105,36 @@ class AccordionRoot(AccordionComponent):
|
|||||||
"on_value_change": lambda e0: [e0],
|
"on_value_change": lambda e0: [e0],
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_custom_code(self) -> str:
|
def add_style(self):
|
||||||
return """
|
"""Add style to the component.
|
||||||
const slideDown = keyframes`
|
|
||||||
from {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
height: var(--radix-accordion-content-height);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const slideUp = keyframes`
|
|
||||||
from {
|
|
||||||
height: var(--radix-accordion-content-height);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _exclude_props(self) -> list[str]:
|
Returns:
|
||||||
return ["color_scheme", "variant"]
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"border_radius": "6px",
|
||||||
|
"box_shadow": f"0 2px 10px {color('black', 1, alpha=True)}",
|
||||||
|
"&[data-variant='classic']": {
|
||||||
|
"background_color": color("accent", 9),
|
||||||
|
"box_shadow": f"0 2px 10px {color('black', 4, alpha=True)}",
|
||||||
|
},
|
||||||
|
"&[data-variant='soft']": {
|
||||||
|
"background_color": color("accent", 3),
|
||||||
|
},
|
||||||
|
"&[data-variant='outline']": {
|
||||||
|
"border": f"1px solid {color('accent', 6)}",
|
||||||
|
},
|
||||||
|
"&[data-variant='surface']": {
|
||||||
|
"border": f"1px solid {color('accent', 6)}",
|
||||||
|
"background_color": color("accent", 3),
|
||||||
|
},
|
||||||
|
"&[data-variant='ghost']": {
|
||||||
|
"background_color": "none",
|
||||||
|
"box_shadow": "None",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccordionItem(AccordionComponent):
|
class AccordionItem(AccordionComponent):
|
||||||
@ -488,13 +158,6 @@ class AccordionItem(AccordionComponent):
|
|||||||
|
|
||||||
_valid_parents: List[str] = ["AccordionRoot"]
|
_valid_parents: List[str] = ["AccordionRoot"]
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
self.style = Style(
|
|
||||||
{
|
|
||||||
**self.style,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
cls,
|
cls,
|
||||||
@ -506,9 +169,9 @@ class AccordionItem(AccordionComponent):
|
|||||||
"""Create an accordion item.
|
"""Create an accordion item.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
*children: The list of children to use if header and content are not provided.
|
||||||
header: The header of the accordion item.
|
header: The header of the accordion item.
|
||||||
content: The content of the accordion item.
|
content: The content of the accordion item.
|
||||||
*children: The list of children to use if header and content are not provided.
|
|
||||||
**props: Additional properties to apply to the accordion item.
|
**props: Additional properties to apply to the accordion item.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -527,14 +190,55 @@ class AccordionItem(AccordionComponent):
|
|||||||
AccordionHeader.create(
|
AccordionHeader.create(
|
||||||
AccordionTrigger.create(
|
AccordionTrigger.create(
|
||||||
header,
|
header,
|
||||||
AccordionIcon.create(),
|
AccordionIcon.create(
|
||||||
|
color_scheme=props.get("color_scheme"),
|
||||||
|
variant=props.get("variant"),
|
||||||
|
),
|
||||||
|
color_scheme=props.get("color_scheme"),
|
||||||
|
variant=props.get("variant"),
|
||||||
),
|
),
|
||||||
|
color_scheme=props.get("color_scheme"),
|
||||||
|
variant=props.get("variant"),
|
||||||
|
),
|
||||||
|
AccordionContent.create(
|
||||||
|
content, color_scheme=props.get("color_scheme")
|
||||||
),
|
),
|
||||||
AccordionContent.create(content),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return super().create(*children, value=value, **props, class_name=cls_name)
|
return super().create(*children, value=value, **props, class_name=cls_name)
|
||||||
|
|
||||||
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
for child in self.children:
|
||||||
|
if isinstance(child, (AccordionHeader, AccordionContent)):
|
||||||
|
child.color_scheme = self.color_scheme
|
||||||
|
child.variant = self.variant
|
||||||
|
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"overflow": "hidden",
|
||||||
|
"width": "100%",
|
||||||
|
"margin_top": "1px",
|
||||||
|
"&:first-child": {
|
||||||
|
"margin_top": 0,
|
||||||
|
"border_top_left_radius": "4px",
|
||||||
|
"border_top_right_radius": "4px",
|
||||||
|
},
|
||||||
|
"&:last-child": {
|
||||||
|
"border_bottom_left_radius": "4px",
|
||||||
|
"border_bottom_right_radius": "4px",
|
||||||
|
},
|
||||||
|
"&:focus-within": {
|
||||||
|
"position": "relative",
|
||||||
|
"z_index": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccordionHeader(AccordionComponent):
|
class AccordionHeader(AccordionComponent):
|
||||||
"""An accordion component."""
|
"""An accordion component."""
|
||||||
@ -561,8 +265,21 @@ class AccordionHeader(AccordionComponent):
|
|||||||
|
|
||||||
return super().create(*children, class_name=cls_name, **props)
|
return super().create(*children, class_name=cls_name, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style({**self.style})
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
for child in self.children:
|
||||||
|
if isinstance(child, AccordionTrigger):
|
||||||
|
child.color_scheme = self.color_scheme
|
||||||
|
child.variant = self.variant
|
||||||
|
|
||||||
|
return Style({"display": "flex"})
|
||||||
|
|
||||||
|
|
||||||
|
cubic_bezier = "cubic-bezier(0.87, 0, 0.13, 1)"
|
||||||
|
|
||||||
|
|
||||||
class AccordionTrigger(AccordionComponent):
|
class AccordionTrigger(AccordionComponent):
|
||||||
@ -590,8 +307,52 @@ class AccordionTrigger(AccordionComponent):
|
|||||||
|
|
||||||
return super().create(*children, class_name=cls_name, **props)
|
return super().create(*children, class_name=cls_name, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style({**self.style})
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
for child in self.children:
|
||||||
|
if isinstance(child, AccordionIcon):
|
||||||
|
child.color_scheme = self.color_scheme
|
||||||
|
child.variant = self.variant
|
||||||
|
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"color": color("accent", 11),
|
||||||
|
"line_height": 1,
|
||||||
|
"font_size": "15px",
|
||||||
|
"justify_content": "space-between",
|
||||||
|
"align_items": "center",
|
||||||
|
"flex": 1,
|
||||||
|
"display": "flex",
|
||||||
|
"padding": "0 20px",
|
||||||
|
"height": "45px",
|
||||||
|
"font_family": "inherit",
|
||||||
|
"width": "100%",
|
||||||
|
"&[data-state='open'] > .AccordionChevron": {
|
||||||
|
"transform": "rotate(180deg)",
|
||||||
|
},
|
||||||
|
"&:hover": {
|
||||||
|
"background_color": color("accent", 4),
|
||||||
|
},
|
||||||
|
"& > .AccordionChevron": {
|
||||||
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
|
||||||
|
},
|
||||||
|
"&[data-variant='classic']": {
|
||||||
|
"color": color("accent", 12),
|
||||||
|
"box_shadow": color("accent", 11),
|
||||||
|
"&:hover": {
|
||||||
|
"background_color": color("accent", 10),
|
||||||
|
},
|
||||||
|
"& > .AccordionChevron": {
|
||||||
|
"color": color("accent", 12),
|
||||||
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccordionIcon(Icon):
|
class AccordionIcon(Icon):
|
||||||
@ -623,6 +384,14 @@ class AccordionContent(AccordionComponent):
|
|||||||
|
|
||||||
alias = "RadixAccordionContent"
|
alias = "RadixAccordionContent"
|
||||||
|
|
||||||
|
def add_imports(self) -> imports.ImportDict:
|
||||||
|
"""Add imports to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The imports of the component.
|
||||||
|
"""
|
||||||
|
return {"@emotion/react": [imports.ImportVar(tag="keyframes")]}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, *children, **props) -> Component:
|
def create(cls, *children, **props) -> Component:
|
||||||
"""Create the Accordion content component.
|
"""Create the Accordion content component.
|
||||||
@ -641,14 +410,66 @@ class AccordionContent(AccordionComponent):
|
|||||||
|
|
||||||
return super().create(*children, class_name=cls_name, **props)
|
return super().create(*children, class_name=cls_name, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_custom_code(self) -> list[str]:
|
||||||
self.style = Style({**self.style})
|
"""Add custom code to the component.
|
||||||
|
|
||||||
# def _get_imports(self):
|
Returns:
|
||||||
# return {
|
The custom code of the component.
|
||||||
# **super()._get_imports(),
|
"""
|
||||||
# "@emotion/react": [imports.ImportVar(tag="keyframes")],
|
return [
|
||||||
# }
|
"""
|
||||||
|
const slideDown = keyframes`
|
||||||
|
from {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
height: var(--radix-accordion-content-height);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
const slideUp = keyframes`
|
||||||
|
from {
|
||||||
|
height: var(--radix-accordion-content-height);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
|
||||||
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
slideDown = Var.create(
|
||||||
|
f"${{slideDown}} {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
|
||||||
|
_var_is_string=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
slideUp = Var.create(
|
||||||
|
f"${{slideUp}} {DEFAULT_ANIMATION_DURATION}ms {cubic_bezier}",
|
||||||
|
_var_is_string=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"overflow": "hidden",
|
||||||
|
"font_size": "10px",
|
||||||
|
"color": color("accent", 11),
|
||||||
|
"background_color": color("accent", 3),
|
||||||
|
"padding": "0 15px",
|
||||||
|
"&[data-state='open']": {"animation": slideDown},
|
||||||
|
"&[data-state='closed']": {"animation": slideUp},
|
||||||
|
"&[data-variant='classic']": {
|
||||||
|
"color": color("accent", 12),
|
||||||
|
"background_color": color("accent", 9),
|
||||||
|
},
|
||||||
|
"&[data-variant='outline']": {"background_color": "transparent"},
|
||||||
|
"&[data-variant='ghost']": {"background_color": "transparent"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Accordion(ComponentNamespace):
|
class Accordion(ComponentNamespace):
|
||||||
|
@ -9,41 +9,95 @@ from reflex.event import EventChain, EventHandler, EventSpec
|
|||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from typing import Any, Dict, List, Literal, Optional, Union
|
from typing import Any, Dict, List, Literal, Optional, Union
|
||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import Component, ComponentNamespace
|
||||||
from reflex.components.core.match import Match
|
from reflex.components.core.colors import color
|
||||||
from reflex.components.lucide.icon import Icon
|
from reflex.components.lucide.icon import Icon
|
||||||
from reflex.components.radix.primitives.base import RadixPrimitiveComponent
|
from reflex.components.radix.primitives.base import RadixPrimitiveComponent
|
||||||
from reflex.components.radix.themes.base import LiteralAccentColor
|
from reflex.components.radix.themes.base import LiteralAccentColor
|
||||||
from reflex.style import (
|
from reflex.style import Style
|
||||||
Style,
|
|
||||||
convert_dict_to_style_and_format_emotion,
|
|
||||||
format_as_emotion,
|
|
||||||
)
|
|
||||||
from reflex.utils import imports
|
from reflex.utils import imports
|
||||||
from reflex.vars import BaseVar, Var, VarData, get_uuid_string_var
|
from reflex.vars import Var, get_uuid_string_var
|
||||||
|
|
||||||
LiteralAccordionType = Literal["single", "multiple"]
|
LiteralAccordionType = Literal["single", "multiple"]
|
||||||
LiteralAccordionDir = Literal["ltr", "rtl"]
|
LiteralAccordionDir = Literal["ltr", "rtl"]
|
||||||
LiteralAccordionOrientation = Literal["vertical", "horizontal"]
|
LiteralAccordionOrientation = Literal["vertical", "horizontal"]
|
||||||
LiteralAccordionRootVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
|
LiteralAccordionVariant = Literal["classic", "soft", "surface", "outline", "ghost"]
|
||||||
LiteralAccordionRootColorScheme = Literal["primary", "accent"]
|
|
||||||
DEFAULT_ANIMATION_DURATION = 250
|
DEFAULT_ANIMATION_DURATION = 250
|
||||||
|
|
||||||
def get_theme_accordion_root(variant: Var[str], color_scheme: Var[str]) -> BaseVar: ...
|
|
||||||
def get_theme_accordion_item(): ...
|
|
||||||
def get_theme_accordion_header() -> dict[str, str]: ...
|
|
||||||
def get_theme_accordion_trigger(
|
|
||||||
variant: str | Var, color_scheme: str | Var
|
|
||||||
) -> BaseVar: ...
|
|
||||||
def get_theme_accordion_content(
|
|
||||||
variant: str | Var, color_scheme: str | Var
|
|
||||||
) -> BaseVar: ...
|
|
||||||
|
|
||||||
class AccordionComponent(RadixPrimitiveComponent):
|
class AccordionComponent(RadixPrimitiveComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
|
color_scheme: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -102,6 +156,8 @@ class AccordionComponent(RadixPrimitiveComponent):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
color_scheme: The color scheme of the component.
|
||||||
|
variant: The variant of the component.
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -208,8 +264,6 @@ class AccordionRoot(AccordionComponent):
|
|||||||
],
|
],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
_dynamic_themes: Optional[Union[Var[dict], dict]] = None,
|
|
||||||
_var_data: Optional[VarData] = None,
|
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -278,10 +332,8 @@ class AccordionRoot(AccordionComponent):
|
|||||||
disabled: Whether or not the accordion is disabled.
|
disabled: Whether or not the accordion is disabled.
|
||||||
dir: The reading direction of the accordion when applicable.
|
dir: The reading direction of the accordion when applicable.
|
||||||
orientation: The orientation of the accordion.
|
orientation: The orientation of the accordion.
|
||||||
variant: The variant of the accordion.
|
variant: The variant of the component.
|
||||||
color_scheme: The color scheme of the accordion.
|
color_scheme: The color scheme of the component.
|
||||||
_dynamic_themes: dynamic themes of the accordion generated at compile time.
|
|
||||||
_var_data: The var_data associated with the component.
|
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -296,6 +348,7 @@ class AccordionRoot(AccordionComponent):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||||
|
def add_style(self): ...
|
||||||
|
|
||||||
class AccordionItem(AccordionComponent):
|
class AccordionItem(AccordionComponent):
|
||||||
@overload
|
@overload
|
||||||
@ -307,6 +360,74 @@ class AccordionItem(AccordionComponent):
|
|||||||
content: Optional[Union[Component, Var]] = None,
|
content: Optional[Union[Component, Var]] = None,
|
||||||
value: Optional[Union[Var[str], str]] = None,
|
value: Optional[Union[Var[str], str]] = None,
|
||||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
color_scheme: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -364,11 +485,13 @@ class AccordionItem(AccordionComponent):
|
|||||||
"""Create an accordion item.
|
"""Create an accordion item.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
*children: The list of children to use if header and content are not provided.
|
||||||
header: The header of the accordion item.
|
header: The header of the accordion item.
|
||||||
content: The content of the accordion item.
|
content: The content of the accordion item.
|
||||||
*children: The list of children to use if header and content are not provided.
|
|
||||||
value: A unique identifier for the item.
|
value: A unique identifier for the item.
|
||||||
disabled: When true, prevents the user from interacting with the item.
|
disabled: When true, prevents the user from interacting with the item.
|
||||||
|
color_scheme: The color scheme of the component.
|
||||||
|
variant: The variant of the component.
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -382,6 +505,7 @@ class AccordionItem(AccordionComponent):
|
|||||||
The accordion item.
|
The accordion item.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
|
|
||||||
class AccordionHeader(AccordionComponent):
|
class AccordionHeader(AccordionComponent):
|
||||||
@overload
|
@overload
|
||||||
@ -389,6 +513,74 @@ class AccordionHeader(AccordionComponent):
|
|||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
|
color_scheme: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -447,6 +639,8 @@ class AccordionHeader(AccordionComponent):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
color_scheme: The color scheme of the component.
|
||||||
|
variant: The variant of the component.
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -460,6 +654,9 @@ class AccordionHeader(AccordionComponent):
|
|||||||
The Accordion header Component.
|
The Accordion header Component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
|
|
||||||
|
cubic_bezier = "cubic-bezier(0.87, 0, 0.13, 1)"
|
||||||
|
|
||||||
class AccordionTrigger(AccordionComponent):
|
class AccordionTrigger(AccordionComponent):
|
||||||
@overload
|
@overload
|
||||||
@ -467,6 +664,74 @@ class AccordionTrigger(AccordionComponent):
|
|||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
|
color_scheme: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -525,6 +790,8 @@ class AccordionTrigger(AccordionComponent):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
color_scheme: The color scheme of the component.
|
||||||
|
variant: The variant of the component.
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -538,6 +805,7 @@ class AccordionTrigger(AccordionComponent):
|
|||||||
The Accordion trigger Component.
|
The Accordion trigger Component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
|
|
||||||
class AccordionIcon(Icon):
|
class AccordionIcon(Icon):
|
||||||
@overload
|
@overload
|
||||||
@ -618,11 +886,80 @@ class AccordionIcon(Icon):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class AccordionContent(AccordionComponent):
|
class AccordionContent(AccordionComponent):
|
||||||
|
def add_imports(self) -> imports.ImportDict: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
|
color_scheme: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
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",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
@ -681,6 +1018,8 @@ class AccordionContent(AccordionComponent):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
color_scheme: The color scheme of the component.
|
||||||
|
variant: The variant of the component.
|
||||||
as_child: Change the default rendered element for the one passed as a child.
|
as_child: Change the default rendered element for the one passed as a child.
|
||||||
style: The style of the component.
|
style: The style of the component.
|
||||||
key: A unique key for the component.
|
key: A unique key for the component.
|
||||||
@ -694,6 +1033,8 @@ class AccordionContent(AccordionComponent):
|
|||||||
The Accordion content Component.
|
The Accordion content Component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_custom_code(self) -> list[str]: ...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
|
|
||||||
class Accordion(ComponentNamespace):
|
class Accordion(ComponentNamespace):
|
||||||
content = staticmethod(AccordionContent.create)
|
content = staticmethod(AccordionContent.create)
|
||||||
|
@ -4,10 +4,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any, Dict, Literal
|
from typing import Any, Dict, Literal
|
||||||
|
|
||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import ComponentNamespace
|
||||||
from reflex.components.el.elements.forms import Form as HTMLForm
|
from reflex.components.el.elements.forms import Form as HTMLForm
|
||||||
from reflex.components.radix.themes.components.text_field import TextFieldRoot
|
from reflex.components.radix.themes.components.text_field import TextFieldRoot
|
||||||
from reflex.constants.event import EventTriggers
|
from reflex.constants.event import EventTriggers
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from .base import RadixPrimitiveComponentWithClassName
|
from .base import RadixPrimitiveComponentWithClassName
|
||||||
@ -37,11 +38,13 @@ class FormRoot(FormComponent, HTMLForm):
|
|||||||
EventTriggers.ON_CLEAR_SERVER_ERRORS: lambda: [],
|
EventTriggers.ON_CLEAR_SERVER_ERRORS: lambda: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
return {
|
"""Add style to the component.
|
||||||
"width": "260px",
|
|
||||||
**self.style,
|
Returns:
|
||||||
}
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style({"width": "260px"})
|
||||||
|
|
||||||
|
|
||||||
class FormField(FormComponent):
|
class FormField(FormComponent):
|
||||||
@ -57,12 +60,13 @@ class FormField(FormComponent):
|
|||||||
# Flag to mark the form field as invalid, for server side validation.
|
# Flag to mark the form field as invalid, for server side validation.
|
||||||
server_invalid: Var[bool]
|
server_invalid: Var[bool]
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
return {
|
"""Add style to the component.
|
||||||
"display": "grid",
|
|
||||||
"margin_bottom": "10px",
|
Returns:
|
||||||
**self.style,
|
The style of the component.
|
||||||
}
|
"""
|
||||||
|
return Style({"display": "grid", "margin_bottom": "10px"})
|
||||||
|
|
||||||
|
|
||||||
class FormLabel(FormComponent):
|
class FormLabel(FormComponent):
|
||||||
@ -72,13 +76,13 @@ class FormLabel(FormComponent):
|
|||||||
|
|
||||||
alias = "RadixFormLabel"
|
alias = "RadixFormLabel"
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
return {
|
"""Add style to the component.
|
||||||
"font_size": "15px",
|
|
||||||
"font_weight": "500",
|
Returns:
|
||||||
"line_height": "35px",
|
The style of the component.
|
||||||
**self.style,
|
"""
|
||||||
}
|
return Style({"font_size": "15px", "font_weight": "500", "line_height": "35px"})
|
||||||
|
|
||||||
|
|
||||||
class FormControl(FormComponent):
|
class FormControl(FormComponent):
|
||||||
@ -145,13 +149,13 @@ class FormMessage(FormComponent):
|
|||||||
# Forces the message to be shown. This is useful when using server-side validation.
|
# Forces the message to be shown. This is useful when using server-side validation.
|
||||||
force_match: Var[bool]
|
force_match: Var[bool]
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
return {
|
"""Add style to the component.
|
||||||
"font_size": "13px",
|
|
||||||
"opacity": "0.8",
|
Returns:
|
||||||
"color": "white",
|
The style of the component.
|
||||||
**self.style,
|
"""
|
||||||
}
|
return Style({"font_size": "13px", "opacity": "0.8", "color": "white"})
|
||||||
|
|
||||||
|
|
||||||
class FormValidityState(FormComponent):
|
class FormValidityState(FormComponent):
|
||||||
|
@ -8,10 +8,11 @@ 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 Any, Dict, Literal
|
from typing import Any, Dict, Literal
|
||||||
from reflex.components.component import Component, ComponentNamespace
|
from reflex.components.component import ComponentNamespace
|
||||||
from reflex.components.el.elements.forms import Form as HTMLForm
|
from reflex.components.el.elements.forms import Form as HTMLForm
|
||||||
from reflex.components.radix.themes.components.text_field import TextFieldRoot
|
from reflex.components.radix.themes.components.text_field import TextFieldRoot
|
||||||
from reflex.constants.event import EventTriggers
|
from reflex.constants.event import EventTriggers
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
from .base import RadixPrimitiveComponentWithClassName
|
from .base import RadixPrimitiveComponentWithClassName
|
||||||
|
|
||||||
@ -95,6 +96,7 @@ class FormComponent(RadixPrimitiveComponentWithClassName):
|
|||||||
|
|
||||||
class FormRoot(FormComponent, HTMLForm):
|
class FormRoot(FormComponent, HTMLForm):
|
||||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -273,6 +275,7 @@ class FormRoot(FormComponent, HTMLForm):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class FormField(FormComponent):
|
class FormField(FormComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -355,6 +358,7 @@ class FormField(FormComponent):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class FormLabel(FormComponent):
|
class FormLabel(FormComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -528,6 +532,7 @@ LiteralMatcher = Literal[
|
|||||||
]
|
]
|
||||||
|
|
||||||
class FormMessage(FormComponent):
|
class FormMessage(FormComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
|
@ -28,20 +28,24 @@ class ProgressRoot(ProgressComponent):
|
|||||||
# Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
|
# Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
|
||||||
radius: Var[LiteralRadius]
|
radius: Var[LiteralRadius]
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
if self.radius is not None:
|
if self.radius is not None:
|
||||||
self.custom_attrs["data-radius"] = self.radius
|
self.custom_attrs["data-radius"] = self.radius
|
||||||
|
|
||||||
self.style = Style(
|
return Style(
|
||||||
{
|
{
|
||||||
"position": "relative",
|
"position": "relative",
|
||||||
"overflow": "hidden",
|
"overflow": "hidden",
|
||||||
"background": "var(--gray-a3)",
|
"background": color("gray", 3, alpha=True),
|
||||||
"border_radius": "max(var(--radius-2), var(--radius-full))",
|
"border_radius": "max(var(--radius-2), var(--radius-full))",
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "20px",
|
"height": "20px",
|
||||||
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
"boxShadow": f"inset 0 0 0 1px {color('gray', 5, alpha=True)}",
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,22 +69,26 @@ class ProgressIndicator(ProgressComponent):
|
|||||||
# The color scheme of the progress indicator.
|
# The color scheme of the progress indicator.
|
||||||
color_scheme: Var[LiteralAccentColor]
|
color_scheme: Var[LiteralAccentColor]
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
if self.color_scheme is not None:
|
if self.color_scheme is not None:
|
||||||
self.custom_attrs["data-accent-color"] = self.color_scheme
|
self.custom_attrs["data-accent-color"] = self.color_scheme
|
||||||
|
|
||||||
self.style = Style(
|
return Style(
|
||||||
{
|
{
|
||||||
"background_color": color("accent", 9),
|
"background_color": color("accent", 9),
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
f"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
||||||
"&[data_state='loading']": {
|
"&[data_state='loading']": {
|
||||||
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
||||||
},
|
},
|
||||||
"transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
|
"transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
|
||||||
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ class ProgressComponent(RadixPrimitiveComponentWithClassName):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class ProgressRoot(ProgressComponent):
|
class ProgressRoot(ProgressComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -180,6 +181,7 @@ class ProgressRoot(ProgressComponent):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class ProgressIndicator(ProgressComponent):
|
class ProgressIndicator(ProgressComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
|
@ -59,8 +59,13 @@ class SliderRoot(SliderComponent):
|
|||||||
"on_value_commit": lambda e0: [e0], # trigger when thumb is released
|
"on_value_commit": lambda e0: [e0], # trigger when thumb is released
|
||||||
}
|
}
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"position": "relative",
|
"position": "relative",
|
||||||
"display": "flex",
|
"display": "flex",
|
||||||
@ -74,7 +79,6 @@ class SliderRoot(SliderComponent):
|
|||||||
"width": "20px",
|
"width": "20px",
|
||||||
"height": "100px",
|
"height": "100px",
|
||||||
},
|
},
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -85,18 +89,20 @@ class SliderTrack(SliderComponent):
|
|||||||
tag = "Track"
|
tag = "Track"
|
||||||
alias = "RadixSliderTrack"
|
alias = "RadixSliderTrack"
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"position": "relative",
|
"position": "relative",
|
||||||
"flex_grow": "1",
|
"flex_grow": "1",
|
||||||
"background_color": "black",
|
"background_color": "black",
|
||||||
"border_radius": "9999px",
|
"border_radius": "9999px",
|
||||||
"height": "3px",
|
"height": "3px",
|
||||||
"&[data-orientation='vertical']": {
|
"&[data-orientation='vertical']": {"width": "3px"},
|
||||||
"width": "3px",
|
|
||||||
},
|
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -107,16 +113,18 @@ class SliderRange(SliderComponent):
|
|||||||
tag = "Range"
|
tag = "Range"
|
||||||
alias = "RadixSliderRange"
|
alias = "RadixSliderRange"
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"background_color": "white",
|
"background_color": "white",
|
||||||
"height": "100%",
|
"height": "100%",
|
||||||
"&[data-orientation='vertical']": {
|
"&[data-orientation='vertical']": {"width": "100%"},
|
||||||
"width": "100%",
|
|
||||||
},
|
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -127,8 +135,13 @@ class SliderThumb(SliderComponent):
|
|||||||
tag = "Thumb"
|
tag = "Thumb"
|
||||||
alias = "RadixSliderThumb"
|
alias = "RadixSliderThumb"
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"display": "block",
|
"display": "block",
|
||||||
"width": "20px",
|
"width": "20px",
|
||||||
@ -143,7 +156,6 @@ class SliderThumb(SliderComponent):
|
|||||||
"outline": "none",
|
"outline": "none",
|
||||||
"box_shadow": "0 0 0 4px gray",
|
"box_shadow": "0 0 0 4px gray",
|
||||||
},
|
},
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ class SliderComponent(RadixPrimitiveComponentWithClassName):
|
|||||||
|
|
||||||
class SliderRoot(SliderComponent):
|
class SliderRoot(SliderComponent):
|
||||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -196,6 +197,7 @@ class SliderRoot(SliderComponent):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class SliderTrack(SliderComponent):
|
class SliderTrack(SliderComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -274,6 +276,7 @@ class SliderTrack(SliderComponent):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class SliderRange(SliderComponent):
|
class SliderRange(SliderComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
@ -352,6 +355,7 @@ class SliderRange(SliderComponent):
|
|||||||
...
|
...
|
||||||
|
|
||||||
class SliderThumb(SliderComponent):
|
class SliderThumb(SliderComponent):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Interactive components provided by @radix-ui/themes."""
|
"""Interactive components provided by @radix-ui/themes."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
@ -6,6 +7,7 @@ from reflex import el
|
|||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.core.match import Match
|
from reflex.components.core.match import Match
|
||||||
from reflex.components.lucide import Icon
|
from reflex.components.lucide import Icon
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from ..base import (
|
from ..base import (
|
||||||
@ -68,25 +70,25 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
|
|||||||
"IconButton requires a child icon. Pass a string as the first child or a rx.icon."
|
"IconButton requires a child icon. Pass a string as the first child or a rx.icon."
|
||||||
)
|
)
|
||||||
if "size" in props:
|
if "size" in props:
|
||||||
|
RADIX_TO_LUCIDE_SIZE = {"1": "12px", "2": "24px", "3": "36px", "4": "48px"}
|
||||||
|
|
||||||
if isinstance(props["size"], str):
|
if isinstance(props["size"], str):
|
||||||
RADIX_TO_LUCIDE_SIZE = {
|
|
||||||
"1": "12px",
|
|
||||||
"2": "24px",
|
|
||||||
"3": "36px",
|
|
||||||
"4": "48px",
|
|
||||||
}
|
|
||||||
children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]
|
children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]
|
||||||
else:
|
else:
|
||||||
children[0].size = Match.create(
|
children[0].size = Match.create(
|
||||||
props["size"],
|
props["size"],
|
||||||
("1", "12px"),
|
*[(size, px) for size, px in RADIX_TO_LUCIDE_SIZE.items()],
|
||||||
("2", "24px"),
|
|
||||||
("3", "36px"),
|
|
||||||
("4", "48px"),
|
|
||||||
"12px",
|
"12px",
|
||||||
)
|
)
|
||||||
props.setdefault("padding", "6px")
|
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
|
def add_style(self):
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style({"padding": "6px"})
|
||||||
|
|
||||||
|
|
||||||
icon_button = IconButton.create
|
icon_button = IconButton.create
|
||||||
|
@ -12,6 +12,7 @@ from reflex import el
|
|||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.core.match import Match
|
from reflex.components.core.match import Match
|
||||||
from reflex.components.lucide import Icon
|
from reflex.components.lucide import Icon
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
from ..base import (
|
from ..base import (
|
||||||
LiteralAccentColor,
|
LiteralAccentColor,
|
||||||
@ -280,5 +281,6 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
|
|||||||
The IconButton component.
|
The IconButton component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self): ...
|
||||||
|
|
||||||
icon_button = IconButton.create
|
icon_button = IconButton.create
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.style import Style
|
||||||
|
|
||||||
from .flex import Flex
|
from .flex import Flex
|
||||||
|
|
||||||
@ -10,8 +10,13 @@ from .flex import Flex
|
|||||||
class Center(Flex):
|
class Center(Flex):
|
||||||
"""A center component."""
|
"""A center component."""
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style.update(
|
"""Add style that center the content.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"display": "flex",
|
"display": "flex",
|
||||||
"align_items": "center",
|
"align_items": "center",
|
||||||
|
@ -7,10 +7,11 @@ 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 reflex.components.component import Component
|
from reflex.style import Style
|
||||||
from .flex import Flex
|
from .flex import Flex
|
||||||
|
|
||||||
class Center(Flex):
|
class Center(Flex):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""List components."""
|
"""List components."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Iterable, Literal, Optional, Union
|
from typing import Iterable, Literal, Optional, Union
|
||||||
|
|
||||||
@ -77,12 +78,16 @@ class BaseList(Component):
|
|||||||
style["gap"] = props["gap"]
|
style["gap"] = props["gap"]
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style = Style(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"direction": "column",
|
"direction": "column",
|
||||||
"list_style_position": "inside",
|
"list_style_position": "inside",
|
||||||
**self.style,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ class BaseList(Component):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
|
|
||||||
class UnorderedList(BaseList, Ul):
|
class UnorderedList(BaseList, Ul):
|
||||||
@overload
|
@overload
|
||||||
@ -165,7 +166,7 @@ class UnorderedList(BaseList, Ul):
|
|||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
items: Optional[Union[Var[Iterable], Iterable]] = None,
|
items: Optional[Union[Var[Iterable], Iterable]] = None,
|
||||||
list_style_type: Optional[Literal["none", "disc", "circle", "square"]] = "disc",
|
list_style_type: Optional[LiteralListStyleTypeUnordered] = "disc",
|
||||||
access_key: Optional[
|
access_key: Optional[
|
||||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
] = None,
|
] = None,
|
||||||
@ -302,24 +303,7 @@ class OrderedList(BaseList, Ol):
|
|||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
items: Optional[Union[Var[Iterable], Iterable]] = None,
|
items: Optional[Union[Var[Iterable], Iterable]] = None,
|
||||||
list_style_type: Optional[
|
list_style_type: Optional[LiteralListStyleTypeOrdered] = "decimal",
|
||||||
Literal[
|
|
||||||
"none",
|
|
||||||
"decimal",
|
|
||||||
"decimal-leading-zero",
|
|
||||||
"lower-roman",
|
|
||||||
"upper-roman",
|
|
||||||
"lower-greek",
|
|
||||||
"lower-latin",
|
|
||||||
"upper-latin",
|
|
||||||
"armenian",
|
|
||||||
"georgian",
|
|
||||||
"lower-alpha",
|
|
||||||
"upper-alpha",
|
|
||||||
"hiragana",
|
|
||||||
"katakana",
|
|
||||||
]
|
|
||||||
] = "decimal",
|
|
||||||
reversed: Optional[
|
reversed: Optional[
|
||||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
] = None,
|
] = None,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.style import Style
|
||||||
|
|
||||||
from .flex import Flex
|
from .flex import Flex
|
||||||
|
|
||||||
@ -10,8 +10,13 @@ from .flex import Flex
|
|||||||
class Spacer(Flex):
|
class Spacer(Flex):
|
||||||
"""A spacer component."""
|
"""A spacer component."""
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
def add_style(self) -> Style | None:
|
||||||
self.style.update(
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
|
return Style(
|
||||||
{
|
{
|
||||||
"flex": 1,
|
"flex": 1,
|
||||||
"justify_self": "stretch",
|
"justify_self": "stretch",
|
||||||
|
@ -7,10 +7,11 @@ 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 reflex.components.component import Component
|
from reflex.style import Style
|
||||||
from .flex import Flex
|
from .flex import Flex
|
||||||
|
|
||||||
class Spacer(Flex):
|
class Spacer(Flex):
|
||||||
|
def add_style(self) -> Style | None: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
|
@ -37,6 +37,8 @@ ColorType = Literal[
|
|||||||
"bronze",
|
"bronze",
|
||||||
"gray",
|
"gray",
|
||||||
"accent",
|
"accent",
|
||||||
|
"black",
|
||||||
|
"white",
|
||||||
]
|
]
|
||||||
|
|
||||||
ShadeType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
ShadeType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""To experiment with layout component, move them to reflex/components later."""
|
"""To experiment with layout component, move them to reflex/components later."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from reflex import color, cond
|
from reflex import color, cond
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
||||||
@ -9,6 +11,7 @@ from reflex.components.radix.themes.layout import Box, Container, HStack
|
|||||||
from reflex.event import call_script
|
from reflex.event import call_script
|
||||||
from reflex.experimental import hooks
|
from reflex.experimental import hooks
|
||||||
from reflex.state import ComponentState
|
from reflex.state import ComponentState
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
|
|
||||||
@ -26,23 +29,38 @@ class Sidebar(Box, MemoizationLeaf):
|
|||||||
Returns:
|
Returns:
|
||||||
The sidebar component.
|
The sidebar component.
|
||||||
"""
|
"""
|
||||||
props.setdefault("border_right", f"1px solid {color('accent', 12)}")
|
# props.setdefault("border_right", f"1px solid {color('accent', 12)}")
|
||||||
props.setdefault("background_color", color("accent", 1))
|
# props.setdefault("background_color", color("accent", 1))
|
||||||
props.setdefault("width", "20vw")
|
# props.setdefault("width", "20vw")
|
||||||
props.setdefault("height", "100vh")
|
# props.setdefault("height", "100vh")
|
||||||
props.setdefault("position", "fixed")
|
# props.setdefault("position", "fixed")
|
||||||
|
|
||||||
return super().create(
|
return super().create(
|
||||||
Box.create(*children, **props), # sidebar for content
|
Box.create(*children, **props), # sidebar for content
|
||||||
Box.create(width=props.get("width")), # spacer for layout
|
Box.create(width=props.get("width")), # spacer for layout
|
||||||
)
|
)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component | None):
|
def add_style(self) -> Style | None:
|
||||||
|
"""Add style to the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The style of the component.
|
||||||
|
"""
|
||||||
sidebar: Component = self.children[-2] # type: ignore
|
sidebar: Component = self.children[-2] # type: ignore
|
||||||
spacer: Component = self.children[-1] # type: ignore
|
spacer: Component = self.children[-1] # type: ignore
|
||||||
open = self.State.open if self.State else Var.create("open") # type: ignore
|
open = self.State.open if self.State else Var.create("open") # type: ignore
|
||||||
sidebar.style["display"] = spacer.style["display"] = cond(open, "block", "none")
|
sidebar.style["display"] = spacer.style["display"] = cond(open, "block", "none")
|
||||||
|
|
||||||
|
return Style(
|
||||||
|
{
|
||||||
|
"position": "fixed",
|
||||||
|
"border_right": f"1px solid {color('accent', 12)}",
|
||||||
|
"background_color": color("accent", 1),
|
||||||
|
"width": "20vw",
|
||||||
|
"height": "100vh",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def _get_hooks(self) -> Var | None:
|
def _get_hooks(self) -> Var | None:
|
||||||
return hooks.useState("open", "true") if not self.State else None
|
return hooks.useState("open", "true") if not self.State else None
|
||||||
|
|
||||||
|
@ -159,12 +159,17 @@ def format_style_key(key: str) -> Tuple[str, ...]:
|
|||||||
class Style(dict):
|
class Style(dict):
|
||||||
"""A style dictionary."""
|
"""A style dictionary."""
|
||||||
|
|
||||||
def __init__(self, style_dict: dict | None = None):
|
def __init__(self, style_dict: dict | None = None, **kwargs):
|
||||||
"""Initialize the style.
|
"""Initialize the style.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
style_dict: The style dictionary.
|
style_dict: The style dictionary.
|
||||||
|
kwargs: Other key value pairs to apply to the dict update.
|
||||||
"""
|
"""
|
||||||
|
if style_dict:
|
||||||
|
style_dict.update(kwargs)
|
||||||
|
else:
|
||||||
|
style_dict = kwargs
|
||||||
style_dict, self._var_data = convert(style_dict or {})
|
style_dict, self._var_data = convert(style_dict or {})
|
||||||
super().__init__(style_dict)
|
super().__init__(style_dict)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from typing import Dict, List, Set, Tuple, Union
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from reflex.components import box, foreach, text, theme
|
from reflex.components import box, foreach, text
|
||||||
from reflex.components.core import Foreach
|
from reflex.components.core import Foreach
|
||||||
from reflex.state import BaseState
|
from reflex.state import BaseState
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
@ -220,15 +220,6 @@ def test_foreach_render(state_var, render_fn, render_dict):
|
|||||||
seen_index_vars.add(arg_index._var_name)
|
seen_index_vars.add(arg_index._var_name)
|
||||||
|
|
||||||
|
|
||||||
def test_foreach_apply_theme():
|
|
||||||
"""Test that the foreach component applies the theme."""
|
|
||||||
tag = Foreach.create(ForEachState.colors_list, display_color) # type: ignore
|
|
||||||
_theme = theme()
|
|
||||||
tag.apply_theme(_theme)
|
|
||||||
assert tag.theme == _theme
|
|
||||||
tag.render()
|
|
||||||
|
|
||||||
|
|
||||||
def test_foreach_bad_annotations():
|
def test_foreach_bad_annotations():
|
||||||
"""Test that the foreach component raises a TypeError if the iterable is of type Any."""
|
"""Test that the foreach component raises a TypeError if the iterable is of type Any."""
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from reflex.components.lucide.icon import LUCIDE_ICON_LIST, RENAMED_ICONS_05, Icon
|
from reflex.components.lucide.icon import LUCIDE_ICON_LIST, RENAMED_ICONS_05, Icon
|
||||||
from reflex.components.radix.themes.base import Theme
|
|
||||||
from reflex.utils import format
|
from reflex.utils import format
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ RENAMED_TAGS = [tag for tag in RENAMED_ICONS_05.items()]
|
|||||||
@pytest.mark.parametrize("tag, new_tag", RENAMED_TAGS)
|
@pytest.mark.parametrize("tag, new_tag", RENAMED_TAGS)
|
||||||
def test_icon_renamed_tags(tag, new_tag):
|
def test_icon_renamed_tags(tag, new_tag):
|
||||||
Icon.create(tag)
|
Icon.create(tag)
|
||||||
# need a PR so we can pass the following test. Currently it fails and uses the old tag as the import.
|
# TODO: need a PR so we can pass the following test. Currently it fails and uses the old tag as the import.
|
||||||
# assert icon.alias == f"Lucide{format.to_title_case(new_tag)}Icon"
|
# assert icon.alias == f"Lucide{format.to_title_case(new_tag)}Icon"
|
||||||
|
|
||||||
|
|
||||||
@ -36,6 +35,6 @@ def test_icon_multiple_children():
|
|||||||
_ = Icon.create("activity", "child1", "child2")
|
_ = Icon.create("activity", "child1", "child2")
|
||||||
|
|
||||||
|
|
||||||
def test_icon_apply_theme():
|
def test_icon_add_style():
|
||||||
ic = Icon.create("activity")
|
ic = Icon.create("activity")
|
||||||
ic._apply_theme(Theme())
|
assert ic.add_style() is None
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from reflex.components.lucide.icon import Icon
|
from reflex.components.lucide.icon import Icon
|
||||||
from reflex.components.radix.themes.base import Theme
|
|
||||||
from reflex.components.radix.themes.components.icon_button import IconButton
|
from reflex.components.radix.themes.components.icon_button import IconButton
|
||||||
|
from reflex.style import Style
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
|
|
||||||
def test_icon_button():
|
def test_icon_button():
|
||||||
ib1 = IconButton.create("activity")
|
ib1 = IconButton.create("activity")
|
||||||
ib1._apply_theme(Theme.create())
|
|
||||||
assert isinstance(ib1, IconButton)
|
assert isinstance(ib1, IconButton)
|
||||||
|
|
||||||
ib2 = IconButton.create(Icon.create("activity"))
|
ib2 = IconButton.create(Icon.create("activity"))
|
||||||
assert isinstance(ib2, IconButton)
|
assert isinstance(ib2, IconButton)
|
||||||
|
|
||||||
|
assert isinstance(ib1.add_style(), Style)
|
||||||
|
assert isinstance(ib2.add_style(), Style)
|
||||||
|
|
||||||
|
|
||||||
def test_icon_button_no_child():
|
def test_icon_button_no_child():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
Loading…
Reference in New Issue
Block a user