reflex/pynecone/components/layout/foreach.py
2022-11-18 12:44:06 -08:00

63 lines
1.7 KiB
Python

"""Create a list of components from an iterable."""
from __future__ import annotations
from typing import Any, List, Protocol, runtime_checkable
from pynecone.components.component import Component
from pynecone.components.tags import IterTag, Tag
from pynecone.var import BaseVar, Var
@runtime_checkable
class RenderFn(Protocol):
"""A function that renders a component."""
def __call__(self, *args, **kwargs) -> Component:
"""Render a component.
Args:
*args: The positional arguments.
**kwargs: The keyword arguments.
Returns: # noqa: DAR202
The rendered component.
"""
...
class Foreach(Component):
"""Display a foreach."""
# The iterable to create components from.
iterable: Var[List]
# A function from the render args to the component.
render_fn: RenderFn
@classmethod
def create(cls, iterable: Var[List], render_fn: RenderFn, **props) -> Foreach:
"""Create a foreach component.
Args:
iterable: The iterable to create components from.
render_fn: A function from the render args to the component.
**props: The attributes to pass to each child component.
Returns:
The foreach component.
"""
try:
type_ = iterable.type_.__args__[0]
except:
type_ = Any
arg = BaseVar(name="_", type_=type_, is_local=True)
return cls(
iterable=iterable,
render_fn=render_fn,
children=[IterTag.render_component(render_fn, arg=arg)],
**props,
)
def _render(self) -> Tag:
return IterTag(iterable=self.iterable, render_fn=self.render_fn)