accordion.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Container to stack elements with spacing."""
  2. from typing import List, Optional, Union
  3. from reflex.components.component import Component
  4. from reflex.components.libs.chakra import ChakraComponent
  5. from reflex.vars import Var
  6. class Accordion(ChakraComponent):
  7. """The wrapper that uses cloneElement to pass props to AccordionItem children."""
  8. tag = "Accordion"
  9. # If true, multiple accordion items can be expanded at once.
  10. allow_multiple: Var[bool]
  11. # If true, any expanded accordion item can be collapsed again.
  12. allow_toggle: Var[bool]
  13. # The initial index(es) of the expanded accordion item(s).
  14. default_index: Var[Optional[List[int]]]
  15. # The index(es) of the expanded accordion item
  16. index: Var[Union[int, List[int]]]
  17. # If true, height animation and transitions will be disabled.
  18. reduce_motion: Var[bool]
  19. @classmethod
  20. def create(
  21. cls,
  22. *children,
  23. items=None,
  24. icon_pos="right",
  25. allow_multiple: Optional[Var[bool]] = None,
  26. allow_toggle: Optional[Var[bool]] = None,
  27. **props
  28. ) -> Component:
  29. """Create an accordion component.
  30. Args:
  31. children: The children of the component.
  32. items: The items of the accordion component: list of tuples (label,panel)
  33. icon_pos: The position of the arrow icon of the accordion. "right", "left" or None
  34. allow_multiple: The allow_multiple property of the accordion. (True or False)
  35. allow_toggle: The allow_toggle property of the accordion. (True or False)
  36. props: The properties of the component.
  37. Returns:
  38. The accordion component
  39. """
  40. if len(children) == 0:
  41. children = []
  42. if not items:
  43. items = []
  44. for label, panel in items:
  45. if icon_pos == "right":
  46. button = AccordionButton.create(label, AccordionIcon.create())
  47. elif icon_pos == "left":
  48. button = AccordionButton.create(AccordionIcon.create(), label)
  49. else:
  50. button = AccordionButton.create(label)
  51. children.append(
  52. AccordionItem.create(
  53. button,
  54. AccordionPanel.create(panel),
  55. )
  56. )
  57. # if allow_multiple is True, allow_toggle is implicitely used and does not need to be defined
  58. if allow_multiple:
  59. props.update({"allow_multiple": allow_multiple})
  60. elif allow_toggle:
  61. props.update({"allow_toggle": allow_toggle})
  62. return super().create(*children, **props)
  63. class AccordionItem(ChakraComponent):
  64. """A single accordion item."""
  65. tag = "AccordionItem"
  66. # A unique id for the accordion item.
  67. id_: Var[str]
  68. # If true, the accordion item will be disabled.
  69. is_disabled: Var[bool]
  70. # If true, the accordion item will be focusable.
  71. is_focusable: Var[bool]
  72. class AccordionButton(ChakraComponent):
  73. """The button that toggles the expand/collapse state of the accordion item. This button must be wrapped in an element with role heading."""
  74. tag = "AccordionButton"
  75. class AccordionPanel(ChakraComponent):
  76. """The container for the details to be revealed."""
  77. tag = "AccordionPanel"
  78. class AccordionIcon(ChakraComponent):
  79. """A chevron-down icon that rotates based on the expanded/collapsed state."""
  80. tag = "AccordionIcon"