Source code for dash_prism.icons

"""Icon utilities for dash_prism.

This module provides access to the available icon names that can be used
with :class:`Action` and tab icons in :class:`Prism`.

The icon list is defined in ``src/icons.json`` (single source of truth)
and copied to the package during build.
"""

from __future__ import annotations

import json
from functools import lru_cache
from pathlib import Path
from typing import List


@lru_cache(maxsize=1)
def _load_icons() -> frozenset[str]:
    """Load available icons from icons.json.

    :returns: Frozen set of available icon names.
    :rtype: frozenset[str]
    """
    icons_path = Path(__file__).parent / "icons.json"
    if not icons_path.exists():
        # Fallback for development when icons.json hasn't been copied
        icons_path = Path(__file__).parent.parent / "src" / "icons.json"

    if not icons_path.exists():
        raise FileNotFoundError(
            f"icons.json not found. Expected at {icons_path}. "
            "Run 'npm run build' to generate it."
        )

    with icons_path.open("r", encoding="utf-8") as f:
        data = json.load(f)

    return frozenset(data["icons"])


def _get_available_icons_set() -> frozenset[str]:
    """Get the frozen set of available icons (lazy-loaded).

    :returns: Frozen set of available icon names.
    :rtype: frozenset[str]
    """
    return _load_icons()


[docs] def get_available_icons() -> List[str]: """Get a sorted list of available icon names. These icons can be used with the ``icon`` parameter of :class:`Action` and for tab icons in :class:`Prism`. Icons are from a curated subset of `lucide-react <https://lucide.dev/icons>`_. :returns: Sorted list of available icon names. :rtype: list[str] .. rubric:: Example .. code-block:: python import dash_prism # Print all available icons for icon in dash_prism.get_available_icons(): print(icon) # Check if an icon is available if 'Rocket' in dash_prism.AVAILABLE_ICONS: print('Rocket icon is available!') .. seealso:: :data:`AVAILABLE_ICONS` Frozen set for membership testing. :class:`Action` Action component that uses icons. """ return sorted(_get_available_icons_set())
# Module-level constant for convenient access # Note: This is loaded lazily on first access to avoid import-time file I/O class _AvailableIconsProxy: """Lazy proxy for AVAILABLE_ICONS to defer file loading until first use.""" _icons: frozenset[str] | None = None def _load(self) -> frozenset[str]: if self._icons is None: self._icons = _load_icons() return self._icons def __contains__(self, item: object) -> bool: return item in self._load() def __iter__(self): return iter(self._load()) def __len__(self) -> int: return len(self._load()) def __repr__(self) -> str: return f"frozenset({sorted(self._load())!r})" #: Frozen set of all available icon names. #: Icons are from a curated subset of `lucide-react <https://lucide.dev/icons>`_. #: #: Use for membership testing:: #: #: if 'Rocket' in dash_prism.AVAILABLE_ICONS: #: print('Available!') #: #: For a sorted list, use :func:`get_available_icons`. AVAILABLE_ICONS: frozenset[str] = _AvailableIconsProxy() # type: ignore[assignment]