Popover
Popover - Phlex implementation
Examples
Default
Displays rich content in a portal, triggered by a button.
<%= render "ui/popover" do %>
<%= render "ui/popover/trigger" do %>
<%= render "ui/button", variant: :outline do %>Open popover<% end %>
<% end %>
<%= render "ui/popover/content" do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
</div>
<% end %>
<% end %><%= render UI::Popover.new do %>
<%= render UI::PopoverTrigger.new(as_child: true) do |attrs| %>
<%= render UI::Button.new(**attrs, variant: :outline) { "Open popover" } %>
<% end %>
<%= render UI::PopoverContent.new do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
</div>
<% end %>
<% end %><%= render UI::PopoverComponent.new do %>
<%= render UI::PopoverTriggerComponent.new(as_child: true) do %>
<%= render(UI::ButtonComponent.new(variant: :outline)) { "Open popover" } %>
<% end %>
<%= render UI::PopoverContentComponent.new do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
</div>
<% end %>
<% end %>With Form
Popover containing a form for input.
<%= render "ui/popover" do %>
<%= render "ui/popover/trigger" do %>
<%= render "ui/button", variant: :outline do %>Open<% end %>
<% end %>
<%= render "ui/popover/content", classes: "w-80" do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
<div class="grid gap-2">
<div class="grid grid-cols-3 items-center gap-4">
<%= render "ui/label", for: "width" do %>Width<% end %>
<%= render "ui/input", id: "width", value: "100%", classes: "col-span-2 h-8" %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render "ui/label", for: "max-width" do %>Max. width<% end %>
<%= render "ui/input", id: "max-width", value: "300px", classes: "col-span-2 h-8" %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render "ui/label", for: "height" do %>Height<% end %>
<%= render "ui/input", id: "height", value: "25px", classes: "col-span-2 h-8" %>
</div>
</div>
</div>
<% end %>
<% end %><%= render UI::Popover.new do %>
<%= render UI::PopoverTrigger.new(as_child: true) do |attrs| %>
<%= render UI::Button.new(**attrs, variant: :outline) { "Open" } %>
<% end %>
<%= render UI::PopoverContent.new(classes: "w-80") do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
<div class="grid gap-2">
<div class="grid grid-cols-3 items-center gap-4">
<%= render UI::Label.new(for: "width") { "Width" } %>
<%= render UI::Input.new(id: "width", value: "100%", classes: "col-span-2 h-8") %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render UI::Label.new(for: "max-width") { "Max. width" } %>
<%= render UI::Input.new(id: "max-width", value: "300px", classes: "col-span-2 h-8") %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render UI::Label.new(for: "height") { "Height" } %>
<%= render UI::Input.new(id: "height", value: "25px", classes: "col-span-2 h-8") %>
</div>
</div>
</div>
<% end %>
<% end %><%= render UI::PopoverComponent.new do %>
<%= render UI::PopoverTriggerComponent.new(as_child: true) do %>
<%= render(UI::ButtonComponent.new(variant: :outline)) { "Open" } %>
<% end %>
<%= render UI::PopoverContentComponent.new(classes: "w-80") do %>
<div class="grid gap-4">
<div class="space-y-2">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
<div class="grid gap-2">
<div class="grid grid-cols-3 items-center gap-4">
<%= render(UI::LabelComponent.new(for: "width")) { "Width" } %>
<%= render UI::InputComponent.new(id: "width", value: "100%", classes: "col-span-2 h-8") %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render(UI::LabelComponent.new(for: "max-width")) { "Max. width" } %>
<%= render UI::InputComponent.new(id: "max-width", value: "300px", classes: "col-span-2 h-8") %>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<%= render(UI::LabelComponent.new(for: "height")) { "Height" } %>
<%= render UI::InputComponent.new(id: "height", value: "25px", classes: "col-span-2 h-8") %>
</div>
</div>
</div>
<% end %>
<% end %>Features
- Custom styling with Tailwind classes
- Click outside to close
API Reference
Popover
Container for popover trigger and content.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| placement | String | bottom | The placement |
| offset | Integer | 4 | The offset |
| trigger | String | click | The trigger |
| hover_delay | Integer | 200 | The hover delay |
| align | String | nil | Alignment within container |
| side_offset | String | nil | The side offset |
Content
The floating content panel.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| side | String | bottom | Which side to display on |
| align | String | center | Alignment within container |
Trigger
Button or element that triggers the popover.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| as_child | Boolean | false | When true, yields attributes to block instead of rendering wrapper |
Accessibility
Adheres to theDialog (Non-modal) WAI-ARIA design pattern
Implements the WAI-ARIA Dialog (Non-modal) pattern with proper roles, states, and keyboard navigation.
Keyboard Shortcuts
| Key | Description |
|---|---|
| Enter | Activates the focused element |
| Escape | Closes the component |
JavaScript
Stimulus Controller
ui--popoverValues
| Name | Type | Description |
|---|---|---|
| open | Boolean | Controls open state |
Actions
teardownKeyboardNavigationtoggleshowfindTriggerElementToFocushideEvents
| Event | Description | Detail |
|---|---|---|
| popover:show | Fired when popover show | - |
| popover:hide | Fired when popover hide | - |