fix dynamic icons for underscore and positional argument
This commit is contained in:
parent
b3b79a652d
commit
1da68d2467
@ -107,9 +107,7 @@ class StickyBadge(A):
|
||||
default=True,
|
||||
global_ref=False,
|
||||
)
|
||||
localhost_hostnames = Var.create(
|
||||
["localhost", "127.0.0.1", "[::1]"]
|
||||
).guess_type()
|
||||
localhost_hostnames = Var.create(["localhost", "127.0.0.1", "[::1]"])
|
||||
is_localhost_expr = localhost_hostnames.contains(
|
||||
Var("window.location.hostname", _var_type=str).guess_type(),
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ from reflex.components.component import Component
|
||||
from reflex.utils import format
|
||||
from reflex.utils.imports import ImportVar
|
||||
from reflex.vars.base import LiteralVar, Var
|
||||
from reflex.vars.sequence import LiteralStringVar
|
||||
from reflex.vars.sequence import LiteralStringVar, StringVar
|
||||
|
||||
|
||||
class LucideIconComponent(Component):
|
||||
@ -40,7 +40,12 @@ class Icon(LucideIconComponent):
|
||||
The created component.
|
||||
"""
|
||||
if children:
|
||||
if len(children) == 1 and isinstance(children[0], str):
|
||||
if len(children) == 1:
|
||||
child = Var.create(children[0]).guess_type()
|
||||
if not isinstance(child, StringVar):
|
||||
raise AttributeError(
|
||||
f"Icon name must be a string, got {children[0]._var_type if isinstance(children[0], Var) else children[0]}"
|
||||
)
|
||||
props["tag"] = children[0]
|
||||
else:
|
||||
raise AttributeError(
|
||||
@ -56,7 +61,10 @@ class Icon(LucideIconComponent):
|
||||
else:
|
||||
raise TypeError(f"Icon name must be a string, got {type(tag)}")
|
||||
elif isinstance(tag, Var):
|
||||
return DynamicIcon.create(name=tag, **props)
|
||||
tag_stringified = tag.guess_type()
|
||||
if not isinstance(tag_stringified, StringVar):
|
||||
raise TypeError(f"Icon name must be a string, got {tag._var_type}")
|
||||
return DynamicIcon.create(name=tag_stringified.replace("_", "-"), **props)
|
||||
|
||||
if (
|
||||
not isinstance(tag, str)
|
||||
|
@ -27,6 +27,7 @@ from typing import (
|
||||
List,
|
||||
Literal,
|
||||
Mapping,
|
||||
Never,
|
||||
NoReturn,
|
||||
Optional,
|
||||
Sequence,
|
||||
@ -75,9 +76,9 @@ from reflex.utils.types import (
|
||||
if TYPE_CHECKING:
|
||||
from reflex.state import BaseState
|
||||
|
||||
from .number import BooleanVar, NumberVar
|
||||
from .object import ObjectVar
|
||||
from .sequence import ArrayVar, StringVar
|
||||
from .number import BooleanVar, LiteralBooleanVar, LiteralNumberVar, NumberVar
|
||||
from .object import LiteralObjectVar, ObjectVar
|
||||
from .sequence import ArrayVar, LiteralArrayVar, LiteralStringVar, StringVar
|
||||
|
||||
|
||||
VAR_TYPE = TypeVar("VAR_TYPE", covariant=True)
|
||||
@ -573,13 +574,21 @@ class Var(Generic[VAR_TYPE]):
|
||||
|
||||
return value_with_replaced
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # pyright: ignore[reportOverlappingOverload]
|
||||
cls,
|
||||
value: Never,
|
||||
_var_data: VarData | None = None,
|
||||
) -> Var[Any]: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # pyright: ignore[reportOverlappingOverload]
|
||||
cls,
|
||||
value: bool,
|
||||
_var_data: VarData | None = None,
|
||||
) -> BooleanVar: ...
|
||||
) -> LiteralBooleanVar: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@ -587,7 +596,7 @@ class Var(Generic[VAR_TYPE]):
|
||||
cls,
|
||||
value: int,
|
||||
_var_data: VarData | None = None,
|
||||
) -> NumberVar[int]: ...
|
||||
) -> LiteralNumberVar[int]: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@ -595,7 +604,15 @@ class Var(Generic[VAR_TYPE]):
|
||||
cls,
|
||||
value: float,
|
||||
_var_data: VarData | None = None,
|
||||
) -> NumberVar[float]: ...
|
||||
) -> LiteralNumberVar[float]: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # pyright: ignore [reportOverlappingOverload]
|
||||
cls,
|
||||
value: str,
|
||||
_var_data: VarData | None = None,
|
||||
) -> LiteralStringVar: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@ -611,7 +628,7 @@ class Var(Generic[VAR_TYPE]):
|
||||
cls,
|
||||
value: None,
|
||||
_var_data: VarData | None = None,
|
||||
) -> NoneVar: ...
|
||||
) -> LiteralNoneVar: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@ -619,7 +636,7 @@ class Var(Generic[VAR_TYPE]):
|
||||
cls,
|
||||
value: MAPPING_TYPE,
|
||||
_var_data: VarData | None = None,
|
||||
) -> ObjectVar[MAPPING_TYPE]: ...
|
||||
) -> LiteralObjectVar[MAPPING_TYPE]: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@ -627,7 +644,7 @@ class Var(Generic[VAR_TYPE]):
|
||||
cls,
|
||||
value: SEQUENCE_TYPE,
|
||||
_var_data: VarData | None = None,
|
||||
) -> ArrayVar[SEQUENCE_TYPE]: ...
|
||||
) -> LiteralArrayVar[SEQUENCE_TYPE]: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
|
@ -974,7 +974,7 @@ def boolean_not_operation(value: BooleanVar):
|
||||
frozen=True,
|
||||
slots=True,
|
||||
)
|
||||
class LiteralNumberVar(LiteralVar, NumberVar):
|
||||
class LiteralNumberVar(LiteralVar, NumberVar[NUMBER_T]):
|
||||
"""Base class for immutable literal number vars."""
|
||||
|
||||
_var_value: float | int = dataclasses.field(default=0)
|
||||
|
@ -372,6 +372,33 @@ class StringVar(Var[STRING_TYPE], python_types=str):
|
||||
|
||||
return string_ge_operation(self, other)
|
||||
|
||||
@overload
|
||||
def replace( # pyright: ignore [reportOverlappingOverload]
|
||||
self, search_value: StringVar | str, new_value: StringVar | str
|
||||
) -> StringVar: ...
|
||||
|
||||
@overload
|
||||
def replace(
|
||||
self, search_value: Any, new_value: Any
|
||||
) -> CustomVarOperationReturn[StringVar]: ...
|
||||
|
||||
def replace(self, search_value: Any, new_value: Any) -> StringVar: # pyright: ignore [reportInconsistentOverload]
|
||||
"""Replace a string with a value.
|
||||
|
||||
Args:
|
||||
search_value: The string to search.
|
||||
new_value: The value to be replaced with.
|
||||
|
||||
Returns:
|
||||
The string replace operation.
|
||||
"""
|
||||
if not isinstance(search_value, (StringVar, str)):
|
||||
raise_unsupported_operand_types("replace", (type(self), type(search_value)))
|
||||
if not isinstance(new_value, (StringVar, str)):
|
||||
raise_unsupported_operand_types("replace", (type(self), type(new_value)))
|
||||
|
||||
return string_replace_operation(self, search_value, new_value)
|
||||
|
||||
|
||||
@var_operation
|
||||
def string_lt_operation(lhs: StringVar[Any] | str, rhs: StringVar[Any] | str):
|
||||
@ -570,7 +597,7 @@ def array_join_operation(array: ArrayVar, sep: StringVar[Any] | str = ""):
|
||||
|
||||
@var_operation
|
||||
def string_replace_operation(
|
||||
string: StringVar, search_value: StringVar | str, new_value: StringVar | str
|
||||
string: StringVar[Any], search_value: StringVar | str, new_value: StringVar | str
|
||||
):
|
||||
"""Replace a string with a value.
|
||||
|
||||
@ -583,7 +610,7 @@ def string_replace_operation(
|
||||
The string replace operation.
|
||||
"""
|
||||
return var_operation_return(
|
||||
js_expression=f"{string}.replace({search_value}, {new_value})",
|
||||
js_expression=f"{string}.replaceAll({search_value}, {new_value})",
|
||||
var_type=str,
|
||||
)
|
||||
|
||||
|
@ -11,6 +11,7 @@ from reflex.components.lucide.icon import Icon
|
||||
from reflex.components.radix.themes.layout.box import Box
|
||||
from reflex.style import Style
|
||||
from reflex.vars import Var
|
||||
from reflex.vars.base import LiteralVar
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -99,7 +100,9 @@ def test_create_shiki_code_block(
|
||||
|
||||
applied_styles = component.style
|
||||
for key, value in expected_styles.items():
|
||||
assert Var.create(applied_styles[key])._var_value == value
|
||||
var = Var.create(applied_styles[key])
|
||||
assert isinstance(var, LiteralVar)
|
||||
assert var._var_value == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -74,11 +74,11 @@ class ObjectState(rx.State):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type_", [Base, Bare, SqlaModel, Dataclass])
|
||||
def test_var_create(type_: GenericType) -> None:
|
||||
def test_var_create(type_: type[Base | Bare | SqlaModel | Dataclass]) -> None:
|
||||
my_object = type_()
|
||||
var = Var.create(my_object)
|
||||
assert var._var_type is type_
|
||||
|
||||
assert isinstance(var, ObjectVar)
|
||||
quantity = var.quantity
|
||||
assert quantity._var_type is int
|
||||
|
||||
@ -94,12 +94,12 @@ def test_literal_create(type_: GenericType) -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("type_", [Base, Bare, SqlaModel, Dataclass])
|
||||
def test_guess(type_: GenericType) -> None:
|
||||
def test_guess(type_: type[Base | Bare | SqlaModel | Dataclass]) -> None:
|
||||
my_object = type_()
|
||||
var = Var.create(my_object)
|
||||
var = var.guess_type()
|
||||
assert var._var_type is type_
|
||||
|
||||
assert isinstance(var, ObjectVar)
|
||||
quantity = var.quantity
|
||||
assert quantity._var_type is int
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user