1
0

classes.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from typing import TYPE_CHECKING, Generic, List, Optional, TypeVar
  2. if TYPE_CHECKING:
  3. from .element import Element
  4. T = TypeVar('T', bound='Element')
  5. class Classes(list, Generic[T]):
  6. def __init__(self, *args, element: T, **kwargs) -> None:
  7. super().__init__(*args, **kwargs)
  8. self.element = element
  9. def __call__(self,
  10. add: Optional[str] = None, *,
  11. remove: Optional[str] = None,
  12. toggle: Optional[str] = None,
  13. replace: Optional[str] = None) -> T:
  14. """Apply, remove, toggle, or replace HTML classes.
  15. This allows modifying the look of the element or its layout using `Tailwind <https://v3.tailwindcss.com/>`_ or `Quasar <https://quasar.dev/>`_ classes.
  16. Removing or replacing classes can be helpful if predefined classes are not desired.
  17. :param add: whitespace-delimited string of classes
  18. :param remove: whitespace-delimited string of classes to remove from the element
  19. :param toggle: whitespace-delimited string of classes to toggle (*added in version 2.7.0*)
  20. :param replace: whitespace-delimited string of classes to use instead of existing ones
  21. """
  22. # DEPRECATED: replace Tailwind v3 link with v4 (throughout the whole codebase!) after upgrading in NiceGUI 3.0
  23. new_classes = self.update_list(self, add, remove, toggle, replace)
  24. if self != new_classes:
  25. self[:] = new_classes
  26. self.element.update()
  27. return self.element
  28. @staticmethod
  29. def update_list(classes: List[str],
  30. add: Optional[str] = None,
  31. remove: Optional[str] = None,
  32. toggle: Optional[str] = None,
  33. replace: Optional[str] = None) -> List[str]:
  34. """Update a list of classes."""
  35. class_list = classes if replace is None else []
  36. class_list = [c for c in class_list if c not in (remove or '').split()]
  37. class_list += (add or '').split()
  38. class_list += (replace or '').split()
  39. class_list = list(dict.fromkeys(class_list)) # NOTE: remove duplicates while preserving order
  40. if toggle is not None:
  41. for class_ in toggle.split():
  42. if class_ in class_list:
  43. class_list.remove(class_)
  44. else:
  45. class_list.append(class_)
  46. return class_list