popover.py 5.6 KB

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