Component: translate underscore suffix for props supported by chakra (#2636)

* Component: translate underscore suffix for props supported by chakra

type_ becomes type
min_ becomes min
max_ becomes max
id_ becomes id

The deprecation warning is only displayed when the underscore suffix prop is
passed and the non-underscore suffix prop is defined on the given component.

* Rename type_ to type in accordion and scroll_area

All of the new radix components avoid the underscore suffix names where
possible.

* Update deprecation warning wording

* Refactor for readability

* Do not raise deprecation warning for `id_`

id is kind of a special prop because it exists on all components

* Add test case for deprecating underscore suffix props
This commit is contained in:
Masen Furer 2024-02-15 20:46:06 -08:00 committed by GitHub
parent 0beec0b2a6
commit 3350fa0388
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 77 additions and 6 deletions

View File

@ -598,6 +598,21 @@ class Component(BaseComponent, ABC):
# Import here to avoid circular imports. # Import here to avoid circular imports.
from reflex.components.base.bare import Bare from reflex.components.base.bare import Bare
# Translate deprecated props to new names.
new_prop_names = [
prop for prop in cls.get_props() if prop in ["type", "min", "max"]
]
for prop in new_prop_names:
under_prop = f"{prop}_"
if under_prop in props:
console.deprecate(
f"Underscore suffix for prop `{under_prop}`",
reason=f"for consistency. Use `{prop}` instead.",
deprecation_version="0.4.0",
removal_version="0.5.0",
)
props[prop] = props.pop(under_prop)
# Validate all the children. # Validate all the children.
for child in children: for child in children:
# Make sure the child is a valid type. # Make sure the child is a valid type.

View File

@ -311,7 +311,7 @@ class AccordionRoot(AccordionComponent):
alias = "RadixAccordionRoot" alias = "RadixAccordionRoot"
# The type of accordion (single or multiple). # The type of accordion (single or multiple).
type_: Var[LiteralAccordionType] type: Var[LiteralAccordionType]
# The value of the item to expand. # The value of the item to expand.
value: Var[Optional[Union[str, List[str]]]] value: Var[Optional[Union[str, List[str]]]]

View File

@ -125,7 +125,7 @@ class AccordionRoot(AccordionComponent):
def create( # type: ignore def create( # type: ignore
cls, cls,
*children, *children,
type_: Optional[ type: Optional[
Union[Var[Literal["single", "multiple"]], Literal["single", "multiple"]] Union[Var[Literal["single", "multiple"]], Literal["single", "multiple"]]
] = None, ] = None,
value: Optional[ value: Optional[
@ -274,7 +274,7 @@ class AccordionRoot(AccordionComponent):
Args: Args:
*children: The children of the component. *children: The children of the component.
type_: The type of accordion (single or multiple). type: The type of accordion (single or multiple).
value: The value of the item to expand. value: The value of the item to expand.
default_value: The default value of the item to expand. default_value: The default value of the item to expand.
collapsible: Whether or not the accordion is collapsible. collapsible: Whether or not the accordion is collapsible.

View File

@ -17,7 +17,7 @@ class ScrollArea(RadixThemesComponent):
scrollbars: Var[Literal["vertical", "horizontal", "both"]] scrollbars: Var[Literal["vertical", "horizontal", "both"]]
# Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars. "auto" | "always" | "scroll" | "hover" # Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars. "auto" | "always" | "scroll" | "hover"
type_: Var[Literal["auto", "always", "scroll", "hover"]] type: Var[Literal["auto", "always", "scroll", "hover"]]
# If type is set to either "scroll" or "hover", this prop determines the length of time, in milliseconds, before the scrollbars are hidden after the user stops interacting with scrollbars. # If type is set to either "scroll" or "hover", this prop determines the length of time, in milliseconds, before the scrollbars are hidden after the user stops interacting with scrollbars.
scroll_hide_delay: Var[int] scroll_hide_delay: Var[int]

View File

@ -23,7 +23,7 @@ class ScrollArea(RadixThemesComponent):
Literal["vertical", "horizontal", "both"], Literal["vertical", "horizontal", "both"],
] ]
] = None, ] = None,
type_: Optional[ type: Optional[
Union[ Union[
Var[Literal["auto", "always", "scroll", "hover"]], Var[Literal["auto", "always", "scroll", "hover"]],
Literal["auto", "always", "scroll", "hover"], Literal["auto", "always", "scroll", "hover"],
@ -91,7 +91,7 @@ class ScrollArea(RadixThemesComponent):
Args: Args:
*children: Child components. *children: Child components.
scrollbars: The alignment of the scroll area scrollbars: The alignment of the scroll area
type_: Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars. "auto" | "always" | "scroll" | "hover" type: Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars. "auto" | "always" | "scroll" | "hover"
scroll_hide_delay: If type is set to either "scroll" or "hover", this prop determines the length of time, in milliseconds, before the scrollbars are hidden after the user stops interacting with scrollbars. scroll_hide_delay: If type is set to either "scroll" or "hover", this prop determines the length of time, in milliseconds, before the scrollbars are hidden after the user stops interacting with scrollbars.
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.

View File

@ -1213,3 +1213,59 @@ def test_rename_props():
assert "renamed_prop1={`prop1_2`}" in rendered_c2["props"] assert "renamed_prop1={`prop1_2`}" in rendered_c2["props"]
assert "subclass_prop2={`prop2_2`}" in rendered_c2["props"] assert "subclass_prop2={`prop2_2`}" in rendered_c2["props"]
assert "renamed_prop3={`prop3_2`}" in rendered_c2["props"] assert "renamed_prop3={`prop3_2`}" in rendered_c2["props"]
def test_deprecated_props(capsys):
"""Assert that deprecated underscore suffix props are translated.
Args:
capsys: Pytest fixture for capturing stdout and stderr.
"""
class C1(Component):
tag = "C1"
type: Var[str]
min: Var[str]
max: Var[str]
# No warnings are emitted when using the new prop names.
c1_1 = C1.create(type="type1", min="min1", max="max1")
out_err = capsys.readouterr()
assert not out_err.err
assert not out_err.out
c1_1_render = c1_1.render()
assert "type={`type1`}" in c1_1_render["props"]
assert "min={`min1`}" in c1_1_render["props"]
assert "max={`max1`}" in c1_1_render["props"]
# Deprecation warning is emitted with underscore suffix,
# but the component still works.
c1_2 = C1.create(type_="type2", min_="min2", max_="max2")
out_err = capsys.readouterr()
assert out_err.out.count("DeprecationWarning:") == 3
assert not out_err.err
c1_2_render = c1_2.render()
assert "type={`type2`}" in c1_2_render["props"]
assert "min={`min2`}" in c1_2_render["props"]
assert "max={`max2`}" in c1_2_render["props"]
class C2(Component):
tag = "C2"
type_: Var[str]
min_: Var[str]
max_: Var[str]
# No warnings are emitted if the actual prop has an underscore suffix
c2_1 = C2.create(type_="type1", min_="min1", max_="max1")
out_err = capsys.readouterr()
assert not out_err.err
assert not out_err.out
c2_1_render = c2_1.render()
assert "type={`type1`}" in c2_1_render["props"]
assert "min={`min1`}" in c2_1_render["props"]
assert "max={`max1`}" in c2_1_render["props"]