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."""
|
"""Lucide Icon component."""
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.style import Style
|
|
||||||
from reflex.utils import console, format
|
from reflex.utils import console, format
|
||||||
from reflex.vars import Var
|
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["tag"] = format.to_title_case(format.to_snake_case(props["tag"])) + "Icon"
|
||||||
props["alias"] = f"Lucide{props['tag']}"
|
props["alias"] = f"Lucide{props['tag']}"
|
||||||
|
props.setdefault("color", f"var(--current-color)")
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
self.style = Style(
|
|
||||||
{
|
|
||||||
"color": f"var(--current-color)",
|
|
||||||
**self.style,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
RENAMED_ICONS_05 = {
|
RENAMED_ICONS_05 = {
|
||||||
"activity_square": "square_activity",
|
"activity_square": "square_activity",
|
||||||
|
@ -8,7 +8,6 @@ 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.components.component import Component
|
||||||
from reflex.style import Style
|
|
||||||
from reflex.utils import console, format
|
from reflex.utils import console, format
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
|
@ -14,18 +14,20 @@ rx.text(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
from typing import Literal, get_args
|
||||||
|
|
||||||
from reflex.components.component import BaseComponent
|
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.components.lucide.icon import Icon
|
||||||
from reflex.style import LIGHT_COLOR_MODE, color_mode, toggle_color_mode
|
from reflex.style import color_mode, toggle_color_mode
|
||||||
from reflex.vars import BaseVar
|
from reflex.utils import console
|
||||||
|
from reflex.vars import BaseVar, Var
|
||||||
|
|
||||||
from .components.button import Button
|
from .components.icon_button import IconButton
|
||||||
from .components.switch import Switch
|
|
||||||
|
|
||||||
DEFAULT_LIGHT_ICON: Icon = Icon.create(tag="sun")
|
DEFAULT_LIGHT_ICON: Icon = Icon.create(tag="sun")
|
||||||
DEFAULT_DARK_ICON: Icon = Icon.create(tag="moon")
|
DEFAULT_DARK_ICON: Icon = Icon.create(tag="moon")
|
||||||
@ -55,44 +57,87 @@ class ColorModeIcon(Cond):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ColorModeSwitch(Switch):
|
LiteralPosition = Literal["top-left", "top-right", "bottom-left", "bottom-right"]
|
||||||
"""Switch for toggling light / dark mode via toggle_color_mode."""
|
|
||||||
|
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
|
@classmethod
|
||||||
def create(cls, *children, **props):
|
def create(
|
||||||
"""Create a switch component bound to color_mode.
|
cls,
|
||||||
|
*children,
|
||||||
Args:
|
position: LiteralPosition | None = None,
|
||||||
*children: The children of the component.
|
**props,
|
||||||
**props: The props to pass to the component.
|
):
|
||||||
|
"""Create a icon button component that calls toggle_color_mode on click.
|
||||||
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.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*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.
|
**props: The props to pass to the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The button component.
|
The button component.
|
||||||
"""
|
"""
|
||||||
return Button.create(
|
if children:
|
||||||
*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,
|
on_click=toggle_color_mode,
|
||||||
**props,
|
**props,
|
||||||
)
|
)
|
||||||
@ -102,8 +147,7 @@ class ColorModeNamespace(BaseVar):
|
|||||||
"""Namespace for color mode components."""
|
"""Namespace for color mode components."""
|
||||||
|
|
||||||
icon = staticmethod(ColorModeIcon.create)
|
icon = staticmethod(ColorModeIcon.create)
|
||||||
switch = staticmethod(ColorModeSwitch.create)
|
button = staticmethod(ColorModeIconButton.create)
|
||||||
button = staticmethod(ColorModeButton.create)
|
|
||||||
|
|
||||||
|
|
||||||
color_mode_var_and_namespace = ColorModeNamespace(**dataclasses.asdict(color_mode))
|
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.event import EventChain, EventHandler, EventSpec
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
from typing import Literal, get_args
|
||||||
from reflex.components.component import BaseComponent
|
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.components.lucide.icon import Icon
|
||||||
from reflex.style import LIGHT_COLOR_MODE, color_mode, toggle_color_mode
|
from reflex.style import color_mode, toggle_color_mode
|
||||||
from reflex.vars import BaseVar
|
from reflex.utils import console
|
||||||
from .components.button import Button
|
from reflex.vars import BaseVar, Var
|
||||||
from .components.switch import Switch
|
from .components.icon_button import IconButton
|
||||||
|
|
||||||
DEFAULT_LIGHT_ICON: Icon
|
DEFAULT_LIGHT_ICON: Icon
|
||||||
DEFAULT_DARK_ICON: Icon
|
DEFAULT_DARK_ICON: Icon
|
||||||
@ -92,187 +93,23 @@ class ColorModeIcon(Cond):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
class ColorModeSwitch(Switch):
|
LiteralPosition = Literal["top-left", "top-right", "bottom-left", "bottom-right"]
|
||||||
@overload
|
position_values = get_args(LiteralPosition)
|
||||||
@classmethod
|
position_map = {
|
||||||
def create( # type: ignore
|
"position": position_values,
|
||||||
cls,
|
"left": ["top-left", "bottom-left"],
|
||||||
*children,
|
"right": ["top-right", "bottom-right"],
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
"top": ["top-left", "top-right"],
|
||||||
default_checked: Optional[Union[Var[bool], bool]] = None,
|
"bottom": ["bottom-left", "bottom-right"],
|
||||||
checked: Optional[Union[Var[bool], bool]] = None,
|
}
|
||||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
|
||||||
required: Optional[Union[Var[bool], bool]] = None,
|
class ColorModeIconButton(IconButton):
|
||||||
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):
|
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
|
position: Optional[LiteralPosition | None] = None,
|
||||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
size: Optional[
|
size: Optional[
|
||||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
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]
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
] = None,
|
] = None,
|
||||||
**props
|
**props
|
||||||
) -> "ColorModeButton":
|
) -> "ColorModeIconButton":
|
||||||
"""Create a button component that calls toggle_color_mode on click.
|
"""Create a icon button component that calls toggle_color_mode on click.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*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.
|
as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
|
||||||
size: Button size "1" - "4"
|
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
|
color_scheme: Override theme color for button
|
||||||
high_contrast: Whether to render the button with higher contrast color against background
|
high_contrast: Whether to render the button with higher contrast color against background
|
||||||
radius: Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
radius: Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
||||||
@ -524,7 +362,6 @@ class ColorModeButton(Button):
|
|||||||
|
|
||||||
class ColorModeNamespace(BaseVar):
|
class ColorModeNamespace(BaseVar):
|
||||||
icon = staticmethod(ColorModeIcon.create)
|
icon = staticmethod(ColorModeIcon.create)
|
||||||
switch = staticmethod(ColorModeSwitch.create)
|
button = staticmethod(ColorModeIconButton.create)
|
||||||
button = staticmethod(ColorModeButton.create)
|
|
||||||
|
|
||||||
color_mode_var_and_namespace = ColorModeNamespace(**dataclasses.asdict(color_mode))
|
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.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 (
|
||||||
@ -86,10 +85,8 @@ class IconButton(el.Button, RadixLoadingProp, RadixThemesComponent):
|
|||||||
("4", "48px"),
|
("4", "48px"),
|
||||||
"12px",
|
"12px",
|
||||||
)
|
)
|
||||||
|
props.setdefault("padding", "6px")
|
||||||
return super().create(*children, **props)
|
return super().create(*children, **props)
|
||||||
|
|
||||||
def _apply_theme(self, theme: Component):
|
|
||||||
self.style = Style({"padding": "6px", **self.style})
|
|
||||||
|
|
||||||
|
|
||||||
icon_button = IconButton.create
|
icon_button = IconButton.create
|
||||||
|
@ -12,7 +12,6 @@ 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,
|
||||||
|
Loading…
Reference in New Issue
Block a user