Popover
Source
Example
Vanilla Popover
<div class="x-popover focus">
<div role="button" class="x-button" tabindex="0">Toggle Popover</div>
<div class="x-popover-content center shadow dark:bg-body-secondary mt-2.5 p-2 w-32 flex-col">
Popover content
</div>
</div>Javascript Popover
Leverages the Popover API with floating-ui.
<div
class="x-popover"
data-controller="x-popover"
>
<button
class="x-button"
role="button"
popovertargetaction="toggle"
popovertarget="popoverElement"
id="popoverAction"
>Toggle Popover</button>
<div class="x-popover-content shadow h-48" id="popoverElement" aria-describedby="popoverAction" popover="manual">
Popover content
<button
type="button"
data-action="x-popover#hide"
>x</button>
</div>
</div>Autocomplete Popover
Preview
Source
<div class="x-popover trigger-focus group mx-auto w-80" data-controller="x-popover">
<div class="x-control w-full">
<input
data-action="input->x-popover#autocomplete"
data-x-popover-target="autocomplete"
type="search"
placeholder="Vyhledávání ..."
autocomplete="off"
role="combobox"
aria-autocomplete="list"
aria-controls="popoverContent"
aria-haspopup="listbox"
aria-expanded="true"
value="Volba"
>
</div>
<div
class="x-popover-content center flex flex-col shadow dark:bg-body-secondary mt-2 p-2 gap-2 w-full empty:closed group-not-has-aria-expanded:closed"
data-x-popover-target="content"
role="listbox"
id="popoverContent"
>
<button id="option-1" class="x-button ghosted justify-start" role="option" data-action="click->x-popover#selectDescendant">Volba 1</button>
<button id="option-2" class="x-button ghosted justify-start" role="option" data-action="click->x-popover#selectDescendant">Volba 2</button>
<button id="option-3" class="x-button ghosted justify-start" role="option" data-action="click->x-popover#selectDescendant">Volba 3</button>
</div>
</div>More examples can be found in the Winduum docs.
Example CSS
@import "winduum/src/components/popover/props/content.css" layer(theme);
@import "winduum/src/components/popover/content.css" layer(utilities);
@import "winduum/src/components/popover/default.css" layer(utilities);
/* Example customization */
@layer utilities {
.x-popover {
--x-popover-content-background-color: var(--color-accent);
--x-popover-content-border-radius: var(--radius-md);
}
}Winduum CSS Code
winduum/src/components/popover/props/content.css
:root, :host {
--x-popover-content-background-color: var(--color-body-primary);
--x-popover-content-border-radius: var(--radius-xl);
--x-popover-content-padding-block: calc(var(--spacing) * 2);
--x-popover-content-padding-inline: calc(var(--spacing) * 2);
--x-popover-content-scale-y: 0.75;
--x-popover-content-scale-x: 0.75;
}winduum/src/components/popover/content.css
.x-popover-content {
background-color: var(--x-popover-content-background-color);
border-radius: var(--x-popover-content-border-radius);
padding: var(--x-popover-content-padding-block) var(--x-popover-content-padding-inline);
z-index: var(--x-popover-content-z-index, var(--z-index-10));
transition-property: var(--default-transition-property);
transition-timing-function: var(--ease-in-out);
transition-duration: var(--default-transition-duration);
transform:
translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0))
scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1));
will-change: transform;
inline-size: max-content;
position: absolute;
&:where(.bottom), & {
transform-origin: top;
}
&:where(.bottom-start) {
transform-origin: top left;
}
&:where(.bottom-end) {
inset-inline-end: 0;
transform-origin: top right;
}
&:where(.right) {
inset-block-start: 0;
inset-inline-start: 100%;
transform-origin: left;
}
&:where(.right-start) {
transform-origin: left top;
}
&:where(.right-end) {
inset-block: auto 0;
transform-origin: left bottom;
}
&:where(.left) {
inset-block-start: 0;
inset-inline-end: 100%;
transform-origin: right;
}
&:where(.left-start) {
transform-origin: right top;
}
&:where(.left-end) {
inset-block: auto 0;
transform-origin: right bottom;
}
&:where(.top) {
inset-block-end: 100%;
transform-origin: bottom;
}
&:where(.top-start) {
transform-origin: bottom left;
}
&:where(.top-end) {
inset-inline-end: 0;
transform-origin: bottom right;
}
&:where(.inline-center) {
--tw-translate-x: -50%;
inset-inline-start: 50%;
}
&:where(.block-center) {
--tw-translate-y: -50%;
inset-block-start: 50%;
}
&[popover]:not([data-open]) {
--tw-scale-x: var(--x-popover-content-scale-x);
--tw-scale-y: var(--x-popover-content-scale-y);
opacity: 0%;
pointer-events: none;
}
&:not([popover]) {
.trigger-focus:not(:focus, :focus-within) > &, .trigger-hover:not(:hover) > & {
--tw-scale-x: var(--x-popover-content-scale-x);
--tw-scale-y: var(--x-popover-content-scale-y);
opacity: 0%;
visibility: hidden;
}
}
}winduum/src/components/popover/default.css
.x-popover {
position: relative;
display: inline-block;
}Stimulus Actions
toggle
Action is automatically added on first [popovertargetaction] element upon controller connection, if it exists.
<button
class="x-button"
role="button"
popovertargetaction="toggle"
data-action="click->x-popover#toggle:prevent keydown.esc@window->x-popover#hide click@window->x-popover#dismiss click->invoke-ripple#show"
popovertarget="_6zbalmci_"
aria-expanded="false"
aria-haspopup="dialog"
>
Toggle Popover
</button>show
Action is automatically added on first [popovertargetaction] element upon controller connection, if it exists.
hide
Action is automatically added on first [popovertargetaction] element upon controller connection, if it exists.
<div class="x-popover-content shadow h-48" id="popoverElement" aria-describedby="popoverAction" popover="manual">
Popover content
<button
type="button"
data-action="x-popover#hide"
>x</button>
</div>dismiss
Action is automatically added on first [popovertargetaction] element upon controller connection as click@window->x-popover#dismiss, if it exists.
fetch
Fetches the popover remotely, used internally.
onFetchComplete
Callback that is executed after fetch is complete.
Stimulus Values
url
Fetches the popover remotely, popovertarget is added dynamically upon completed request.
<div
class="x-popover"
data-controller="x-popover"
data-x-popover-url-value="/popover/info.json"
>
<button
class="x-button"
role="button"
popovertargetaction="toggle"
id="popoverAction"
>Fetch Popover</button>
</div>appendTo
Choose a selector where to append the popover after a fetch. Defaults to position after the trigger element of the popover.
<div
class="x-popover"
data-controller="x-popover"
data-x-popover-url-value="/popover/info.json"
data-x-popover-append-to-value="body"
id="popoverAction"
>
<button
class="x-button"
role="button"
popovertargetaction="toggle"
>Fetch Popover</button>
</div>manual
Disables automatic generation of action values to [popovertargetaction] element upon controller connection.
<div
class="x-popover"
data-controller="x-popover"
data-x-popover-manual-value="true"
>
<button
class="x-button"
role="button"
popovertargetaction="toggle"
popovertarget="popoverElement"
>Toggle Popover</button>
</div>