Allow showing popover above & tweaks

This commit is contained in:
Svilen Markov 2024-08-20 13:29:44 +01:00
parent 984f26807e
commit 8860f4591b
2 changed files with 53 additions and 14 deletions

View File

@ -36,7 +36,7 @@ function handleMouseEnter(event) {
if (activeTarget !== null) {
if (activeTarget !== target) {
hidePopover();
setTimeout(showPopover, 5);
requestAnimationFrame(showPopover);
}
return;
@ -96,28 +96,45 @@ function showPopover() {
}
function repositionContainer() {
const activeTargetBounds = activeTarget.getBoundingClientRect();
const targetBounds = activeTarget.getBoundingClientRect();
const containerBounds = containerElement.getBoundingClientRect();
const containerInlinePadding = parseInt(containerComputedStyle.getPropertyValue("padding-inline"));
const activeTargetBoundsWidthOffset = activeTargetBounds.width * (activeTarget.dataset.popoverOffset || 0.5);
const left = activeTargetBounds.left + activeTargetBoundsWidthOffset - (containerBounds.width / 2);
const activeTargetBoundsWidthOffset = targetBounds.width * (activeTarget.dataset.popoverOffset || 0.5);
const position = activeTarget.dataset.popoverPosition || "below";
const left = targetBounds.left + activeTargetBoundsWidthOffset - (containerBounds.width / 2) + 1;
if (left < 0) {
containerElement.style.left = 0;
containerElement.style.removeProperty("right");
containerElement.style.setProperty("--triangle-offset", activeTargetBounds.left - containerInlinePadding + activeTargetBoundsWidthOffset + "px");
containerElement.style.setProperty("--triangle-offset", targetBounds.left - containerInlinePadding + activeTargetBoundsWidthOffset + "px");
} else if (left + containerBounds.width > window.innerWidth) {
containerElement.style.removeProperty("left");
containerElement.style.right = 0;
containerElement.style.setProperty("--triangle-offset", containerBounds.width - containerInlinePadding - (window.innerWidth - activeTargetBounds.left - activeTargetBoundsWidthOffset) + "px");
containerElement.style.setProperty("--triangle-offset", containerBounds.width - containerInlinePadding - (window.innerWidth - targetBounds.left - activeTargetBoundsWidthOffset) + "px");
} else {
containerElement.style.removeProperty("right");
containerElement.style.left = left + "px";
containerElement.style.removeProperty("--triangle-offset");
}
frameElement.style.marginTop = activeTarget.dataset.popoverMargin || defaultDistanceFromTarget;
containerElement.style.top = activeTargetBounds.top + window.scrollY + activeTargetBounds.height + "px";
const distanceFromTarget = activeTarget.dataset.popoverMargin || defaultDistanceFromTarget;
const topWhenAbove = targetBounds.top + window.scrollY - containerBounds.height;
const topWhenBelow = targetBounds.top + window.scrollY + targetBounds.height;
if (
position === "above" && topWhenAbove > window.scrollY ||
(position === "below" && topWhenBelow + containerBounds.height > window.scrollY + window.innerHeight)
) {
containerElement.classList.add("position-above");
frameElement.style.removeProperty("margin-top");
frameElement.style.marginBottom = distanceFromTarget;
containerElement.style.top = topWhenAbove + "px";
} else {
containerElement.classList.remove("position-above");
frameElement.style.removeProperty("margin-bottom");
frameElement.style.marginTop = distanceFromTarget;
containerElement.style.top = topWhenBelow + "px";
}
}
function hidePopover() {

View File

@ -34,8 +34,8 @@
--color-separator: hsl(var(--bghs), calc(var(--scheme) ((var(--scheme) var(--bgl)) + 4% * var(--cm))));
--color-widget-content-border: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 4%)));
--color-widget-background-highlight: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 4%)));
--color-popover-background: hsl(var(--bgh), calc(var(--bgs) + 3%), calc(var(--bgl) + 2%));
--color-popover-border: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 7%)));
--color-popover-background: hsl(var(--bgh), calc(var(--bgs) + 3%), calc(var(--bgl) + 3%));
--color-popover-border: hsl(var(--bghs), calc(var(--scheme) (var(--scheme) var(--bgl) + 10%)));
--ths: var(--bgh), calc(var(--bgs) * var(--tsm));
--color-text-base: hsl(var(--ths), calc(var(--scheme) var(--cm) * 58%));
@ -439,20 +439,32 @@ kbd:active {
.popover-container {
--triangle-size: 10px;
--triangle-offset: 50%;
--triangle-margin: calc(var(--triangle-size) + 3px);
--entrance-y-offset: 8px;
--entrance-direction: calc(var(--entrance-y-offset) * -1);
z-index: 20;
position: absolute;
padding-top: calc(var(--triangle-size) + 3px);
padding-top: var(--triangle-margin);
padding-inline: var(--content-bounds-padding);
}
.popover-container.position-above {
--entrance-direction: var(--entrance-y-offset);
padding-top: 0;
padding-bottom: var(--triangle-margin);
}
.popover-frame {
--shadow-properties: 0 15px 20px -10px;
--shadow-color: hsla(var(--bghs), calc(var(--bgl) * 0.2), 0.5);
position: relative;
padding: 10px;
background: var(--color-popover-background);
border: 1px solid var(--color-popover-border);
border-radius: 5px;
animation: popoverFrameEntrance 0.3s backwards cubic-bezier(0.16, 1, 0.3, 1);
box-shadow: 0 15px 30px -5px hsla(var(--bghs), calc(var(--bgl) * 0.2), 0.5);
box-shadow: var(--shadow-properties) var(--shadow-color);
}
.popover-frame::before {
@ -462,17 +474,27 @@ kbd:active {
height: var(--triangle-size);
transform: rotate(45deg);
background-color: var(--color-popover-background);
border-top-left-radius: 4px;
border-top-left-radius: 2px;
border-left: 1px solid var(--color-popover-border);
border-top: 1px solid var(--color-popover-border);
left: calc(var(--triangle-offset) - (var(--triangle-size) / 2));
top: calc(var(--triangle-size) / 2 * -1 - 1px);
}
.popover-container.position-above .popover-frame::before {
transform: rotate(-135deg);
top: auto;
bottom: calc(var(--triangle-size) / 2 * -1 - 1px);
}
.popover-container.position-above .popover-frame {
--shadow-properties: 0 10px 20px -10px;
}
@keyframes popoverFrameEntrance {
from {
opacity: 0;
transform: translateY(-8px);
transform: translateY(var(--entrance-direction));
}
}