diff --git a/reflex/__init__.py b/reflex/__init__.py index 87280b130..0fb530e90 100644 --- a/reflex/__init__.py +++ b/reflex/__init__.py @@ -9,7 +9,6 @@ from __future__ import annotations import importlib from typing import Type -from reflex.constants.colors import Color as color from reflex.page import page as page from reflex.utils import console from reflex.utils.format import to_snake_case @@ -254,6 +253,7 @@ _MAPPING = { "reflex.compiler.utils": ["get_asset_path"], "reflex.components": _ALL_COMPONENTS + ["chakra", "next"], "reflex.components.component": ["memo"], + "reflex.components.core": ["color"], "reflex.components.el": ["el"], "reflex.components.lucide": ["lucide"], "reflex.components.radix": ["radix"], diff --git a/reflex/__init__.pyi b/reflex/__init__.pyi index 251e8d34f..a259161c8 100644 --- a/reflex/__init__.pyi +++ b/reflex/__init__.pyi @@ -447,6 +447,7 @@ from reflex.components import NoSSRComponent as NoSSRComponent from reflex.components import chakra as chakra from reflex.components import next as next from reflex.components.component import memo as memo +from reflex.components.core import color as color from reflex.components import el as el from reflex.components import lucide as lucide from reflex.components import radix as radix diff --git a/reflex/components/core/__init__.py b/reflex/components/core/__init__.py index 4df12bef4..ba26ecfeb 100644 --- a/reflex/components/core/__init__.py +++ b/reflex/components/core/__init__.py @@ -2,6 +2,7 @@ from . import layout as layout from .banner import ConnectionBanner, ConnectionModal +from .colors import color from .cond import Cond, cond from .debounce import DebounceInput from .foreach import Foreach diff --git a/reflex/components/core/colors.py b/reflex/components/core/colors.py new file mode 100644 index 000000000..d146fae1e --- /dev/null +++ b/reflex/components/core/colors.py @@ -0,0 +1,21 @@ +"""The colors used in Reflex are a wrapper around https://www.radix-ui.com/colors.""" + +from reflex.constants.colors import Color, ColorType, ShadeType + + +def color( + color: ColorType, + shade: ShadeType = 7, + alpha: bool = False, +) -> Color: + """Create a color object. + + Args: + color: The color to use. + shade: The shade of the color to use. + alpha: Whether to use the alpha variant of the color. + + Returns: + The color object. + """ + return Color(color, shade, alpha) diff --git a/reflex/constants/colors.py b/reflex/constants/colors.py index 8524c4a77..fe4616abc 100644 --- a/reflex/constants/colors.py +++ b/reflex/constants/colors.py @@ -1,4 +1,5 @@ """The colors used in Reflex are a wrapper around https://www.radix-ui.com/colors.""" + from dataclasses import dataclass from typing import Literal @@ -40,6 +41,20 @@ ColorType = Literal[ ShadeType = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] +def format_color(color: ColorType, shade: ShadeType, alpha: bool) -> str: + """Format a color as a CSS color string. + + Args: + color: The color to use. + shade: The shade of the color to use. + alpha: Whether to use the alpha variant of the color. + + Returns: + The formatted color. + """ + return f"var(--{color}-{'a' if alpha else ''}{shade})" + + @dataclass class Color: """A color in the Reflex color palette.""" @@ -52,3 +67,14 @@ class Color: # Whether to use the alpha variant of the color alpha: bool = False + + def __format__(self, format_spec: str) -> str: + """Format the color as a CSS color string. + + Args: + format_spec: The format specifier to use. + + Returns: + The formatted color. + """ + return format_color(self.color, self.shade, self.alpha) diff --git a/reflex/utils/serializers.py b/reflex/utils/serializers.py index 6174f8c82..60f07c32a 100644 --- a/reflex/utils/serializers.py +++ b/reflex/utils/serializers.py @@ -8,7 +8,7 @@ from datetime import date, datetime, time, timedelta from typing import Any, Callable, Dict, List, Set, Tuple, Type, Union, get_type_hints from reflex.base import Base -from reflex.constants.colors import Color +from reflex.constants.colors import Color, format_color from reflex.utils import exceptions, format, types # Mapping from type to a serializer. @@ -232,7 +232,7 @@ def serialize_datetime(dt: Union[date, datetime, time, timedelta]) -> str: @serializer -def serialize_color(color: Color) -> SerializedType: +def serialize_color(color: Color) -> str: """Serialize a color. Args: @@ -241,10 +241,7 @@ def serialize_color(color: Color) -> SerializedType: Returns: The serialized color. """ - if color.alpha: - return f"var(--{color.color}-a{color.shade})" - else: - return f"var(--{color.color}-{color.shade})" + return format_color(color.color, color.shade, color.alpha) try: diff --git a/tests/utils/test_serializers.py b/tests/utils/test_serializers.py index b08505a2e..e136c5300 100644 --- a/tests/utils/test_serializers.py +++ b/tests/utils/test_serializers.py @@ -5,7 +5,7 @@ from typing import Any, Dict, List, Type import pytest from reflex.base import Base -from reflex.constants.colors import Color as color +from reflex.components.core.colors import color from reflex.utils import serializers from reflex.vars import Var