tabs.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. """Interactive components provided by @radix-ui/themes."""
  2. from __future__ import annotations
  3. from typing import Any, Dict, List, Literal
  4. from reflex.components.component import Component, ComponentNamespace
  5. from reflex.components.core.breakpoints import Responsive
  6. from reflex.components.core.colors import color
  7. from reflex.event import EventHandler, passthrough_event_spec
  8. from reflex.vars.base import Var
  9. from ..base import LiteralAccentColor, RadixThemesComponent
  10. vertical_orientation_css = "&[data-orientation='vertical']"
  11. class TabsRoot(RadixThemesComponent):
  12. """Set of content sections to be displayed one at a time."""
  13. tag = "Tabs.Root"
  14. # The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs.
  15. default_value: Var[str]
  16. # The controlled value of the tab that should be active. Use when you need to control the state of the tabs.
  17. value: Var[str]
  18. # The orientation of the tabs.
  19. orientation: Var[Literal["horizontal", "vertical"]]
  20. # Reading direction of the tabs.
  21. dir: Var[Literal["ltr", "rtl"]]
  22. # The mode of activation for the tabs. "automatic" will activate the tab when focused. "manual" will activate the tab when clicked.
  23. activation_mode: Var[Literal["automatic", "manual"]]
  24. # Props to rename
  25. _rename_props = {"onChange": "onValueChange"}
  26. # Fired when the value of the tabs changes.
  27. on_change: EventHandler[passthrough_event_spec(str)]
  28. def add_style(self) -> Dict[str, Any] | None:
  29. """Add style for the component.
  30. Returns:
  31. The style to add.
  32. """
  33. return {
  34. vertical_orientation_css: {
  35. "display": "flex",
  36. }
  37. }
  38. class TabsList(RadixThemesComponent):
  39. """Contains the triggers that sit alongside the active content."""
  40. tag = "Tabs.List"
  41. # Tabs size "1" - "2"
  42. size: Var[Responsive[Literal["1", "2"]]]
  43. # When true, the tabs will loop when reaching the end.
  44. loop: Var[bool]
  45. def add_style(self):
  46. """Add style for the component.
  47. Returns:
  48. The style to add.
  49. """
  50. return {
  51. vertical_orientation_css: {
  52. "display": "block",
  53. "box_shadow": f"inset -1px 0 0 0 {color('gray', 5, alpha=True)}",
  54. },
  55. }
  56. class TabsTrigger(RadixThemesComponent):
  57. """The button that activates its associated content."""
  58. tag = "Tabs.Trigger"
  59. # The value of the tab. Must be unique for each tab.
  60. value: Var[str]
  61. # Whether the tab is disabled
  62. disabled: Var[bool]
  63. # The color of the line under the tab when active.
  64. color_scheme: Var[LiteralAccentColor]
  65. _valid_parents: List[str] = ["TabsList"]
  66. @classmethod
  67. def create(cls, *children, **props) -> Component:
  68. """Create a TabsTrigger component.
  69. Args:
  70. *children: The children of the component.
  71. **props: The properties of the component.
  72. Returns:
  73. The TabsTrigger Component.
  74. """
  75. if "color_scheme" in props:
  76. custom_attrs = props.setdefault("custom_attrs", {})
  77. custom_attrs["data-accent-color"] = props["color_scheme"]
  78. return super().create(*children, **props)
  79. def _exclude_props(self) -> list[str]:
  80. return ["color_scheme"]
  81. def add_style(self) -> Dict[str, Any] | None:
  82. """Add style for the component.
  83. Returns:
  84. The style to add.
  85. """
  86. return {vertical_orientation_css: {"width": "100%"}}
  87. class TabsContent(RadixThemesComponent):
  88. """Contains the content associated with each trigger."""
  89. tag = "Tabs.Content"
  90. # The value of the tab. Must be unique for each tab.
  91. value: Var[str]
  92. # Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
  93. force_mount: Var[bool]
  94. def add_style(self) -> dict[str, Any] | None:
  95. """Add style for the component.
  96. Returns:
  97. The style to add.
  98. """
  99. return {
  100. vertical_orientation_css: {"width": "100%", "margin": None},
  101. }
  102. class Tabs(ComponentNamespace):
  103. """Set of content sections to be displayed one at a time."""
  104. root = __call__ = staticmethod(TabsRoot.create)
  105. list = staticmethod(TabsList.create)
  106. trigger = staticmethod(TabsTrigger.create)
  107. content = staticmethod(TabsContent.create)
  108. tabs = Tabs()