Source code for duck.html.components.utils.include

"""
Module containing function for including bulk HTML components in a module.
"""
import inspect

from typing import List, Dict
from functools import lru_cache

from duck.html.components import HtmlComponent
from duck.utils.string import is_pascal_case
from duck.utils.importer import import_module_once


BASE_MODULE = "duck.html.components"
BUILTIN_COMPONENTS = [
    f"{BASE_MODULE}.{module}" for module in [
        "page",
        "paragraph",
        "heading",
        "snackbar",
        "progressbar",
        "section",
        "card",
        "icon",
        "link",
        "form",
        "script",
        "style",
        "input",
        "textarea",
        "select",
        "image",
        "video",
        "hero",
        "container",
        "checkbox",
        "navbar",
        "footer",
        "button",
        "modal",
        "lively",
        "code",
        "label",
        "fileinput",
        "table_of_contents",
    ]
]


[docs] @lru_cache def components_include(modules: List[str]) -> Dict[str, str]: """ This looks up HTML components in the provided modules and returns a dictionary containing the components found. Args: modules (List[str]): The list of module names containing HTML components in PascalCase. Returns: Dict[str, str]: A dictionary mapping component names to their full module path. """ from duck.html.components import ComponentError components = {} for mod_name in modules: try: mod = import_module_once(mod_name) # Ensure module is imported except Exception as e: raise ComponentError(f"Error importing component library '{mod_name}': {e} ") if not mod: continue # Skip if import fails for attr_name in dir(mod): if is_pascal_case(attr_name): # Ensure it's PascalCase cls = getattr(mod, attr_name) if inspect.isclass(cls) and issubclass(cls, HtmlComponent): components[attr_name] = f"{mod_name}.{attr_name}" # Correct dictionary assignment return components