Factor out responsive helpers (#624)
This commit is contained in:
parent
b751260276
commit
8ba22ed92d
@ -1,10 +1,6 @@
|
|||||||
"""Import all the components."""
|
"""Import all the components."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from pynecone import utils
|
|
||||||
|
|
||||||
from .component import Component
|
from .component import Component
|
||||||
from .datadisplay import *
|
from .datadisplay import *
|
||||||
from .disclosure import *
|
from .disclosure import *
|
||||||
@ -17,9 +13,6 @@ from .navigation import *
|
|||||||
from .overlay import *
|
from .overlay import *
|
||||||
from .typography import *
|
from .typography import *
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
# Add the convenience methods for all the components.
|
# Add the convenience methods for all the components.
|
||||||
# locals().update(
|
# 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
|
component = Component.create
|
||||||
badge = Badge.create
|
badge = Badge.create
|
||||||
code = Code.create
|
code = Code.create
|
||||||
@ -205,116 +200,3 @@ heading = Heading.create
|
|||||||
markdown = Markdown.create
|
markdown = Markdown.create
|
||||||
span = Span.create
|
span = Span.create
|
||||||
text = Text.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 .box import Box
|
||||||
from .center import Center, Circle, Square
|
from .center import Center, Circle, Square
|
||||||
from .cond import Cond
|
from .cond import Cond, cond
|
||||||
from .container import Container
|
from .container import Container
|
||||||
from .flex import Flex
|
from .flex import Flex
|
||||||
from .foreach import Foreach
|
from .foreach import Foreach
|
||||||
from .fragment import Fragment
|
from .fragment import Fragment
|
||||||
from .grid import Grid, GridItem, ResponsiveGrid
|
from .grid import Grid, GridItem, ResponsiveGrid
|
||||||
from .html import Html
|
from .html import Html
|
||||||
|
from .responsive import (
|
||||||
|
desktop_only,
|
||||||
|
mobile_and_tablet,
|
||||||
|
mobile_only,
|
||||||
|
tablet_and_desktop,
|
||||||
|
tablet_only,
|
||||||
|
)
|
||||||
from .spacer import Spacer
|
from .spacer import Spacer
|
||||||
from .stack import Hstack, Stack, Vstack
|
from .stack import Hstack, Stack, Vstack
|
||||||
from .wrap import Wrap, WrapItem
|
from .wrap import Wrap, WrapItem
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from pynecone import utils
|
||||||
from pynecone.components.component import Component
|
from pynecone.components.component import Component
|
||||||
from pynecone.components.layout.fragment import Fragment
|
from pynecone.components.layout.fragment import Fragment
|
||||||
from pynecone.components.tags import CondTag, Tag
|
from pynecone.components.tags import CondTag, Tag
|
||||||
@ -64,3 +65,50 @@ class Cond(Component):
|
|||||||
false_value=self.comp2.render(),
|
false_value=self.comp2.render(),
|
||||||
is_nested=self.is_nested,
|
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 pytest
|
||||||
|
|
||||||
import pynecone as pc
|
import pynecone as pc
|
||||||
from pynecone.components import cond
|
from pynecone.components.layout.cond import Cond, cond
|
||||||
from pynecone.components.layout.cond import Cond
|
|
||||||
from pynecone.components.layout.fragment import Fragment
|
from pynecone.components.layout.fragment import Fragment
|
||||||
from pynecone.components.typography.text import Text
|
from pynecone.components.typography.text import Text
|
||||||
from pynecone.var import Var
|
from pynecone.var import Var
|
||||||
|
Loading…
Reference in New Issue
Block a user