pc table validation (#1075)
This commit is contained in:
parent
0afea72eaf
commit
368b79f160
@ -64,6 +64,9 @@ class Component(Base, ABC):
|
||||
# Whether the component should take the focus once the page is loaded
|
||||
autofocus: bool = False
|
||||
|
||||
# components that cannot be children
|
||||
invalid_children: List[str] = []
|
||||
|
||||
@classmethod
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
"""Set default properties.
|
||||
@ -411,7 +414,8 @@ class Component(Base, ABC):
|
||||
The dictionary for template of component.
|
||||
"""
|
||||
tag = self._render()
|
||||
return dict(
|
||||
|
||||
rendered_dict = dict(
|
||||
tag.add_props(
|
||||
**self.event_triggers,
|
||||
key=self.key,
|
||||
@ -425,6 +429,29 @@ class Component(Base, ABC):
|
||||
),
|
||||
autofocus=self.autofocus,
|
||||
)
|
||||
self._validate_component_children(
|
||||
rendered_dict["name"], rendered_dict["children"]
|
||||
)
|
||||
return rendered_dict
|
||||
|
||||
def _validate_component_children(self, comp_name: str, children: List[Dict]):
|
||||
"""Validate the children components.
|
||||
|
||||
Args:
|
||||
comp_name: name of the component.
|
||||
children: list of children components.
|
||||
|
||||
Raises:
|
||||
ValueError: when an unsupported component is matched.
|
||||
"""
|
||||
if not self.invalid_children:
|
||||
return
|
||||
for child in children:
|
||||
name = child["name"]
|
||||
if name in self.invalid_children:
|
||||
raise ValueError(
|
||||
f"The component `{comp_name.lower()}` cannot have `{name.lower()}` as a child component"
|
||||
)
|
||||
|
||||
def _get_custom_code(self) -> Optional[str]:
|
||||
"""Get custom code for the component.
|
||||
|
@ -1,4 +1,5 @@
|
||||
"""Table components."""
|
||||
from typing import List
|
||||
|
||||
from pynecone.components.component import Component
|
||||
from pynecone.components.layout.foreach import Foreach
|
||||
@ -62,6 +63,9 @@ class Thead(ChakraComponent):
|
||||
|
||||
tag = "Thead"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead", "Tfoot"]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, headers=None, **props) -> Component:
|
||||
"""Create a table header component.
|
||||
@ -84,6 +88,9 @@ class Tbody(ChakraComponent):
|
||||
|
||||
tag = "Tbody"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead", "Tfoot", "Td", "Th"]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, rows=None, **props) -> Component:
|
||||
"""Create a table body component.
|
||||
@ -106,6 +113,9 @@ class Tfoot(ChakraComponent):
|
||||
|
||||
tag = "Tfoot"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead", "Td", "Th", "Tfoot"]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, footers=None, **props) -> Component:
|
||||
"""Create a table footer component.
|
||||
@ -128,6 +138,9 @@ class Tr(ChakraComponent):
|
||||
|
||||
tag = "Tr"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead", "Tfoot", "Tr"]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, cell_type: str = "", cells=None, **props) -> Component:
|
||||
"""Create a table row component.
|
||||
@ -156,6 +169,9 @@ class Th(ChakraComponent):
|
||||
|
||||
tag = "Th"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead", "Tr", "Td", "Th"]
|
||||
|
||||
# Aligns the cell content to the right.
|
||||
is_numeric: Var[bool]
|
||||
|
||||
@ -165,6 +181,9 @@ class Td(ChakraComponent):
|
||||
|
||||
tag = "Td"
|
||||
|
||||
# invalid children components
|
||||
invalid_children: List[str] = ["Tbody", "Thead"]
|
||||
|
||||
# Aligns the cell content to the right.
|
||||
is_numeric: Var[bool]
|
||||
|
||||
|
@ -112,6 +112,22 @@ def component4() -> Type[Component]:
|
||||
return TestComponent4
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def component5() -> Type[Component]:
|
||||
"""A test component.
|
||||
|
||||
Returns:
|
||||
A test component.
|
||||
"""
|
||||
|
||||
class TestComponent5(Component):
|
||||
tag = "Tag"
|
||||
|
||||
invalid_children: List[str] = ["Text"]
|
||||
|
||||
return TestComponent5
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def on_click1() -> EventHandler:
|
||||
"""A sample on click function.
|
||||
@ -433,3 +449,18 @@ def test_get_hooks_nested2(component3, component4):
|
||||
).get_hooks()
|
||||
== exp_hooks
|
||||
)
|
||||
|
||||
|
||||
def test_unsupported_child_components(component5):
|
||||
"""Test that a value error is raised when an unsupported component is provided as a child.
|
||||
|
||||
Args:
|
||||
component5: the test component
|
||||
"""
|
||||
with pytest.raises(ValueError) as err:
|
||||
comp = component5.create(pc.text("testing component"))
|
||||
comp.render()
|
||||
assert (
|
||||
err.value.args[0]
|
||||
== f"The component `tag` cannot have `text` as a child component"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user