popover.py 5.6 KB

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