IconButton for color_mode with nice default and a position props to control it (#3165)
This commit is contained in:
parent
3a58558166
commit
92cdc15896
@ -1,7 +1,6 @@
|
||||
"""Lucide Icon component."""
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.style import Style
|
||||
from reflex.utils import console, format
|
||||
from reflex.vars import Var
|
||||
|
||||
@ -73,16 +72,9 @@ class Icon(LucideIconComponent):
|
||||
|
||||
props["tag"] = format.to_title_case(format.to_snake_case(props["tag"])) + "Icon"
|
||||
props["alias"] = f"Lucide{props['tag']}"
|
||||
props.setdefault("color", f"var(--current-color)")
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _apply_theme(self, theme: Component):
|
||||
self.style = Style(
|
||||
{
|
||||
"color": f"var(--current-color)",
|
||||
**self.style,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
RENAMED_ICONS_05 = {
|
||||
"activity_square": "square_activity",
|
||||
|
@ -8,7 +8,6 @@ from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from reflex.components.component import Component
|
||||
from reflex.style import Style
|
||||
from reflex.utils import console, format
|
||||
from reflex.vars import Var
|
||||
|
||||
|
@ -14,18 +14,20 @@ rx.text(
|
||||
)
|
||||
```
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
from typing import Literal, get_args
|
||||
|
||||
from reflex.components.component import BaseComponent
|
||||
from reflex.components.core.cond import Cond, color_mode_cond
|
||||
from reflex.components.core.cond import Cond, color_mode_cond, cond
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.style import LIGHT_COLOR_MODE, color_mode, toggle_color_mode
|
||||
from reflex.vars import BaseVar
|
||||
from reflex.style import color_mode, toggle_color_mode
|
||||
from reflex.utils import console
|
||||
from reflex.vars import BaseVar, Var
|
||||
|
||||
from .components.button import Button
|
||||
from .components.switch import Switch
|
||||
from .components.icon_button import IconButton
|
||||
|
||||
DEFAULT_LIGHT_ICON: Icon = Icon.create(tag="sun")
|
||||
DEFAULT_DARK_ICON: Icon = Icon.create(tag="moon")
|
||||
@ -55,44 +57,87 @@ class ColorModeIcon(Cond):
|
||||
)
|
||||
|
||||
|
||||
class ColorModeSwitch(Switch):
|
||||
"""Switch for toggling light / dark mode via toggle_color_mode."""
|
||||
LiteralPosition = Literal["top-left", "top-right", "bottom-left", "bottom-right"]
|
||||
|
||||
position_values = get_args(LiteralPosition)
|
||||
|
||||
position_map = {
|
||||
"position": position_values,
|
||||
"left": ["top-left", "bottom-left"],
|
||||
"right": ["top-right", "bottom-right"],
|
||||
"top": ["top-left", "top-right"],
|
||||
"bottom": ["bottom-left", "bottom-right"],
|
||||
}
|
||||
|
||||
|
||||
# needed to inverse contains for find
|
||||
def _find(const, var):
|
||||
return Var.create_safe(const).contains(var)
|
||||
|
||||
|
||||
def _set_var_default(props, position, prop, default1, default2=""):
|
||||
props.setdefault(
|
||||
prop, cond(_find(position_map[prop], position), default1, default2)
|
||||
)
|
||||
|
||||
|
||||
def _set_static_default(props, position, prop, default):
|
||||
if prop in position:
|
||||
props.setdefault(prop, default)
|
||||
|
||||
|
||||
class ColorModeIconButton(IconButton):
|
||||
"""Icon Button for toggling light / dark mode via toggle_color_mode."""
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
"""Create a switch component bound to color_mode.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The switch component.
|
||||
"""
|
||||
return Switch.create(
|
||||
*children,
|
||||
checked=color_mode != LIGHT_COLOR_MODE,
|
||||
on_change=toggle_color_mode,
|
||||
**props,
|
||||
)
|
||||
|
||||
|
||||
class ColorModeButton(Button):
|
||||
"""Button for toggling chakra light / dark mode via toggle_color_mode."""
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
"""Create a button component that calls toggle_color_mode on click.
|
||||
def create(
|
||||
cls,
|
||||
*children,
|
||||
position: LiteralPosition | None = None,
|
||||
**props,
|
||||
):
|
||||
"""Create a icon button component that calls toggle_color_mode on click.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
position: The position of the icon button. Follow document flow if None.
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The button component.
|
||||
"""
|
||||
return Button.create(
|
||||
*children,
|
||||
if children:
|
||||
console.deprecate(
|
||||
feature_name="passing children to color_mode.button",
|
||||
reason=", use color_mode_cond and toggle_color_mode instead to build a custom color_mode component",
|
||||
deprecation_version="0.5.0",
|
||||
removal_version="0.6.0",
|
||||
)
|
||||
|
||||
# position is used to set nice defaults for positioning the icon button
|
||||
if isinstance(position, Var):
|
||||
_set_var_default(props, position, "position", "fixed", position)
|
||||
_set_var_default(props, position, "bottom", "2rem")
|
||||
_set_var_default(props, position, "top", "2rem")
|
||||
_set_var_default(props, position, "left", "2rem")
|
||||
_set_var_default(props, position, "right", "2rem")
|
||||
elif position is not None:
|
||||
if position in position_values:
|
||||
props.setdefault("position", "fixed")
|
||||
_set_static_default(props, position, "bottom", "2rem")
|
||||
_set_static_default(props, position, "top", "2rem")
|
||||
_set_static_default(props, position, "left", "2rem")
|
||||
_set_static_default(props, position, "right", "2rem")
|
||||
else:
|
||||
props["position"] = position
|
||||
|
||||
props.setdefault("background", "transparent")
|
||||
props.setdefault("color", "inherit")
|
||||
props.setdefault("z_index", "20")
|
||||
props.setdefault(":hover", {"cursor": "pointer"})
|
||||
|
||||
return super().create(
|
||||
ColorModeIcon.create(),
|
||||
on_click=toggle_color_mode,
|
||||
**props,
|
||||
)
|
||||
@ -102,8 +147,7 @@ class ColorModeNamespace(BaseVar):
|
||||
"""Namespace for color mode components."""
|
||||
|
||||
icon = staticmethod(ColorModeIcon.create)
|
||||
switch = staticmethod(ColorModeSwitch.create)
|
||||
button = staticmethod(ColorModeButton.create)
|
||||
button = staticmethod(ColorModeIconButton.create)
|
||||
|
||||
|
||||
color_mode_var_and_namespace = ColorModeNamespace(**dataclasses.asdict(color_mode))
|
||||
|
@ -8,13 +8,14 @@ from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
import dataclasses
|
||||
from typing import Literal, get_args
|
||||
from reflex.components.component import BaseComponent
|
||||
from reflex.components.core.cond import Cond, color_mode_cond
|
||||
from reflex.components.core.cond import Cond, color_mode_cond, cond
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.style import LIGHT_COLOR_MODE, color_mode, toggle_color_mode
|
||||
from reflex.vars import BaseVar
|
||||
from .components.button import Button
|
||||
from .components.switch import Switch
|
||||
from reflex.style import color_mode, toggle_color_mode
|
||||
from reflex.utils import console
|
||||
from reflex.vars import BaseVar, Var
|
||||
from .components.icon_button import IconButton
|
||||
|
||||
DEFAULT_LIGHT_ICON: Icon
|
||||
DEFAULT_DARK_ICON: Icon
|
||||
@ -92,187 +93,23 @@ class ColorModeIcon(Cond):
|
||||
"""
|
||||
...
|
||||
|
||||
class ColorModeSwitch(Switch):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||
default_checked: Optional[Union[Var[bool], bool]] = None,
|
||||
checked: Optional[Union[Var[bool], bool]] = None,
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
required: Optional[Union[Var[bool], bool]] = None,
|
||||
name: Optional[Union[Var[str], str]] = None,
|
||||
value: Optional[Union[Var[str], str]] = None,
|
||||
size: Optional[
|
||||
Union[Var[Literal["1", "2", "3"]], Literal["1", "2", "3"]]
|
||||
] = None,
|
||||
variant: Optional[
|
||||
Union[
|
||||
Var[Literal["classic", "surface", "soft"]],
|
||||
Literal["classic", "surface", "soft"],
|
||||
]
|
||||
] = 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,
|
||||
high_contrast: Optional[Union[Var[bool], bool]] = None,
|
||||
radius: Optional[
|
||||
Union[
|
||||
Var[Literal["none", "small", "full"]], Literal["none", "small", "full"]
|
||||
]
|
||||
] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
class_name: Optional[Any] = None,
|
||||
autofocus: Optional[bool] = None,
|
||||
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||
on_blur: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_change: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_context_menu: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_double_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_focus: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mount: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_down: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_enter: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_leave: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_move: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_out: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_over: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_mouse_up: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_scroll: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_unmount: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
**props
|
||||
) -> "ColorModeSwitch":
|
||||
"""Create a switch component bound to color_mode.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
|
||||
default_checked: Whether the switch is checked by default
|
||||
checked: Whether the switch is checked
|
||||
disabled: If true, prevent the user from interacting with the switch
|
||||
required: If true, the user must interact with the switch to submit the form
|
||||
name: The name of the switch (when submitting a form)
|
||||
value: The value associated with the "on" position
|
||||
size: Switch size "1" - "4"
|
||||
variant: Variant of switch: "classic" | "surface" | "soft"
|
||||
color_scheme: Override theme color for switch
|
||||
high_contrast: Whether to render the switch with higher contrast color against background
|
||||
radius: Override theme radius for switch: "none" | "small" | "full"
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
class_name: The class name for the component.
|
||||
autofocus: Whether the component should take the focus once the page is loaded
|
||||
custom_attrs: custom attribute
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The switch component.
|
||||
"""
|
||||
...
|
||||
|
||||
class ColorModeButton(Button):
|
||||
LiteralPosition = Literal["top-left", "top-right", "bottom-left", "bottom-right"]
|
||||
position_values = get_args(LiteralPosition)
|
||||
position_map = {
|
||||
"position": position_values,
|
||||
"left": ["top-left", "bottom-left"],
|
||||
"right": ["top-right", "bottom-right"],
|
||||
"top": ["top-left", "top-right"],
|
||||
"bottom": ["bottom-left", "bottom-right"],
|
||||
}
|
||||
|
||||
class ColorModeIconButton(IconButton):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
position: Optional[LiteralPosition | None] = None,
|
||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||
size: Optional[
|
||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
||||
@ -470,14 +307,15 @@ class ColorModeButton(Button):
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
**props
|
||||
) -> "ColorModeButton":
|
||||
"""Create a button component that calls toggle_color_mode on click.
|
||||
) -> "ColorModeIconButton":
|
||||
"""Create a icon button component that calls toggle_color_mode on click.
|
||||
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
position: The position of the icon button. Follow document flow if None.
|
||||
as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
|
||||
size: Button size "1" - "4"
|
||||
variant: Variant of button: "solid" | "soft" | "outline" | "ghost"
|
||||
variant: Variant of button: "classic" | "solid" | "soft" | "surface" | "outline" | "ghost"
|
||||
color_scheme: Override theme color for button
|
||||
high_contrast: Whether to render the button with higher contrast color against background
|
||||
radius: Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
||||
@ -524,7 +362,6 @@ class ColorModeButton(Button):
|
||||
|
||||
class ColorModeNamespace(BaseVar):
|
||||
icon = staticmethod(ColorModeIcon.create)
|
||||
switch = staticmethod(ColorModeSwitch.create)
|
||||
button = staticmethod(ColorModeButton.create)
|
||||
button = staticmethod(ColorModeIconButton.create)
|
||||
|
||||
color_mode_var_and_namespace = ColorModeNamespace(**dataclasses.asdict(color_mode))
|
||||
|
@ -6,7 +6,6 @@ from reflex import el
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.core.match import Match
|
||||
from reflex.components.lucide import Icon
|
||||
from reflex.style import Style
|
||||
from reflex.vars import Var
|
||||
|
||||
from ..base import (
|
||||
@ -86,10 +85,8 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
|
||||
("4", "48px"),
|
||||
"12px",
|
||||
)
|
||||
props.setdefault("padding", "6px")
|
||||
return super().create(*children, **props)
|
||||
|
||||
def _apply_theme(self, theme: Component):
|
||||
self.style = Style({"padding": "6px", **self.style})
|
||||
|
||||
|
||||
icon_button = IconButton.create
|
||||
|
@ -12,7 +12,6 @@ from reflex import el
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.core.match import Match
|
||||
from reflex.components.lucide import Icon
|
||||
from reflex.style import Style
|
||||
from reflex.vars import Var
|
||||
from ..base import (
|
||||
LiteralAccentColor,
|
||||
|
Loading…
Reference in New Issue
Block a user