popover.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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.var 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. @classmethod
  52. def get_triggers(cls) -> Set[str]:
  53. """Get the event triggers for the component.
  54. Returns:
  55. The event triggers.
  56. """
  57. return super().get_triggers() | {"on_close", "on_open"}
  58. @classmethod
  59. def create(
  60. cls,
  61. *children,
  62. trigger=None,
  63. header=None,
  64. body=None,
  65. footer=None,
  66. use_close_button=False,
  67. **props
  68. ) -> Component:
  69. """Create a popover component.
  70. Args:
  71. children: The children of the component.
  72. trigger: The trigger that opens the popover.
  73. header: The header of the popover.
  74. body: The body of the popover.
  75. footer: The footer of the popover.
  76. use_close_button: Whether to add a close button on the popover.
  77. props: The properties of the component.
  78. Returns:
  79. The popover component.
  80. """
  81. if len(children) == 0:
  82. contents = []
  83. trigger = PopoverTrigger.create(trigger)
  84. # add header if present in props
  85. if header:
  86. contents.append(PopoverHeader.create(header))
  87. if body:
  88. contents.append(PopoverBody.create(body))
  89. if footer:
  90. contents.append(PopoverFooter.create(footer))
  91. if use_close_button:
  92. contents.append(PopoverCloseButton.create())
  93. children = [trigger, PopoverContent.create(*contents)]
  94. return super().create(*children, **props)
  95. class PopoverContent(ChakraComponent):
  96. """The popover itself."""
  97. tag = "PopoverContent"
  98. class PopoverHeader(ChakraComponent):
  99. """The header of the popover."""
  100. tag = "PopoverHeader"
  101. class PopoverFooter(ChakraComponent):
  102. """Display a popover footer."""
  103. tag = "PopoverFooter"
  104. class PopoverBody(ChakraComponent):
  105. """The body of the popover."""
  106. tag = "PopoverBody"
  107. class PopoverArrow(ChakraComponent):
  108. """A visual arrow that points to the reference (or trigger)."""
  109. tag = "PopoverArrow"
  110. class PopoverCloseButton(ChakraComponent):
  111. """A button to close the popover."""
  112. tag = "PopoverCloseButton"
  113. class PopoverAnchor(ChakraComponent):
  114. """Used to wrap the position-reference element."""
  115. tag = "PopoverAnchor"
  116. class PopoverTrigger(ChakraComponent):
  117. """Used to wrap the reference (or trigger) element."""
  118. tag = "PopoverTrigger"