123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- """List components."""
- from __future__ import annotations
- from collections.abc import Iterable
- from typing import Any, Literal
- from reflex.components.component import Component, ComponentNamespace
- from reflex.components.core.foreach import Foreach
- from reflex.components.el.elements.typography import Li, Ol, Ul
- from reflex.components.lucide.icon import Icon
- from reflex.components.markdown.markdown import MarkdownComponentMap
- from reflex.components.radix.themes.typography.text import Text
- from reflex.vars.base import Var
- LiteralListStyleTypeUnordered = Literal[
- "none",
- "disc",
- "circle",
- "square",
- ]
- LiteralListStyleTypeOrdered = Literal[
- "none",
- "decimal",
- "decimal-leading-zero",
- "lower-roman",
- "upper-roman",
- "lower-greek",
- "lower-latin",
- "upper-latin",
- "armenian",
- "georgian",
- "lower-alpha",
- "upper-alpha",
- "hiragana",
- "katakana",
- ]
- class BaseList(Component, MarkdownComponentMap):
- """Base class for ordered and unordered lists."""
- tag = "ul"
- # The style of the list. Default to "none".
- list_style_type: Var[
- LiteralListStyleTypeUnordered | LiteralListStyleTypeOrdered
- ] = Var.create("none")
- # A list of items to add to the list.
- items: Var[Iterable] = Var.create([])
- @classmethod
- def create(
- cls,
- *children,
- **props,
- ):
- """Create a list component.
- Args:
- *children: The children of the component.
- **props: The properties of the component.
- Returns:
- The list component.
- """
- items = props.pop("items", None)
- list_style_type = props.pop("list_style_type", "none")
- if not children and items is not None:
- if isinstance(items, Var):
- children = [Foreach.create(items, ListItem.create)]
- else:
- children = [ListItem.create(item) for item in items]
- props["direction"] = "column"
- style = props.setdefault("style", {})
- style["list_style_type"] = list_style_type
- if "gap" in props:
- style["gap"] = props["gap"]
- return super().create(*children, **props)
- def add_style(self) -> dict[str, Any] | None:
- """Add style to the component.
- Returns:
- The style of the component.
- """
- return {
- "direction": "column",
- }
- def _exclude_props(self) -> list[str]:
- return ["items", "list_style_type"]
- class UnorderedList(BaseList, Ul):
- """Display an unordered list."""
- tag = "ul"
- @classmethod
- def create(
- cls,
- *children,
- **props,
- ):
- """Create an unordered list component.
- Args:
- *children: The children of the component.
- **props: The properties of the component.
- Returns:
- The list component.
- """
- items = props.pop("items", None)
- list_style_type = props.pop("list_style_type", "disc")
- props["margin_left"] = props.get("margin_left", "1.5rem")
- return super().create(
- *children, items=items, list_style_type=list_style_type, **props
- )
- class OrderedList(BaseList, Ol):
- """Display an ordered list."""
- tag = "ol"
- @classmethod
- def create(
- cls,
- *children,
- **props,
- ):
- """Create an ordered list component.
- Args:
- *children: The children of the component.
- **props: The properties of the component.
- Returns:
- The list component.
- """
- items = props.pop("items", None)
- list_style_type = props.pop("list_style_type", "decimal")
- props["margin_left"] = props.get("margin_left", "1.5rem")
- return super().create(
- *children, items=items, list_style_type=list_style_type, **props
- )
- class ListItem(Li, MarkdownComponentMap):
- """Display an item of an ordered or unordered list."""
- @classmethod
- def create(cls, *children, **props):
- """Create a list item component.
- Args:
- *children: The children of the component.
- **props: The properties of the component.
- Returns:
- The list item component.
- """
- for child in children:
- if isinstance(child, Text):
- child.as_ = "span"
- elif isinstance(child, Icon) and "display" not in child.style:
- child.style["display"] = "inline"
- return super().create(*children, **props)
- class List(ComponentNamespace):
- """List components."""
- item = staticmethod(ListItem.create)
- ordered = staticmethod(OrderedList.create)
- unordered = staticmethod(UnorderedList.create)
- __call__ = staticmethod(BaseList.create)
- list_ns = List()
- list_item = list_ns.item
- ordered_list = list_ns.ordered
- unordered_list = list_ns.unordered
- def __getattr__(name: Any):
- # special case for when accessing list to avoid shadowing
- # python's built in list object.
- if name == "list":
- return list_ns
- try:
- return globals()[name]
- except KeyError:
- raise AttributeError(f"module '{__name__} has no attribute '{name}'") from None
|