popover.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. """Popover components."""
  2. from __future__ import annotations
  3. from reflex.components.chakra import (
  4. ChakraComponent,
  5. LiteralChakraDirection,
  6. LiteralMenuStrategy,
  7. LiteralPopOverTrigger,
  8. )
  9. from reflex.components.component import Component
  10. from reflex.event import EventHandler
  11. from reflex.vars import Var
  12. class Popover(ChakraComponent):
  13. """The wrapper that provides props, state, and context to its children."""
  14. tag = "Popover"
  15. # The padding required to prevent the arrow from reaching the very edge of the popper.
  16. arrow_padding: Var[int]
  17. # The `box-shadow` of the popover arrow
  18. arrow_shadow_color: Var[str]
  19. # The size of the popover arrow
  20. arrow_size: Var[int]
  21. # If true, focus will be transferred to the first interactive element when the popover opens
  22. auto_focus: Var[bool]
  23. # The boundary area for the popper. Used within the preventOverflow modifier
  24. boundary: Var[str]
  25. # If true, the popover will close when you blur out it by clicking outside or tabbing out
  26. close_on_blur: Var[bool]
  27. # If true, the popover will close when you hit the Esc key
  28. close_on_esc: Var[bool]
  29. # If true, the popover will be initially opened.
  30. default_is_open: Var[bool]
  31. # Theme direction ltr or rtl. Popper's placement will be set accordingly
  32. direction: Var[LiteralChakraDirection]
  33. # If true, the popper will change its placement and flip when it's about to overflow its boundary area.
  34. flip: Var[bool]
  35. # The distance or margin between the reference and popper. It is used internally to create an offset modifier. NB: If you define offset prop, it'll override the gutter.
  36. gutter: Var[int]
  37. # The html id attribute of the popover. If not provided, we generate a unique id. This id is also used to auto-generate the `aria-labelledby` and `aria-describedby` attributes that points to the PopoverHeader and PopoverBody
  38. id_: Var[str]
  39. # Performance 🚀: If true, the PopoverContent rendering will be deferred until the popover is open.
  40. is_lazy: Var[bool]
  41. # Performance 🚀: The lazy behavior of popover's content when not visible. Only works when `isLazy={true}` - "unmount": The popover's content is always unmounted when not open. - "keepMounted": The popover's content initially unmounted, but stays mounted when popover is open.
  42. lazy_behavior: Var[str]
  43. # If true, the popover will be opened in controlled mode.
  44. is_open: Var[bool]
  45. # If true, the popper will match the width of the reference at all times. It's useful for autocomplete, `date-picker` and select patterns.
  46. match_width: Var[bool]
  47. # The placement of the popover. It's used internally by Popper.js.
  48. placement: Var[str]
  49. # If true, will prevent the popper from being cut off and ensure it's visible within the boundary area.
  50. prevent_overflow: Var[bool]
  51. # If true, focus will be returned to the element that triggers the popover when it closes
  52. return_focus_on_close: Var[bool]
  53. # The CSS positioning strategy to use. ("fixed" | "absolute")
  54. strategy: Var[LiteralMenuStrategy]
  55. # The interaction that triggers the popover. hover - means the popover will open when you hover with mouse or focus with keyboard on the popover trigger click - means the popover will open on click or press Enter to Space on keyboard ("click" | "hover")
  56. trigger: Var[LiteralPopOverTrigger]
  57. # Fired when the popover is closed.
  58. on_close: EventHandler[lambda: []]
  59. # Fired when the popover is opened.
  60. on_open: EventHandler[lambda: []]
  61. @classmethod
  62. def create(
  63. cls,
  64. *children,
  65. trigger=None,
  66. header=None,
  67. body=None,
  68. footer=None,
  69. use_close_button=False,
  70. **props,
  71. ) -> Component:
  72. """Create a popover component.
  73. Args:
  74. *children: The children of the component.
  75. trigger: The trigger that opens the popover.
  76. header: The header of the popover.
  77. body: The body of the popover.
  78. footer: The footer of the popover.
  79. use_close_button: Whether to add a close button on the popover.
  80. **props: The properties of the component.
  81. Returns:
  82. The popover component.
  83. """
  84. if len(children) == 0:
  85. contents = []
  86. trigger = PopoverTrigger.create(trigger)
  87. # add header if present in props
  88. if header:
  89. contents.append(PopoverHeader.create(header))
  90. if body:
  91. contents.append(PopoverBody.create(body))
  92. if footer:
  93. contents.append(PopoverFooter.create(footer))
  94. if use_close_button:
  95. contents.append(PopoverCloseButton.create())
  96. children = [trigger, PopoverContent.create(*contents)]
  97. return super().create(*children, **props)
  98. class PopoverContent(ChakraComponent):
  99. """The popover itself."""
  100. tag = "PopoverContent"
  101. class PopoverHeader(ChakraComponent):
  102. """The header of the popover."""
  103. tag = "PopoverHeader"
  104. class PopoverFooter(ChakraComponent):
  105. """Display a popover footer."""
  106. tag = "PopoverFooter"
  107. class PopoverBody(ChakraComponent):
  108. """The body of the popover."""
  109. tag = "PopoverBody"
  110. class PopoverArrow(ChakraComponent):
  111. """A visual arrow that points to the reference (or trigger)."""
  112. tag = "PopoverArrow"
  113. class PopoverCloseButton(ChakraComponent):
  114. """A button to close the popover."""
  115. tag = "PopoverCloseButton"
  116. class PopoverAnchor(ChakraComponent):
  117. """Used to wrap the position-reference element."""
  118. tag = "PopoverAnchor"
  119. class PopoverTrigger(ChakraComponent):
  120. """Used to wrap the reference (or trigger) element."""
  121. tag = "PopoverTrigger"