Source code for quirl.components

"""
Modern UI components for Duck Framework's Lively system.

Components are lazily imported on first access (PEP 562), so
`import quirl.components` stays cheap no matter how many components
the pack grows to — only the submodule you actually touch gets loaded.

Adding a new component only requires one entry in COMPONENT_GROUPS
below; no top-level import statement needed. A submodule that exports
several components together (e.g. carousel.py's MarqueeCarousel and
SliderCarousel) lists them as a group — importing any one of them
caches all of them, since they came from the same import anyway.
"""

import importlib


# Maps submodule -> the public component names it exports
COMPONENT_GROUPS = {
    "badge": ["Badge"],
    "avatar": ["Avatar"],
    "alert": ["Alert"],
    "skeleton": ["Skeleton"],
    "tag": ["Tag"],
    "spinner": ["Spinner"],
    "divider": ["Divider"],
    "code": ["CodeBlock", "EditableCodeBlock"],
    "animation.demo": ["Demo"],
    "documentor": ["Documentor"],
    "carousel": ["MarqueeCarousel", "SliderCarousel"],
    "image": ["SmartImage", "CircularSmartImage", "SmartImagePlaceholder"],
}

# Reverse lookup built once: public name -> its submodule
NAME_TO_MODULE = {
    name: module_path
    for module_path, names in COMPONENT_GROUPS.items()
    for name in names
}


__all__ = list(NAME_TO_MODULE)


[docs] def __getattr__(name: str): """ Lazily import a component's submodule and cache its whole group. Args: name: The attribute being accessed, e.g. "MarqueeCarousel". Returns: The requested component class. Raises: AttributeError: If name isn't a known component. """ module_path = NAME_TO_MODULE.get(name) if module_path is None: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") module = importlib.import_module(f".{module_path}", __name__) # Cache every name this submodule exports, not just the one requested for exported_name in COMPONENT_GROUPS[module_path]: globals()[exported_name] = getattr(module, exported_name) # Add name to globals return globals()[name]
[docs] def __dir__(): """ Report the public component names for tab-completion and dir(). """ return sorted(__all__)