cond.py 2.8 KB

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