table.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. """Table components."""
  2. from typing import List
  3. from reflex.components.component import Component
  4. from reflex.components.layout.foreach import Foreach
  5. from reflex.components.libs.chakra import ChakraComponent
  6. from reflex.vars import Var
  7. class Table(ChakraComponent):
  8. """A table component."""
  9. tag = "Table"
  10. # The color scheme of the table
  11. color_scheme: Var[str]
  12. # The variant of the table style to use
  13. variant: Var[str]
  14. # The size of the table
  15. size: Var[str]
  16. # The placement of the table caption.
  17. placement: Var[str]
  18. @classmethod
  19. def create(
  20. cls, *children, caption=None, headers=None, rows=None, footers=None, **props
  21. ) -> Component:
  22. """Create a table component.
  23. Args:
  24. children: The children of the component.
  25. caption: The caption of the table component.
  26. headers: The headers of the table component.
  27. rows: The rows of the table component.
  28. footers: The footers of the table component.
  29. props: The properties of the component.
  30. Returns:
  31. The table component.
  32. """
  33. if len(children) == 0:
  34. children = []
  35. if caption:
  36. children.append(TableCaption.create(caption))
  37. if headers:
  38. children.append(Thead.create(headers=headers))
  39. if rows:
  40. children.append(Tbody.create(rows=rows))
  41. if footers:
  42. children.append(Tfoot.create(footers=footers))
  43. return super().create(*children, **props)
  44. class Thead(ChakraComponent):
  45. """A table header component."""
  46. tag = "Thead"
  47. # invalid children components
  48. invalid_children: List[str] = ["Tbody", "Thead", "Tfoot"]
  49. @classmethod
  50. def create(cls, *children, headers=None, **props) -> Component:
  51. """Create a table header component.
  52. Args:
  53. children: The children of the component.
  54. props: The properties of the component.
  55. headers (list, optional): List of headers. Defaults to None.
  56. Returns:
  57. The table header component.
  58. """
  59. if len(children) == 0:
  60. children = [Tr.create(cell_type="header", cells=headers)]
  61. return super().create(*children, **props)
  62. class Tbody(ChakraComponent):
  63. """A table body component."""
  64. tag = "Tbody"
  65. # invalid children components
  66. invalid_children: List[str] = ["Tbody", "Thead", "Tfoot", "Td", "Th"]
  67. @classmethod
  68. def create(cls, *children, rows=None, **props) -> Component:
  69. """Create a table body component.
  70. Args:
  71. children: The children of the component.
  72. props: The properties of the component.
  73. rows (list[list], optional): The rows of the table body. Defaults to None.
  74. Returns:
  75. Component: _description_
  76. """
  77. if len(children) == 0:
  78. children = [Tr.create(cell_type="data", cells=row) for row in rows or []]
  79. return super().create(*children, **props)
  80. class Tfoot(ChakraComponent):
  81. """A table footer component."""
  82. tag = "Tfoot"
  83. # invalid children components
  84. invalid_children: List[str] = ["Tbody", "Thead", "Td", "Th", "Tfoot"]
  85. @classmethod
  86. def create(cls, *children, footers=None, **props) -> Component:
  87. """Create a table footer component.
  88. Args:
  89. children: The children of the component.
  90. props: The properties of the component.
  91. footers (list, optional): List of footers. Defaults to None.
  92. Returns:
  93. The table footer component.
  94. """
  95. if len(children) == 0:
  96. children = [Tr.create(cell_type="header", cells=footers)]
  97. return super().create(*children, **props)
  98. class Tr(ChakraComponent):
  99. """A table row component."""
  100. tag = "Tr"
  101. # invalid children components
  102. invalid_children: List[str] = ["Tbody", "Thead", "Tfoot", "Tr"]
  103. @classmethod
  104. def create(cls, *children, cell_type: str = "", cells=None, **props) -> Component:
  105. """Create a table row component.
  106. Args:
  107. children: The children of the component.
  108. props: The properties of the component.
  109. cell_type (str): the type of cells in this table row. "header" or "data". Defaults to None.
  110. cells (list, optional): The cells value to add in the table row. Defaults to None.
  111. Returns:
  112. The table row component
  113. """
  114. types = {"header": Th, "data": Td}
  115. cell_cls = types.get(cell_type)
  116. if len(children) == 0 and cell_cls:
  117. if isinstance(cells, Var):
  118. children = [Foreach.create(cells, cell_cls.create)]
  119. else:
  120. children = [cell_cls.create(cell) for cell in cells or []]
  121. return super().create(*children, **props)
  122. class Th(ChakraComponent):
  123. """A table header cell component."""
  124. tag = "Th"
  125. # invalid children components
  126. invalid_children: List[str] = ["Tbody", "Thead", "Tr", "Td", "Th"]
  127. # Aligns the cell content to the right.
  128. is_numeric: Var[bool]
  129. class Td(ChakraComponent):
  130. """A table data cell component."""
  131. tag = "Td"
  132. # invalid children components
  133. invalid_children: List[str] = ["Tbody", "Thead"]
  134. # Aligns the cell content to the right.
  135. is_numeric: Var[bool]
  136. class TableCaption(ChakraComponent):
  137. """A table caption component."""
  138. tag = "TableCaption"
  139. # The placement of the table caption. This sets the `caption-side` CSS attribute.
  140. placement: Var[str]
  141. class TableContainer(ChakraComponent):
  142. """The table container component renders a div that wraps the table component."""
  143. tag = "TableContainer"