Factor out responsive helpers (#624)
This commit is contained in:
parent
b751260276
commit
8ba22ed92d
@ -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),
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
pynecone/components/layout/responsive.py
Normal file
69
pynecone/components/layout/responsive.py
Normal file
@ -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"])
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user