Pārlūkot izejas kodu

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
Masen Furer 1 gadu atpakaļ
vecāks
revīzija
3350fa0388

+ 15 - 0
reflex/components/component.py

@@ -598,6 +598,21 @@ class Component(BaseComponent, ABC):
         # Import here to avoid circular imports.
         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.
         for child in children:
             # Make sure the child is a valid type.

+ 1 - 1
reflex/components/radix/primitives/accordion.py

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

+ 2 - 2
reflex/components/radix/primitives/accordion.pyi

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

+ 1 - 1
reflex/components/radix/themes/components/scroll_area.py

@@ -17,7 +17,7 @@ class ScrollArea(RadixThemesComponent):
     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"
-    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.
     scroll_hide_delay: Var[int]

+ 2 - 2
reflex/components/radix/themes/components/scroll_area.pyi

@@ -23,7 +23,7 @@ class ScrollArea(RadixThemesComponent):
                 Literal["vertical", "horizontal", "both"],
             ]
         ] = None,
-        type_: Optional[
+        type: Optional[
             Union[
                 Var[Literal["auto", "always", "scroll", "hover"]],
                 Literal["auto", "always", "scroll", "hover"],
@@ -91,7 +91,7 @@ class ScrollArea(RadixThemesComponent):
         Args:
             *children: Child components.
             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.
             style: The style of the component.
             key: A unique key for the component.

+ 56 - 0
tests/components/test_component.py

@@ -1213,3 +1213,59 @@ def test_rename_props():
     assert "renamed_prop1={`prop1_2`}" in rendered_c2["props"]
     assert "subclass_prop2={`prop2_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"]