Quellcode durchsuchen

Factor out responsive helpers (#624)

Nikhil Rao vor 2 Jahren
Ursprung
Commit
8ba22ed92d

+ 2 - 120
pynecone/components/__init__.py

@@ -1,10 +1,6 @@
 """Import all the components."""
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
-
-from pynecone import utils
-
 from .component import Component
 from .datadisplay import *
 from .disclosure import *
@@ -17,9 +13,6 @@ from .navigation import *
 from .overlay import *
 from .typography import *
 
-if TYPE_CHECKING:
-    from typing import Any
-
 # Add the convenience methods for all the components.
 # locals().update(
 #     {
@@ -29,6 +22,8 @@ if TYPE_CHECKING:
 #     }
 # )
 
+# Add the convenience methods for all the components manually.
+# This is necessary for static type checking to work.
 component = Component.create
 badge = Badge.create
 code = Code.create
@@ -205,116 +200,3 @@ heading = Heading.create
 markdown = Markdown.create
 span = Span.create
 text = Text.create
-
-
-# Add responsive styles shortcuts.
-def mobile_only(*children, **props):
-    """Create a component that is only visible on mobile.
-
-    Args:
-        *children: The children to pass to the component.
-        **props: The props to pass to the component.
-
-    Returns:
-        The component.
-    """
-    return Box.create(*children, **props, display=["block", "none", "none", "none"])
-
-
-def tablet_only(*children, **props):
-    """Create a component that is only visible on tablet.
-
-    Args:
-        *children: The children to pass to the component.
-        **props: The props to pass to the component.
-
-    Returns:
-        The component.
-    """
-    return Box.create(*children, **props, display=["none", "block", "block", "none"])
-
-
-def desktop_only(*children, **props):
-    """Create a component that is only visible on desktop.
-
-    Args:
-        *children: The children to pass to the component.
-        **props: The props to pass to the component.
-
-    Returns:
-        The component.
-    """
-    return Box.create(*children, **props, display=["none", "none", "none", "block"])
-
-
-def tablet_and_desktop(*children, **props):
-    """Create a component that is only visible on tablet and desktop.
-
-    Args:
-        *children: The children to pass to the component.
-        **props: The props to pass to the component.
-
-    Returns:
-        The component.
-    """
-    return Box.create(*children, **props, display=["none", "block", "block", "block"])
-
-
-def mobile_and_tablet(*children, **props):
-    """Create a component that is only visible on mobile and tablet.
-
-    Args:
-        *children: The children to pass to the component.
-        **props: The props to pass to the component.
-
-    Returns:
-        The component.
-    """
-    return Box.create(*children, **props, display=["block", "block", "block", "none"])
-
-
-def cond(condition: Any, c1: Any, c2: Any = None):
-    """Create a conditional component or Prop.
-
-    Args:
-        condition: The cond to determine which component to render.
-        c1: The component or prop to render if the cond_var is true.
-        c2: The component or prop to render if the cond_var is false.
-
-    Returns:
-        The conditional component.
-
-    Raises:
-        ValueError: If the arguments are invalid.
-    """
-    # Import here to avoid circular imports.
-    from pynecone.var import BaseVar, Var
-
-    # Convert the condition to a Var.
-    cond_var = Var.create(condition)
-    assert cond_var is not None, "The condition must be set."
-
-    # If the first component is a component, create a Cond component.
-    if isinstance(c1, Component):
-        assert c2 is None or isinstance(
-            c2, Component
-        ), "Both arguments must be components."
-        return Cond.create(cond_var, c1, c2)
-
-    # Otherwise, create a conditionl Var.
-    # Check that the second argument is valid.
-    if isinstance(c2, Component):
-        raise ValueError("Both arguments must be props.")
-    if c2 is None:
-        raise ValueError("For conditional vars, the second argument must be set.")
-
-    # Create the conditional var.
-    return BaseVar(
-        name=utils.format_cond(
-            cond=cond_var.full_name,
-            true_value=c1,
-            false_value=c2,
-            is_prop=True,
-        ),
-        type_=c1.type_ if isinstance(c1, BaseVar) else type(c1),
-    )

+ 8 - 1
pynecone/components/layout/__init__.py

@@ -2,13 +2,20 @@
 
 from .box import Box
 from .center import Center, Circle, Square
-from .cond import Cond
+from .cond import Cond, cond
 from .container import Container
 from .flex import Flex
 from .foreach import Foreach
 from .fragment import Fragment
 from .grid import Grid, GridItem, ResponsiveGrid
 from .html import Html
+from .responsive import (
+    desktop_only,
+    mobile_and_tablet,
+    mobile_only,
+    tablet_and_desktop,
+    tablet_only,
+)
 from .spacer import Spacer
 from .stack import Hstack, Stack, Vstack
 from .wrap import Wrap, WrapItem

+ 48 - 0
pynecone/components/layout/cond.py

@@ -3,6 +3,7 @@ from __future__ import annotations
 
 from typing import Any, Optional
 
+from pynecone import utils
 from pynecone.components.component import Component
 from pynecone.components.layout.fragment import Fragment
 from pynecone.components.tags import CondTag, Tag
@@ -64,3 +65,50 @@ class Cond(Component):
             false_value=self.comp2.render(),
             is_nested=self.is_nested,
         )
