Sfoglia il codice sorgente

Provide high-level API for most components (#451)

Thomas Brandého 2 anni fa
parent
commit
0b2f1369a6

+ 20 - 2
pynecone/components/datadisplay/list.py

@@ -19,6 +19,24 @@ class List(ChakraComponent):
     # Shorthand prop for listStyleType
     style_type: Var[str]
 
+    @classmethod
+    def create(cls, *children, items=None, **props) -> Component:
+        """Create a list component.
+
+        Args:
+            children: The children of the component.
+            items: A list of items to add to the list.
+            props: The properties of the component.
+
+        Returns:
+            The list component.
+        """
+        if len(children) == 0:
+            children = []
+            for item in items or []:
+                children.append(ListItem.create(*item))
+        return super().create(*children, **props)
+
 
 class ListItem(ChakraComponent):
     """A single list item."""
@@ -26,13 +44,13 @@ class ListItem(ChakraComponent):
     tag = "ListItem"
 
 
-class OrderedList(ChakraComponent):
+class OrderedList(List):
     """An ordered list component with numbers."""
 
     tag = "OrderedList"
 
 
-class UnorderedList(ChakraComponent):
+class UnorderedList(List):
     """An unordered list component with bullets."""
 
     tag = "UnorderedList"

+ 37 - 0
pynecone/components/datadisplay/stat.py

@@ -1,5 +1,6 @@
 """Statistics components."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -9,6 +10,42 @@ class Stat(ChakraComponent):
 
     tag = "Stat"
 
+    @classmethod
+    def create(
+        cls, *children, label=None, number=0, help_text=None, arrow_type=None, **props
+    ) -> Component:
+        """Create a stat component.
+
+        Args:
+            children: The children of the component.
+            label: A label for the stat component.
+            number: The value of the stat component.
+            help_text: A text added to the stat component.
+            arrow_type: The type of the arrow ("increase", "decrease", None)
+            props: The properties of the component.
+
+        Returns:
+            The stat component.
+        """
+        if len(children) == 0:
+            children = []
+            if label:
+                children.append(StatLabel.create(label))
+
+            children.append(StatNumber.create(number))
+
+            if help_text:
+                if arrow_type:
+                    children.append(
+                        StatHelpText.create(
+                            help_text, StatArrow.create(type_=arrow_type)
+                        )
+                    )
+                else:
+                    children.append(StatHelpText.create(help_text))
+
+        return super().create(*children, **props)
+
 
 class StatLabel(ChakraComponent):
     """A stat label component."""

+ 105 - 4
pynecone/components/datadisplay/table.py

@@ -1,6 +1,7 @@
 """Table components."""
 
 from typing import List
+from pynecone.components.component import Component
 
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
@@ -23,30 +24,130 @@ class Table(ChakraComponent):
     # The placement of the table caption.
     placement: Var[str]
 
+    @classmethod
+    def create(
+        cls, *children, caption=None, headers=None, rows=None, footers=None, **props
+    ) -> Component:
+        """Create a table component.
 
-class Thead(Table):
+        Args:
+            children: The children of the component.
+            caption: The caption of the table component.
+            headers: The headers of the table component.
+            rows: The rows of the table component.
+            footers: The footers of the table component.
+            props: The properties of the component.
+
+        Returns:
+            The table component.
+        """
+        if len(children) == 0:
+            children = []
+
+            if caption:
+                children.append(TableCaption.create(caption))
+
+            if headers:
+                children.append(Thead.create(headers=headers))
+
+            if rows:
+                children.append(Tbody.create(rows=rows))
+
+            if footers:
+                children.append(Tfoot.create(footers=footers))
+        return super().create(*children, **props)
+
+
+class Thead(ChakraComponent):
     """A table header component."""
 
     tag = "Thead"
 
+    @classmethod
+    def create(cls, *children, headers=None, **props) -> Component:
+        """Create a table header component.
+
+        Args:
+            children: The children of the component.
+            props: The properties of the component.
+            headers (list, optional): List of headers. Defaults to None.
+
+        Returns:
+            The table header component.
+        """
+        if len(children) == 0:
+            children = [Tr.create(cell_type="header", cells=headers)]
+        return super().create(*children, **props)
 
-class Tbody(Table):
+
+class Tbody(ChakraComponent):
     """A table body component."""
 
     tag = "Tbody"
 
+    @classmethod
+    def create(cls, *children, rows=None, **props) -> Component:
+        """Create a table body component.
+
+        Args:
+            children: The children of the component.
+            props: The properties of the component.
+            rows (list[list], optional): The rows of the table body. Defaults to None.
+
+        Returns:
+            Component: _description_
+        """
+        if len(children) == 0:
+            children = [Tr.create(cell_type="data", cells=row) for row in rows or []]
+        return super().create(*children, **props)
+
 
-class Tfoot(Table):
+class Tfoot(ChakraComponent):
     """A table footer component."""
 
     tag = "Tfoot"
 
+    @classmethod
+    def create(cls, *children, footers=None, **props) -> Component:
+        """Create a table footer component.
 
-class Tr(Table):
+        Args:
+            children: The children of the component.
+            props: The properties of the component.
+            footers (list, optional): List of footers. Defaults to None.
+
+        Returns:
+            The table footer component.
+        """
+        if len(children) == 0:
+            children = [Tr.create(cell_type="header", cells=footers)]
+        return super().create(*children, **props)
+
+
+class Tr(ChakraComponent):
     """A table row component."""
 
     tag = "Tr"
 
+    @classmethod
+    def create(cls, *children, cell_type: str = "", cells=None, **props) -> Component:
+        """Create a table row component.
+
+        Args:
+            children: The children of the component.
+            props: The properties of the component.
+            cell_type (str): the type of cells in this table row. "header" or "data". Defaults to None.
+            cells (list, optional): The cells value to add in the table row. Defaults to None.
+
+        Returns:
+            The table row component
+        """
+        types = {"header": Th, "data": Td}
+        cell_cls = types.get(cell_type)
+        if len(children) == 0 and cell_cls:
+            children = [cell_cls.create(cell) for cell in cells or []]
+        return super().create(*children, **props)
+
 
 class Th(ChakraComponent):
     """A table header cell component."""

+ 34 - 0
pynecone/components/disclosure/accordion.py

@@ -1,6 +1,7 @@
 """Container to stack elements with spacing."""
 
 from typing import List, Optional, Union
+from pynecone.components.component import Component
 
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
@@ -26,6 +27,39 @@ class Accordion(ChakraComponent):
     # If true, height animation and transitions will be disabled.
     reduce_motion: Var[bool]
 
+    @classmethod
+    def create(cls, *children, items=None, icon_pos="right", **props) -> Component:
+        """Create an accordion component.
+
+        Args:
+            children: The children of the component.
+            items: The items of the accordion component: list of tuples (label,panel)
+            icon_pos: The position of the arrow icon of the accordion. "right", "left" or None
+            props: The properties of the component.
+
+        Returns:
+            The accordion component
+        """
+        if len(children) == 0:
+            children = []
+            if not items:
+                items = []
+            for label, panel in items:
+                if icon_pos == "right":
+                    button = AccordionButton.create(label, AccordionIcon.create())
+                elif icon_pos == "left":
+                    button = AccordionButton.create(AccordionIcon.create(), label)
+                else:
+                    button = AccordionButton.create(label)
+
+                children.append(
+                    AccordionItem.create(
+                        button,
+                        AccordionPanel.create(panel),
+                    )
+                )
+        return super().create(*children, **props)
+
 
 class AccordionItem(ChakraComponent):
     """A single accordion item."""

+ 24 - 0
pynecone/components/disclosure/tabs.py

@@ -1,5 +1,6 @@
 """Tab components."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -33,6 +34,29 @@ class Tabs(ChakraComponent):
     # "line" | "enclosed" | "enclosed-colored" | "soft-rounded" | "solid-rounded" | "unstyled"
     variant: Var[str]
 
+    @classmethod
+    def create(cls, *children, items=None, **props) -> Component:
+        """Create a tab component.
+
+        Args:
+            children: The children of the component.
+            items: The items for the tabs component, a list of tuple (label, panel)
+            props: The properties of the component.
+
+        Returns:
+            The tab component
+        """
+        if len(children) == 0:
+            tabs = []
+            panels = []
+            if not items:
+                items = []
+            for label, panel in items:
+                tabs.append(Tab.create(label))
+                panels.append(TabPanel.create(panel))
+            children = [TabList.create(*tabs), TabPanels.create(*panels)]
+        return super().create(*children, **props)
+
 
 class Tab(ChakraComponent):
     """An element that serves as a label for one of the tab panels and can be activated to display that panel.."""

+ 30 - 0
pynecone/components/feedback/alert.py

@@ -1,5 +1,6 @@
 """Alert components."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -15,6 +16,35 @@ class Alert(ChakraComponent):
     # "subtle" | "left-accent" | "top-accent" | "solid"
     variant: Var[str]
 
+    @classmethod
+    def create(
+        cls, *children, icon=True, title="Alert title", desc=None, **props
+    ) -> Component:
+        """Create an alert component.
+
+        Args:
+            children: The children of the component.
+            icon (bool): The icon of the alert.
+            title (str): The title of the alert.
+            desc (str): The description of the alert
+            props: The properties of the component.
+
+        Returns:
+            The alert component.
+        """
+        if len(children) == 0:
+            contents = []
+
+            if icon:
+                contents.append(AlertIcon.create())
+
+            contents.append(AlertTitle.create(title))
+
+            if desc:
+                contents.append(AlertDescription.create(desc))
+
+        return super().create(*children, **props)
+
 
 class AlertIcon(ChakraComponent):
     """An icon displayed in the alert."""

+ 45 - 0
pynecone/components/forms/formcontrol.py

@@ -1,5 +1,6 @@
 """Form components."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -24,6 +25,50 @@ class FormControl(ChakraComponent):
     # The label text used to inform users as to what information is requested for a text field.
     label: Var[str]
 
+    @classmethod
+    def create(
+        cls,
+        *children,
+        label=None,
+        input=None,
+        help_text=None,
+        error_message=None,
+        **props
+    ) -> Component:
+        """Create a form control component.
+
+        Args:
+            children: The children of the form control.
+            label: The label of the form control.
+            input: The input of the form control.
+            help_text: The help text of the form control.
+            error_message: The error message of the form control.
+            props: The properties of the form control.
+
+        Raises:
+            AttributeError: raise an error if missing required kwargs.
+
+        Returns:
+            The form control component.
+        """
+        if len(children) == 0:
+            children = []
+
+            if label:
+                children.append(FormLabel.create(*label))
+
+            if not input:
+                raise AttributeError("input keyword argument is required")
+            children.append(input)
+
+            if help_text:
+                children.append(FormHelperText.create(*help_text))
+
+            if error_message:
+                children.append(FormErrorMessage.create(*error_message))
+
+        return super().create(*children, **props)
+
 
 class FormHelperText(ChakraComponent):
     """A form helper text component."""

+ 1 - 1
pynecone/components/forms/rangeslider.py

@@ -68,7 +68,7 @@ class RangeSlider(ChakraComponent):
         Returns:
             The RangeSlider component.
         """
-        if not children:
+        if len(children) == 0:
             children = [
                 RangeSliderTrack.create(
                     RangeSliderFilledTrack.create(),

+ 1 - 1
pynecone/components/forms/slider.py

@@ -68,7 +68,7 @@ class Slider(ChakraComponent):
         Returns:
             The slider component.
         """
-        if not children:
+        if len(children) == 0:
             children = [
                 SliderTrack.create(
                     SliderFilledTrack.create(),

+ 20 - 0
pynecone/components/layout/wrap.py

@@ -1,5 +1,6 @@
 """Container to stack elements with spacing."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -30,6 +31,25 @@ class Wrap(ChakraComponent):
     # The vertical spacing between the items.
     spacing_y: Var[str]
 
+    @classmethod
+    def create(cls, *children, items=None, **props) -> Component:
+        """Return a wrap component.
+
+        Args:
+            children: The children of the component.
+            items (list): The items of the wrap component.
+            props: The properties of the component.
+
+        Returns:
+            The wrap component.
+        """
+        if len(children) == 0:
+            children = []
+            for item in items or []:
+                children.append(WrapItem.create(*item))
+
+        return super().create(*children, **props)
+
 
 class WrapItem(ChakraComponent):
     """Item of the Wrap component."""

+ 23 - 0
pynecone/components/navigation/breadcrumb.py

@@ -1,5 +1,6 @@
 """Breadcrumb components."""
 
+from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -15,6 +16,28 @@ class Breadcrumb(ChakraComponent):
     # The left and right margin applied to the separator
     separator_margin: Var[str]
 
+    @classmethod
+    def create(cls, *children, items=None, **props) -> Component:
+        """Create a breadcrumb component.
+
+        If the kw-args `items` is provided and is a list, they will be added as children.
+
+        Args:
+            children: The children of the component.
+            items (list): The items of the breadcrumb: (label, link)
+            props: The properties of the component.
+
+        Returns:
+            The breadcrumb component.
+        """
+        if len(children) == 0:
+            children = []
+            for label, link in items or []:
+                children.append(
+                    BreadcrumbItem.create(BreadcrumbLink.create(label, href=link))
+                )
+        return super().create(*children, **props)
+
 
 class BreadcrumbItem(ChakraComponent):
     """Individual breadcrumb element containing a link and a divider."""

+ 53 - 0
pynecone/components/overlay/alertdialog.py

@@ -2,6 +2,8 @@
 
 from typing import Set
 
+from pynecone.components.component import Component
+from pynecone.components.media.icon import Icon
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
 
@@ -64,6 +66,57 @@ class AlertDialog(ChakraComponent):
             "on_overlay_click",
         }
 
+    @classmethod
+    def create(
+        cls, *children, header=None, body=None, footer=None, close_button=None, **props
+    ) -> Component:
+        """Create an alert dialog component.
+
+        Args:
+            children: The children of the alert dialog component.
+            header: The header of the alert dialog.
+            body: The body of the alert dialog.
+            footer: The footer of the alert dialog.
+            close_button: The close button of the alert dialog.
+            props: The properties of the alert dialog component.
+
+        Raises:
+            AttributeError: if there is a conflict between the props used.
+
+        Returns:
+            The alert dialog component.
+        """
+        if len(children) == 0:
+            contents = []
+
+            if header:
+                contents.append(AlertDialogHeader.create(header))
+
+            if body:
+                contents.append(AlertDialogBody.create(body))
+
+            if footer:
+                contents.append(AlertDialogFooter.create(footer))
+
+            # add AlertDialogCloseButton if either a prop for one was passed, or if on_close callback is present
+            if props.get("on_close"):
+                # get user defined close button or use default one
+                if not close_button:
+                    close_button = Icon.create(tag="CloseIcon")
+                contents.append(AlertDialogCloseButton.create(close_button))
+            elif close_button:
+                raise AttributeError(
+                    "Close button can not be used if on_close event handler is not defined"
+                )
+
+            children = [
+                AlertDialogOverlay.create(
+                    AlertDialogContent.create(*contents),
+                )
+            ]
+
+        return super().create(*children, **props)
+
 
 class AlertDialogBody(ChakraComponent):
     """Should contain the description announced by screen readers."""

+ 55 - 3
pynecone/components/overlay/drawer.py

@@ -1,8 +1,10 @@
 """Container to stack elements with spacing."""
 
 from typing import Set
+from pynecone.components.component import Component
 
 from pynecone.components.libs.chakra import ChakraComponent
+from pynecone.components.media.icon import Icon
 from pynecone.var import Var
 
 
@@ -70,6 +72,56 @@ class Drawer(ChakraComponent):
             "on_overlay_click",
         }
 
+    @classmethod
+    def create(
+        cls, *children, header=None, body=None, footer=None, close_button=None, **props
+    ) -> Component:
+        """Create a drawer component.
+
+        Args:
+            children: The children of the drawer component.
+            header: The header of the drawer.
+            body: The body of the drawer.
+            footer: The footer of the drawer.
+            close_button: The close button of the drawer.
+            props: The properties of the drawer component.
+
+        Raises:
+            AttributeError: error that occurs if conflicting props are passed
+
+        Returns:
+            The drawer component.
+        """
+        if len(children) == 0:
+            contents = []
+
+            if header:
+                contents.append(DrawerHeader.create(header))
+
+            if body:
+                contents.append(DrawerBody.create(body))
+
+            if footer:
+                contents.append(DrawerFooter.create(footer))
+
+            if props.get("on_close"):
+                # use default close button if undefined
+                if not close_button:
+                    close_button = Icon.create(tag="CloseIcon")
+                contents.append(DrawerCloseButton.create(close_button))
+            elif close_button:
+                raise AttributeError(
+                    "Close button can not be used if on_close event handler is not defined"
+                )
+
+            children = [
+                DrawerOverlay.create(
+                    DrawerContent.create(*contents),
+                )
+            ]
+
+        return super().create(*children, **props)
+
 
 class DrawerBody(ChakraComponent):
     """Drawer body."""
@@ -89,19 +141,19 @@ class DrawerFooter(ChakraComponent):
     tag = "DrawerFooter"
 
 
-class DrawerOverlay(Drawer):
+class DrawerOverlay(ChakraComponent):
     """Drawer overlay."""
 
     tag = "DrawerOverlay"
 
 
-class DrawerContent(Drawer):
+class DrawerContent(ChakraComponent):
     """Drawer content."""
 
     tag = "DrawerContent"
 
 
-class DrawerCloseButton(Drawer):
+class DrawerCloseButton(ChakraComponent):
     """Drawer close button."""
 
     tag = "DrawerCloseButton"

+ 25 - 5
pynecone/components/overlay/menu.py

@@ -1,6 +1,7 @@
 """Menu components."""
 
 from typing import Set
+from pynecone.components.component import Component
 
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
@@ -68,6 +69,25 @@ class Menu(ChakraComponent):
         """
         return super().get_triggers() | {"on_close", "on_open"}
 
+    @classmethod
+    def create(cls, *children, items=None, **props) -> Component:
+        """Create a menu component.
+
+        Args:
+            children: The children of the component.
+            items (list): The item of the menu.
+            props: The properties of the component.
+
+        Returns:
+            The menu component.
+        """
+        if len(children) == 0:
+            button = MenuButton.create(*props.pop("button"))
+            if not items:
+                items = []
+            children = [button, MenuList.create(*items)]
+        return super().create(*children, **props)
+
 
 class MenuButton(ChakraComponent):
     """The trigger for the menu list. Must be a direct child of Menu."""
@@ -87,7 +107,7 @@ class MenuList(ChakraComponent):
     tag = "MenuList"
 
 
-class MenuItem(Menu):
+class MenuItem(ChakraComponent):
     """The trigger that handles menu selection. Must be a direct child of a MenuList."""
 
     tag = "MenuItem"
@@ -108,7 +128,7 @@ class MenuItem(Menu):
     is_focusable: Var[bool]
 
 
-class MenuItemOption(Menu):
+class MenuItemOption(ChakraComponent):
     """The checkable menu item, to be used with MenuOptionGroup."""
 
     tag = "MenuItemOption"
@@ -138,13 +158,13 @@ class MenuItemOption(Menu):
     value: Var[str]
 
 
-class MenuGroup(Menu):
+class MenuGroup(ChakraComponent):
     """A wrapper to group related menu items."""
 
     tag = "MenuGroup"
 
 
-class MenuOptionGroup(Menu):
+class MenuOptionGroup(ChakraComponent):
     """A wrapper for checkable menu items (radio and checkbox)."""
 
     tag = "MenuOptionGroup"
@@ -156,7 +176,7 @@ class MenuOptionGroup(Menu):
     value: Var[str]
 
 
-class MenuDivider(Menu):
+class MenuDivider(ChakraComponent):
     """A visual separator for menu items and groups."""
 
     tag = "MenuDivider"

+ 59 - 3
pynecone/components/overlay/modal.py

@@ -1,8 +1,10 @@
 """Modal components."""
 
 from typing import Set
+from pynecone.components.component import Component
 
 from pynecone.components.libs.chakra import ChakraComponent
+from pynecone.components.media import Icon
 from pynecone.var import Var
 
 
@@ -64,8 +66,62 @@ class Modal(ChakraComponent):
             "on_overlay_click",
         }
 
+    @classmethod
+    def create(
+        cls, *children, header=None, body=None, footer=None, close_button=None, **props
+    ) -> Component:
+        """Create a modal component.
+
+        Args:
+            children: The children of the component.
+            header: The header of the modal.
+            body: The body of the modal.
+            footer: The footer of the modal.
+            close_button: The close button of the modal.
+            props: The properties of the component.
+
+        Raises:
+            AttributeError: error that occurs if conflicting props are passed
 
-class ModalOverlay(Modal):
+        Returns:
+            The modal component.
+        """
+        if len(children) == 0:
+            contents = []
+
+            # add header if present in props
+            if header:
+                contents.append(ModalHeader.create(header))
+
+            # add ModalBody if present in props
+            if body:
+                contents.append(ModalBody.create(body))
+
+            # add ModalFooter if present in props
+            if footer:
+                contents.append(ModalFooter.create(footer))
+
+            # add ModalCloseButton if either a prop for one was passed, or if
+            if props.get("on_close"):
+                # get user defined close button or use default one
+                if not close_button:
+                    close_button = Icon.create(tag="CloseIcon")
+                contents.append(ModalCloseButton.create(close_button))
+            elif close_button:
+                raise AttributeError(
+                    "Close button can not be used if on_close event handler is not defined"
+                )
+
+            children = [
+                ModalOverlay.create(
+                    ModalContent.create(*contents),
+                )
+            ]
+
+        return super().create(*children, **props)
+
+
+class ModalOverlay(ChakraComponent):
     """The dimmed overlay behind the modal dialog."""
 
     tag = "ModalOverlay"
@@ -83,7 +139,7 @@ class ModalFooter(ChakraComponent):
     tag = "ModalFooter"
 
 
-class ModalContent(Modal):
+class ModalContent(ChakraComponent):
     """The container for the modal dialog's content."""
 
     tag = "ModalContent"
@@ -95,7 +151,7 @@ class ModalBody(ChakraComponent):
     tag = "ModalBody"
 
 
-class ModalCloseButton(Modal):
+class ModalCloseButton(ChakraComponent):
     """The button that closes the modal."""
 
     tag = "ModalCloseButton"

+ 54 - 5
pynecone/components/overlay/popover.py

@@ -1,6 +1,8 @@
 """Popover components."""
 
 from typing import Set
+from pynecone.components.component import Component
+from pynecone.components.forms.button import Button
 
 from pynecone.components.libs.chakra import ChakraComponent
 from pynecone.var import Var
@@ -83,8 +85,55 @@ class Popover(ChakraComponent):
         """
         return super().get_triggers() | {"on_close", "on_open"}
 
+    @classmethod
+    def create(
+        cls,
+        *children,
+        trigger=None,
+        header=None,
+        body=None,
+        footer=None,
+        use_close_button=False,
+        **props
+    ) -> Component:
+        """Create a popover component.
+
+        Args:
+            children: The children of the component.
+            trigger: The trigger that opens the popover.
+            header: The header of the popover.
+            body: The body of the popover.
+            footer: The footer of the popover.
+            use_close_button: Whether to add a close button on the popover.
+            props: The properties of the component.
+
+        Returns:
+            The popover component.
+        """
+        if len(children) == 0:
+            contents = []
+
+            trigger = PopoverTrigger.create(trigger)
+
+            # add header if present in props
+            if header:
+                contents.append(PopoverHeader.create(header))
+
+            if body:
+                contents.append(PopoverBody.create(body))
+
+            if footer:
+                contents.append(PopoverFooter.create(footer))
+
+            if use_close_button:
+                contents.append(PopoverCloseButton.create())
+
+            children = [trigger, PopoverContent.create(*contents)]
+
+        return super().create(*children, **props)
+
 
-class PopoverContent(Popover):
+class PopoverContent(ChakraComponent):
     """The popover itself."""
 
     tag = "PopoverContent"
@@ -108,25 +157,25 @@ class PopoverBody(ChakraComponent):
     tag = "PopoverBody"
 
 
-class PopoverArrow(Popover):
+class PopoverArrow(ChakraComponent):
     """A visual arrow that points to the reference (or trigger)."""
 
     tag = "PopoverArrow"
 
 
-class PopoverCloseButton(Popover):
+class PopoverCloseButton(ChakraComponent):
     """A button to close the popover."""
 
     tag = "PopoverCloseButton"
 
 
-class PopoverAnchor(Popover):
+class PopoverAnchor(ChakraComponent):
     """Used to wrap the position-reference element."""
 
     tag = "PopoverAnchor"
 
 
-class PopoverTrigger(Popover):
+class PopoverTrigger(ChakraComponent):
     """Used to wrap the reference (or trigger) element."""
 
     tag = "PopoverTrigger"