Tabs validate parent is proper tab container (#2463)
This commit is contained in:
parent
3ff88390c2
commit
209c5fab7b
@ -90,20 +90,28 @@ class Tab(ChakraComponent):
|
||||
# The id of the panel.
|
||||
panel_id: Var[str]
|
||||
|
||||
_valid_parents: List[str] = ["TabList"]
|
||||
|
||||
|
||||
class TabList(ChakraComponent):
|
||||
"""Wrapper for the Tab components."""
|
||||
|
||||
tag = "TabList"
|
||||
|
||||
_valid_parents: List[str] = ["Tabs"]
|
||||
|
||||
|
||||
class TabPanels(ChakraComponent):
|
||||
"""Wrapper for the Tab components."""
|
||||
|
||||
tag = "TabPanels"
|
||||
|
||||
_valid_parents: List[str] = ["Tabs"]
|
||||
|
||||
|
||||
class TabPanel(ChakraComponent):
|
||||
"""An element that contains the content associated with a tab."""
|
||||
|
||||
tag = "TabPanel"
|
||||
|
||||
_valid_parents: List[str] = ["TabPanels"]
|
||||
|
@ -155,6 +155,9 @@ class Component(BaseComponent, ABC):
|
||||
# only components that are allowed as children
|
||||
_valid_children: List[str] = []
|
||||
|
||||
# only components that are allowed as parent
|
||||
_valid_parents: List[str] = []
|
||||
|
||||
# custom attribute
|
||||
custom_attrs: Dict[str, Union[Var, str]] = {}
|
||||
|
||||
@ -651,7 +654,8 @@ class Component(BaseComponent, ABC):
|
||||
children: The children of the component.
|
||||
|
||||
"""
|
||||
if not self._invalid_children and not self._valid_children:
|
||||
skip_parentable = all(child._valid_parents == [] for child in children)
|
||||
if not self._invalid_children and not self._valid_children and skip_parentable:
|
||||
return
|
||||
|
||||
comp_name = type(self).__name__
|
||||
@ -671,6 +675,15 @@ class Component(BaseComponent, ABC):
|
||||
f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
|
||||
)
|
||||
|
||||
def validate_vaild_parent(child_name, valid_parents):
|
||||
if comp_name not in valid_parents:
|
||||
valid_parent_list = ", ".join(
|
||||
[f"`{v_parent}`" for v_parent in valid_parents]
|
||||
)
|
||||
raise ValueError(
|
||||
f"The component `{child_name}` can only be a child of the components: {valid_parent_list}. Got `{comp_name}` instead."
|
||||
)
|
||||
|
||||
for child in children:
|
||||
name = type(child).__name__
|
||||
|
||||
@ -680,6 +693,9 @@ class Component(BaseComponent, ABC):
|
||||
if self._valid_children:
|
||||
validate_valid_child(name)
|
||||
|
||||
if child._valid_parents:
|
||||
validate_vaild_parent(name, child._valid_parents)
|
||||
|
||||
@staticmethod
|
||||
def _get_vars_from_event_triggers(
|
||||
event_triggers: dict[str, EventChain | Var],
|
||||
|
@ -55,6 +55,7 @@ EXCLUDED_PROPS = [
|
||||
"_invalid_children",
|
||||
"_memoization_mode",
|
||||
"_valid_children",
|
||||
"_valid_parents",
|
||||
]
|
||||
|
||||
DEFAULT_TYPING_IMPORTS = {
|
||||
|
@ -137,6 +137,8 @@ def component5() -> Type[Component]:
|
||||
|
||||
_valid_children: List[str] = ["Text"]
|
||||
|
||||
_valid_parents: List[str] = ["Text"]
|
||||
|
||||
return TestComponent5
|
||||
|
||||
|
||||
@ -569,6 +571,20 @@ def test_unsupported_child_components(fixture, request):
|
||||
)
|
||||
|
||||
|
||||
def test_unsupported_parent_components(component5):
|
||||
"""Test that a value error is raised when an component is not in _valid_parents of one of its children.
|
||||
|
||||
Args:
|
||||
component5: component with valid parent of "Text" only
|
||||
"""
|
||||
with pytest.raises(ValueError) as err:
|
||||
rx.Box(children=[component5.create()])
|
||||
assert (
|
||||
err.value.args[0]
|
||||
== f"The component `{component5.__name__}` can only be a child of the components: `{component5._valid_parents[0]}`. Got `Box` instead."
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fixture", ["component5", "component7"])
|
||||
def test_component_with_only_valid_children(fixture, request):
|
||||
"""Test that a value error is raised when an unsupported component (a child component not found in the
|
||||
|
Loading…
Reference in New Issue
Block a user