+
+
+def cond(condition: Any, c1: Any, c2: Any = None):
+    """Create a conditional component or Prop.
+
+    Args:
+        condition: The cond to determine which component to render.
+        c1: The component or prop to render if the cond_var is true.
+        c2: The component or prop to render if the cond_var is false.
+
+    Returns:
+        The conditional component.
+
+    Raises:
+        ValueError: If the arguments are invalid.
+    """
+    # Import here to avoid circular imports.
+    from pynecone.var import BaseVar, Var
+
+    # Convert the condition to a Var.
+    cond_var = Var.create(condition)
+    assert cond_var is not None, "The condition must be set."
+
+    # If the first component is a component, create a Cond component.
+    if isinstance(c1, Component):
+        assert c2 is None or isinstance(
+            c2, Component
+        ), "Both arguments must be components."
+        return Cond.create(cond_var, c1, c2)
+
+    # Otherwise, create a conditionl Var.
+    # Check that the second argument is valid.
+    if isinstance(c2, Component):
+        raise ValueError("Both arguments must be props.")
+    if c2 is None:
+        raise ValueError("For conditional vars, the second argument must be set.")
+
+    # Create the conditional var.
+    return BaseVar(
+        name=utils.format_cond(
+            cond=cond_var.full_name,
+            true_value=c1,
+            false_value=c2,
+            is_prop=True,
+        ),
+        type_=c1.type_ if isinstance(c1, BaseVar) else type(c1),
+    )

+ 69 - 0
pynecone/components/layout/responsive.py

@@ -0,0 +1,69 @@
+"""Responsive components."""
+
+from pynecone.components.layout.box import Box
+
+
+# Add responsive styles shortcuts.
+def mobile_only(*children, **props):
+    """Create a component that is only visible on mobile.
+
+    Args:
+        *children: The children to pass to the component.
+        **props: The props to pass to the component.
+
+    Returns:
+        The component.
+    """
+    return Box.create(*children, **props, display=["block", "none", "none", "none"])
+
+
+def tablet_only(*children, **props):
+    """Create a component that is only visible on tablet.
+
+    Args:
+        *children: The children to pass to the component.
+        **props: The props to pass to the component.
+
+    Returns:
+        The component.
+    """
+    return Box.create(*children, **props, display=["none", "block", "block", "none"])
+
+
+def desktop_only(*children, **props):
+    """Create a component that is only visible on desktop.
+
+    Args:
+        *children: The children to pass to the component.
+        **props: The props to pass to the component.
+
+    Returns:
+        The component.
+    """
+    return Box.create(*children, **props, display=["none", "none", "none", "block"])
+
+
+def tablet_and_desktop(*children, **props):
+    """Create a component that is only visible on tablet and desktop.
+
+    Args:
+        *children: The children to pass to the component.
+        **props: The props to pass to the component.
+
+    Returns:
+        The component.
+    """
+    return Box.create(*children, **props, display=["none", "block", "block", "block"])
+
+
+def mobile_and_tablet(*children, **props):
+    """Create a component that is only visible on mobile and tablet.
+
+    Args:
+        *children: The children to pass to the component.
+        **props: The props to pass to the component.
+
+    Returns:
+        The component.
+    """
+    return Box.create(*children, **props, display=["block", "block", "block", "none"])

+ 1 - 2
tests/components/layout/test_cond.py

@@ -4,8 +4,7 @@ from typing import Any
 import pytest
 
 import pynecone as pc
-from pynecone.components import cond
-from pynecone.components.layout.cond import Cond
+from pynecone.components.layout.cond import Cond, cond
 from pynecone.components.layout.fragment import Fragment
 from pynecone.components.typography.text import Text
 from pynecone.var import Var