HTML elements
coup-doeil tag
Coupdoeil popovers relies on the use of a custom HTML element, the coup-doeil
tag. If you inspect the DOM where there is a popover set up you’ll see it:
<%= coupdoeil_popover_tag ProjectPopover.with(project: @project).summary do %>
<p id="<%= dom_id(@project) %>"><%= @project.name %></p>
<% end %>
<coup-doeil popover-options="c"
popover-type="summary@project"
popover-params='{"project":{"_cd_globalid":"gid://myapp/Project/2"}}'>
<p id="project_2">My Project</p>
</coup-doeil>
When inspecting element in local environment (dev, test), you can also see all the options. But to avoid cluttering the DOM with very repetitive data, and overburden HTML payload, in production the options are compressed to the minimum. This is the popover-options="c"
attribute that can be seen in the example above. If you’re interested to know how this compression works, you can take a look at #to_base36
method in Coupdoeil::Popover::OptionsSet
.
When the popover is open, the coup-doeil
tag attribute data-popover-open
is set to "true"
.
methods
Two methods are available on this custom element:
.openPopover()
.closePopover()
You can call them programmatically to trigger open/close outside of user regular interactions with coup-doeil element.
const myProject = document.getElementById("project_2")
const coupdoeilTag = myProject.closest("coup-doeil")
coupdoeilTag.openPopover()
Popover element
When rendering a popover, you can think of it made of three layers:
- the positioned element
- the layout
- the content
You have controller over the last two elements, but the first one is fully handle by the library.
The positioned element has the .coupdoeil--popover
CSS class, a data-placement
attribute that is set to the current popover position relative to its target, the dialog
role property, and an inline style attribute to actually position it.
<div role="dialog"
class="coupdoeil--popover"
data-placement="bottom-end"
style="position: absolute; left: 675.6px; top: 355.683px;"
>
<div class="my-popover-layout">
<div>My popover content</div>
</div>
</div>