HTML elements
coup-doeil tag
Coupdoeil hovercards relies on the use of a custom HTML element, the coup-doeil
tag. If you inspect the DOM where there is an hovercard set up you’ll see it:
<%= coupdoeil_hovercard_tag ProjectHovercard.with(project: @project).summary do %>
<p id="<%= dom_id(@project) %>"><%= @project.name %></p>
<% end %>
<coup-doeil hc="c"
hc-type="summary@project"
hc-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 hc="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::Hovercard::OptionsSet
.
When the hovercard is open, the coup-doeil
tag attribute data-hovercard-open
is set to "true"
.
methods
Two self-explanatory methods are available on this custom element:
.openHovercard()
.closeHovercard()
You can call them programmatically to trigger open/close outside of user normal interactions.
const myProject = document.getElementById("project_2")
const coupdoeilTag = myProject.closest("coup-doeil")
coupdoeilTag.openHovercard()
Hovercard element
When rendering an hovercard, 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--hovercard
CSS class, a data-placement
attribute that is set to the current hovercard position relative to its target, the dialog
role property, and an inline style attribute to actually position it.
<div role="dialog"
class="coupdoeil--hovercard"
data-placement="bottom-end"
style="position: absolute; left: 675.6px; top: 355.683px;"
>
<div class="my-hovercard-layout">
<div>My hovercard content</div>
</div>
</div>