Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
263ecbbad7
|
@@ -16,17 +16,30 @@ export default modifier((element) => {
|
|||||||
|
|
||||||
const rect = element.getBoundingClientRect();
|
const rect = element.getBoundingClientRect();
|
||||||
const tipRect = tooltipEl.getBoundingClientRect();
|
const tipRect = tooltipEl.getBoundingClientRect();
|
||||||
const margin = 6;
|
const arrowSize = 6;
|
||||||
let top = rect.top - tipRect.height - margin;
|
|
||||||
if (top < margin) top = rect.bottom + margin;
|
// Vertical placement: above trigger, flip below if no room
|
||||||
|
let placement = 'top';
|
||||||
|
let top = rect.top - tipRect.height - arrowSize;
|
||||||
|
if (top < arrowSize) {
|
||||||
|
placement = 'bottom';
|
||||||
|
top = rect.bottom + arrowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal: center on trigger, clamp to viewport
|
||||||
let left = rect.left + rect.width / 2 - tipRect.width / 2;
|
let left = rect.left + rect.width / 2 - tipRect.width / 2;
|
||||||
left = Math.max(
|
left = Math.max(
|
||||||
margin,
|
arrowSize,
|
||||||
Math.min(left, window.innerWidth - tipRect.width - margin)
|
Math.min(left, window.innerWidth - tipRect.width - arrowSize)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Arrow always points at trigger center, even when clamped
|
||||||
|
const arrowLeft = rect.left + rect.width / 2 - left;
|
||||||
|
|
||||||
|
tooltipEl.dataset.placement = placement;
|
||||||
tooltipEl.style.top = `${top}px`;
|
tooltipEl.style.top = `${top}px`;
|
||||||
tooltipEl.style.left = `${left}px`;
|
tooltipEl.style.left = `${left}px`;
|
||||||
|
tooltipEl.style.setProperty('--arrow-left', `${arrowLeft}px`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hide = () => {
|
const hide = () => {
|
||||||
|
|||||||
@@ -728,6 +728,26 @@ body {
|
|||||||
animation: tooltip-fade-in 0.15s ease;
|
animation: tooltip-fade-in 0.15s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border: 6px solid transparent;
|
||||||
|
left: var(--arrow-left, 50%);
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip[data-placement='top']::after {
|
||||||
|
top: 100%;
|
||||||
|
border-top-color: var(--body-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip[data-placement='bottom']::after {
|
||||||
|
bottom: 100%;
|
||||||
|
border-bottom-color: var(--body-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes tooltip-fade-in {
|
@keyframes tooltip-fade-in {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@@ -293,9 +293,30 @@ module('Integration | Component | app-menu/settings/nostr', function (hooks) {
|
|||||||
removeBtn.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
|
removeBtn.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
|
||||||
await settled();
|
await settled();
|
||||||
|
|
||||||
|
const tooltip = document.body.querySelector('.tooltip');
|
||||||
assert.dom('.tooltip', document.body).exists('tooltip appears on hover');
|
assert.dom('.tooltip', document.body).exists('tooltip appears on hover');
|
||||||
assert.dom('.tooltip', document.body).hasText('Remove relay');
|
assert.dom('.tooltip', document.body).hasText('Remove relay');
|
||||||
|
|
||||||
|
// Verify arrow is rendered
|
||||||
|
assert.ok(tooltip.dataset.placement, 'tooltip has placement attribute');
|
||||||
|
const arrowStyle = getComputedStyle(tooltip, '::after');
|
||||||
|
assert.strictEqual(arrowStyle.content, '""', 'arrow pseudo-element exists');
|
||||||
|
|
||||||
|
// Verify arrow points in correct direction based on placement
|
||||||
|
if (tooltip.dataset.placement === 'top') {
|
||||||
|
assert.notStrictEqual(
|
||||||
|
arrowStyle.borderTopColor,
|
||||||
|
'rgba(0, 0, 0, 0)',
|
||||||
|
'arrow points down when tooltip is above trigger'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert.notStrictEqual(
|
||||||
|
arrowStyle.borderBottomColor,
|
||||||
|
'rgba(0, 0, 0, 0)',
|
||||||
|
'arrow points up when tooltip is below trigger'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
removeBtn.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));
|
removeBtn.dispatchEvent(new MouseEvent('mouseleave', { bubbles: true }));
|
||||||
await settled();
|
await settled();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user