A popover is a way to toggle content on top of other content. It can be used for small texts, small forms, or even dropdowns. By default, popover will toggle open/closed by simply clicking the trigger element.
In addition, you may also choose to enable enhanced functionality so that the popover may be toggled by clicking outside of the "trigger element" and/or popover itself.
You are building a single page application where clicking into the popover itself triggers some asynchronous actions which mutate the UI instantaneously. As a result, may want the popover to automatically close after a selection has been made from the popover contents.
You are building an custom in-page results filter list which is contained inside of the popover's content area. Since the filter list contains 5 filters, you may want to keep the popover open so that users may select multiple filters then only close the popover when users click outside of the popover.
<%= pb_rails("flex", props: { dark: true, orientation: "row", vertical: "center" }) do %> <%= pb_rails("body", props: { text: "Click info for more details" }) %> <%= pb_rails("circle_icon_button", props: { variant: "secondary", icon: "info", id: "regular-popover-1" }) %> <%= pb_rails("popover", props: { trigger_element_id: "regular-popover-1", tooltip_id: "tooltip-1", offset: true, position: "top", }) do %> I'm a popover. I can show content of any size. <% end %> <% end %>
Notice offset is not set so the popover is flush with the content.
<%= pb_rails("button", props: { variant: "secondary", id: 'list' }) do %> <%= pb_rails("flex", props: {align: "center"}) do %> Filter By <%= pb_rails("flex/flex_item", props: {margin_left: "xxs"}) do %> <div id="arrow-icon" style="display: flex"> <%= pb_rails("icon", props: { icon: "chevron-down", fixed_width: true }) %> </div> <% end %> <% end %> <% end %> <%= pb_rails("popover", props: {trigger_element_id: "list", tooltip_id: "list-tooltip", position: 'bottom', padding: "none"}) do %> <%= pb_rails("list", props: {ordered: false, dark: false, borderless: false, xpadding: true}) do %> <%= pb_rails("list/item") do %><a>Popularity</a><% end %> <%= pb_rails("list/item") do %><a>Title</a><% end %> <%= pb_rails("list/item") do %><a>Duration</a><% end %> <%= pb_rails("list/item") do %><a>Date Started</a><% end %> <%= pb_rails("list/item") do %><a>Date Ended </a><% end %> <% end %> <% end %> <script type="text/javascript"> const popoverButton = document.querySelector("#list") let buttonClicked = false const arrowDiv = document.querySelector("#arrow-icon") popoverButton.onclick = () => { buttonClicked = !buttonClicked if (buttonClicked) { arrowDiv.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 31 25" fill="none" class="pb_custom_icon svg-inline--fa pb_icon_kit svg_fw" id="" data="{}" aria="{}" tabindex=""><path d="M14.2031 5.70312C14.625 5.28125 15.3281 5.28125 15.75 5.70312L24.7969 14.7031C25.2188 15.1719 25.2188 15.875 24.7969 16.2969C24.3281 16.7656 23.625 16.7656 23.2031 16.2969L15 8.09375L6.79688 16.2969C6.32812 16.7656 5.625 16.7656 5.20312 16.2969C4.73438 15.875 4.73438 15.1719 5.20312 14.75L14.2031 5.70312Z" fill="currentColor"/></svg>' } else { arrowDiv.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 31 25" fill="none" class="pb_custom_icon svg-inline--fa pb_icon_kit svg_fw" id="" data="{}" aria="{}" tabindex=""><path d="M14.2031 19.2969L5.20312 10.2969C4.73438 9.875 4.73438 9.17188 5.20312 8.70312C5.625 8.28125 6.32812 8.28125 6.79688 8.70312L15 16.9531L23.2031 8.75C23.625 8.28125 24.3281 8.28125 24.7969 8.75C25.2188 9.17188 25.2188 9.875 24.7969 10.2969L15.75 19.2969C15.3281 19.7656 14.625 19.7656 14.2031 19.2969Z" fill="currentColor"/></svg>' } } </script>
<%= pb_rails("flex", props: {classname: "flex-container", spacing: "between"}) do %> <span> <%= pb_rails("button", props: { text: "Click Inside", variant: "secondary", id: "inside-popover-1" }) %> <%= pb_rails("popover", props: { close_on_click: "inside", trigger_element_id: "inside-popover-1", tooltip_id: "inside-tooltip-1", position: "bottom", offset: true }) do %> Click on me! <% end %> </span> <span> <%= pb_rails("button", props: { text: "Click Outside", variant: "secondary", id: "outside-popover-1" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "outside-popover-1", tooltip_id: "outside-tooltip-1", position: "left", offset: true }) do %> Click anywhere but me! <% end %> </span> <span> <%= pb_rails("button", props: { text: "Click Anywhere", variant: "secondary", id: "any-popover-1" }) %> <%= pb_rails("popover", props: { close_on_click: "any", trigger_element_id: "any-popover-1", tooltip_id: "any-tooltip-1", position: "top", offset: true }) do %> Click anything! <% end %> </span> <% end %>
<div style="position: relative; z-index: 2"> <%= pb_rails("body", props: {text: "I've got a z-index of 2", margin_bottom: "md"}) %> </div> <%= pb_rails("button", props: { variant: "secondary", id: 'tooltip-z-index-1', text: "Click Me", }) %> <%= pb_rails("popover", props: { trigger_element_id: "tooltip-z-index-1", tooltip_id: "tooltip-z-index", position: 'top', z_index: "3", offset: true }) do %> I've got a z-index of 3 <% end %>
<%= pb_rails("button", props: { variant: "secondary", id: 'scroll-height', text: "Click Me" }) %> <%= pb_rails("popover", props: { trigger_element_id: "scroll-height", tooltip_id: "scroll-height-1", position: 'top', close_on_click: "any", max_height: "150px", max_width: "240px", offset: true }) do %> <%= pb_rails("body", props: { margin_bottom: "sm", text: "So many people live within unhappy circumstances and yet will not take the initiative to change their situation because they are conditioned to a life of security, conformity, and conservation, all of which may appear to give one peace of mind, but in reality, nothing is more damaging to the adventurous spirit." }) %> <%= pb_rails("title", props: { size: 4, text: "- Christopher McCandless" }) %> <% end %>
<%= pb_rails("flex", props: { dark: true, orientation: "row", vertical: "center" }) do %> <%= pb_rails("body", props: { text: "Click info for more details" }) %> <%= pb_rails("circle_icon_button", props: { variant: "secondary", icon: "info", id: "actionable-popover-1" }) %> <%= pb_rails("popover", props: { close_on_click: "any", trigger_element_id: "actionable-popover-1", tooltip_id: "actionable-tooltip-1", offset: true, position: "top" }) do %> <%= pb_rails("button", props: { id: "actionable-tooltip-button", text: "Learn more" }) %> <% end %> <% end %> <%= javascript_tag do %> document.addEventListener('DOMContentLoaded', function () { document.querySelector('#actionable-tooltip-button').addEventListener('click', function (e) { alert("Let's do this") }, { once: true }) }) <% end %>
By default, the popover tooltip attaches to the <body>. To attach it elsewhere, use the append_to prop. Set it to "parent" to place the tooltip inside its parent element, or pass any CSS selector (#id or .class) to specify a custom container.
<%= pb_rails("flex", props: { dark: true, orientation: "row", vertical: "center", margin_bottom: "md" }) do %> <%= pb_rails("body", props: { text: "Click info for more details" }) %> <%= pb_rails("circle_icon_button", props: { variant: "secondary", icon: "info", id: "append-to-popover-1" }) %> <%= pb_rails("popover", props: { trigger_element_id: "append-to-popover-1", tooltip_id: "append-to-tooltip-1", offset: true, position: "top", append_to: "parent", }) do %> I'm a popover. I have been appended to my parent element. <% end %> <% end %> <%= pb_rails("flex", props: { dark: true, orientation: "row", vertical: "center" }) do %> <%= pb_rails("body", props: { text: "Click info for more details" }) %> <%= pb_rails("circle_icon_button", props: { variant: "secondary", icon: "info", id: "append-to-popover-2" }) %> <%= pb_rails("popover", props: { trigger_element_id: "append-to-popover-2", tooltip_id: "append-to-tooltip-2", offset: true, position: "top", append_to: ".pb--page--sideNav", }) do %> I'm a popover. I have been appended to the .pb--page--sideNav. <% end %> <% end %>
Use the position prop to control where the popover appears relative to its trigger. Valid values include top, bottom, left, right, and aligned variants such as top-start, top-end, bottom-start, bottom-end, left-start, left-end, right-start, and right-end.
<%= pb_rails("flex", props: { justify: "around", margin_bottom: "sm", orientation: "row", wrap: true }) do %> <%= pb_rails("button", props: { text: "Top", variant: "secondary", id: "placement-popover-top" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-top", tooltip_id: "placement-tooltip-top", position: "top", offset: true }) do %> Popover: top <% end %> <%= pb_rails("button", props: { text: "Top start", variant: "secondary", id: "placement-popover-top-start" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-top-start", tooltip_id: "placement-tooltip-top-start", position: "top-start", offset: true }) do %> Popover: top start <% end %> <%= pb_rails("button", props: { text: "Top end", variant: "secondary", id: "placement-popover-top-end" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-top-end", tooltip_id: "placement-tooltip-top-end", position: "top-end", offset: true }) do %> Popover: top end <% end %> <% end %> <%= pb_rails("flex", props: { justify: "around", margin_bottom: "sm", orientation: "row", wrap: true }) do %> <%= pb_rails("button", props: { text: "Bottom", variant: "secondary", id: "placement-popover-bottom" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-bottom", tooltip_id: "placement-tooltip-bottom", position: "bottom", offset: true }) do %> Popover: bottom <% end %> <%= pb_rails("button", props: { text: "Bottom start", variant: "secondary", id: "placement-popover-bottom-start" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-bottom-start", tooltip_id: "placement-tooltip-bottom-start", position: "bottom-start", offset: true }) do %> Popover: bottom start <% end %> <%= pb_rails("button", props: { text: "Bottom end", variant: "secondary", id: "placement-popover-bottom-end" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-bottom-end", tooltip_id: "placement-tooltip-bottom-end", position: "bottom-end", offset: true }) do %> Popover: bottom end <% end %> <% end %> <%= pb_rails("flex", props: { justify: "around", margin_bottom: "sm", orientation: "row", wrap: true }) do %> <%= pb_rails("button", props: { text: "Left", variant: "secondary", id: "placement-popover-left" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-left", tooltip_id: "placement-tooltip-left", position: "left", offset: true }) do %> Popover: left <% end %> <%= pb_rails("button", props: { text: "Left start", variant: "secondary", id: "placement-popover-left-start" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-left-start", tooltip_id: "placement-tooltip-left-start", position: "left-start", offset: true }) do %> Popover: left start <% end %> <%= pb_rails("button", props: { text: "Left end", variant: "secondary", id: "placement-popover-left-end" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-left-end", tooltip_id: "placement-tooltip-left-end", position: "left-end", offset: true }) do %> Popover: left end <% end %> <% end %> <%= pb_rails("flex", props: { justify: "around", orientation: "row", wrap: true }) do %> <%= pb_rails("button", props: { text: "Right", variant: "secondary", id: "placement-popover-right" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-right", tooltip_id: "placement-tooltip-right", position: "right", offset: true }) do %> Popover: right <% end %> <%= pb_rails("button", props: { text: "Right start", variant: "secondary", id: "placement-popover-right-start" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-right-start", tooltip_id: "placement-tooltip-right-start", position: "right-start", offset: true }) do %> Popover: right start <% end %> <%= pb_rails("button", props: { text: "Right end", variant: "secondary", id: "placement-popover-right-end" }) %> <%= pb_rails("popover", props: { close_on_click: "outside", trigger_element_id: "placement-popover-right-end", tooltip_id: "placement-tooltip-right-end", position: "right-end", offset: true }) do %> Popover: right end <% end %> <% end %>
| Props | Type | Values |
|---|---|---|
align_content |
enum | responsive
|
start
end
center
spaceBetween
spaceAround
spaceEvenly
|
align_items |
enum | responsive
|
start
end
center
|
border_radius |
enum
|
none
xs
sm
md
lg
xl
rounded
|
cursor |
enum
|
auto
default
none
contextMenu
help
pointer
progress
wait
cell
|
dark |
boolean
|
true
false
|
flex |
enum | responsive
|
auto
initial
0
1
2
3
4
5
6
7
8
9
10
11
12
none
|
flex_direction |
enum | responsive
|
row
column
rowReverse
columnReverse
|
flex_wrap |
enum | responsive
|
wrap
nowrap
wrapReverse
|
justify_content |
enum | responsive
|
start
end
center
spaceBetween
spaceAround
spaceEvenly
|
line_height |
enum
|
loosest
looser
loose
normal
tight
tighter
tightest
|
margin_right |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_left |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_top |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_bottom |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_x |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_y |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin |
array
|
none
xxs
xs
sm
md
lg
xl
|
width |
string
|
|
min_width |
string
|
|
max_width |
string
|
|
gap |
string | responsive
|
|
column_gap |
string | responsive
|
|
row_gap |
string | responsive
|
|
number_spacing |
enum
|
tabular
|
order |
enum | responsive
|
none
first
1
2
3
4
5
6
7
8
9
10
11
12
|
overflow_x |
enum
|
scroll
visible
hidden
auto
|
overflow_y |
enum
|
scroll
visible
hidden
auto
|
overflow |
enum
|
scroll
visible
hidden
auto
|
padding_right |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_left |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_top |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_bottom |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_x |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_y |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding |
array
|
none
xxs
xs
sm
md
lg
xl
|
position |
enum
|
relative
absolute
fixed
sticky
static
|
shadow |
enum
|
none
deep
deeper
deepest
|
text_align |
enum | responsive
|
start
end
left
right
center
justify
justifyAll
matchParent
|
truncate |
enum
|
none
1
2
3
4
5
|
vertical_align |
enum | responsive
|
baseline
super
top
middle
bottom
sub
text-top
text-bottom
|
z_index |
enum | responsive
|
1
2
3
4
5
6
7
8
9
10
max
|
top |
enum | object
|
xxs
xs
sm
md
lg
xl
xxl
|
inset |
boolean
|
true
false
|
right |
enum | object
|
xxs
xs
sm
md
lg
xl
xxl
|
bottom |
enum | object
|
xxs
xs
sm
md
lg
xl
xxl
|
left |
enum | object
|
xxs
xs
sm
md
lg
xl
xxl
|
height |
string
|
|
max_height |
string
|
|
min_height |
string
|
|
hover |
object
|
|
group_hover |
boolean
|
true
false
|
| Props | Type | Values | Default |
|---|---|---|---|
append_to |
string
|
body
|
|
close_on_click |
"outside" | "inside" | "any"
|
none
outside
inside
any
|
none
|
offset |
boolean
|
true
false
|
false
|
reference |
popperreference & any
|
||
show |
boolean
|
true
false
|
false
|
should_close_popover |
function
|
noop
|
|
trigger_element_id |
string
|
||
tooltip_id |
string
|