cond.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. """Create a list of components from an iterable."""
  2. from __future__ import annotations
  3. from typing import Any, TypeVar, Union, overload
  4. from reflex.components.base.fragment import Fragment
  5. from reflex.components.component import BaseComponent, Component
  6. from reflex.style import LIGHT_COLOR_MODE, resolved_color_mode
  7. from reflex.utils import types
  8. from reflex.vars.base import LiteralVar, Var
  9. from reflex.vars.number import ternary_operation
  10. @overload
  11. def cond(
  12. condition: Any, c1: BaseComponent | Var[BaseComponent], c2: Any = None, /
  13. ) -> Var[Component]: ...
  14. T = TypeVar("T")
  15. V = TypeVar("V")
  16. @overload
  17. def cond(condition: Any, c1: T | Var[T], c2: V | Var[V], /) -> Var[T | V]: ...
  18. def cond(condition: Any, c1: Any, c2: Any = None, /) -> Var:
  19. """Create a conditional component or Prop.
  20. Args:
  21. condition: The cond to determine which component to render.
  22. c1: The component or prop to render if the cond_var is true.
  23. c2: The component or prop to render if the cond_var is false.
  24. Returns:
  25. The conditional component.
  26. Raises:
  27. ValueError: If the arguments are invalid.
  28. """
  29. # Convert the condition to a Var.
  30. cond_var = LiteralVar.create(condition)
  31. # If the first component is a component, create a Fragment if the second component is not set.
  32. if isinstance(c1, BaseComponent) or (
  33. isinstance(c1, Var)
  34. and types.safe_typehint_issubclass(
  35. c1._var_type, Union[BaseComponent, list[BaseComponent]]
  36. )
  37. ):
  38. c2 = c2 if c2 is not None else Fragment.create()
  39. # Check that the second argument is valid.
  40. if c2 is None:
  41. raise ValueError("For conditional vars, the second argument must be set.")
  42. # Create the conditional var.
  43. return ternary_operation(
  44. cond_var.bool(),
  45. c1,
  46. c2,
  47. )
  48. @overload
  49. def color_mode_cond(
  50. light: BaseComponent | Var[BaseComponent],
  51. dark: BaseComponent | Var[BaseComponent] | None = ...,
  52. ) -> Var[Component]: ...
  53. @overload
  54. def color_mode_cond(light: T | Var[T], dark: V | Var[V]) -> Var[T | V]: ...
  55. def color_mode_cond(light: Any, dark: Any = None) -> Var:
  56. """Create a component or Prop based on color_mode.
  57. Args:
  58. light: The component or prop to render if color_mode is default
  59. dark: The component or prop to render if color_mode is non-default
  60. Returns:
  61. The conditional component or prop.
  62. """
  63. return cond(
  64. resolved_color_mode == LiteralVar.create(LIGHT_COLOR_MODE),
  65. light,
  66. dark,
  67. )
  68. class Cond:
  69. """Create a conditional component or Prop."""
  70. create = staticmethod(cond)