Better fix on mobile tooltips
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { tick } from 'svelte';
|
||||
|
||||
export let text: string;
|
||||
|
||||
let showTooltip = false;
|
||||
@@ -8,12 +10,13 @@
|
||||
let wrapperElement: HTMLSpanElement;
|
||||
let tooltipPosition = { align: 'center', vertical: 'top' };
|
||||
|
||||
function handleTouchStart() {
|
||||
async function handleTouchStart() {
|
||||
isLongPress = false;
|
||||
touchTimer = window.setTimeout(() => {
|
||||
touchTimer = window.setTimeout(async () => {
|
||||
showTooltip = true;
|
||||
isLongPress = true;
|
||||
updateTooltipPosition();
|
||||
await tick();
|
||||
await updateTooltipPosition();
|
||||
}, 500); // Show after 500ms press
|
||||
}
|
||||
|
||||
@@ -27,13 +30,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
async function handleClick() {
|
||||
// Toggle tooltip on click/tap
|
||||
if (!isLongPress) {
|
||||
showTooltip = !showTooltip;
|
||||
// Auto-hide after 3 seconds
|
||||
if (showTooltip) {
|
||||
updateTooltipPosition();
|
||||
await tick();
|
||||
await updateTooltipPosition();
|
||||
setTimeout(() => {
|
||||
showTooltip = false;
|
||||
}, 3000);
|
||||
@@ -42,34 +46,48 @@
|
||||
isLongPress = false;
|
||||
}
|
||||
|
||||
function handleMouseEnter() {
|
||||
async function handleMouseEnter() {
|
||||
showTooltip = true;
|
||||
// Use requestAnimationFrame to ensure DOM is updated before positioning
|
||||
requestAnimationFrame(() => updateTooltipPosition());
|
||||
await tick();
|
||||
await updateTooltipPosition();
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
showTooltip = false;
|
||||
}
|
||||
|
||||
function updateTooltipPosition() {
|
||||
async function updateTooltipPosition() {
|
||||
// Wait for next frame to ensure rendering is complete
|
||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||
|
||||
if (!tooltipElement || !wrapperElement) return;
|
||||
|
||||
const tooltipRect = tooltipElement.getBoundingClientRect();
|
||||
const wrapperRect = wrapperElement.getBoundingClientRect();
|
||||
const tooltipRect = tooltipElement.getBoundingClientRect();
|
||||
const viewportWidth = window.innerWidth;
|
||||
const viewportHeight = window.innerHeight;
|
||||
const padding = 10; // Minimum padding from screen edge
|
||||
const padding = 10;
|
||||
|
||||
// Check horizontal overflow
|
||||
// Calculate tooltip width and position
|
||||
const tooltipWidth = tooltipRect.width;
|
||||
const wrapperCenterX = wrapperRect.left + wrapperRect.width / 2;
|
||||
|
||||
// Determine horizontal alignment
|
||||
let align = 'center';
|
||||
if (tooltipRect.left < padding) {
|
||||
|
||||
// Check if center alignment would overflow
|
||||
const centerLeft = wrapperCenterX - tooltipWidth / 2;
|
||||
const centerRight = wrapperCenterX + tooltipWidth / 2;
|
||||
|
||||
if (centerLeft < padding) {
|
||||
// Would overflow left, align to left edge of wrapper
|
||||
align = 'left';
|
||||
} else if (tooltipRect.right > viewportWidth - padding) {
|
||||
} else if (centerRight > viewportWidth - padding) {
|
||||
// Would overflow right, align to right edge of wrapper
|
||||
align = 'right';
|
||||
}
|
||||
|
||||
// Check vertical overflow (if tooltip would go above viewport)
|
||||
// Check vertical overflow
|
||||
let vertical = 'top';
|
||||
if (tooltipRect.top < padding) {
|
||||
vertical = 'bottom';
|
||||
@@ -128,11 +146,13 @@
|
||||
padding: 0.5rem;
|
||||
z-index: 1000;
|
||||
width: max-content;
|
||||
max-width: 300px;
|
||||
max-width: min(300px, calc(100vw - 20px));
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Horizontal alignment variants */
|
||||
@@ -143,6 +163,7 @@
|
||||
|
||||
.tooltip-text.align-left {
|
||||
left: 0;
|
||||
right: auto;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@@ -218,7 +239,6 @@
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.tooltip-text {
|
||||
max-width: calc(100vw - 20px);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user