Tooltip — это всплывающая подсказка, которая отображается при наведении на элемент или взаимодействии с ним, предоставляя дополнительную информацию пользователю. В SvelteKit работа с tooltip становится гибкой и удобной благодаря реактивной модели и компонентной архитектуре.
В SvelteKit tooltip обычно реализуется как отдельный компонент, который управляет своим состоянием видимости через реактивные переменные или store. Ключевое отличие от традиционных библиотек — возможность легко связывать tooltip с любым DOM-элементом через binding и actions.
Пример базовой структуры компонента Tooltip:
<script>
import { onMount } from 'svelte';
export let text = '';
let visible = false;
function show() {
visible = true;
}
function hide() {
visible = false;
}
</script>
<div on:mouseenter={show} on:mouseleave={hide} class="tooltip-container">
<slot></slot>
{#if visible}
<div class="tooltip-content">{text}</div>
{/if}
</div>
<style>
.tooltip-container { position: relative; display: inline-block; }
.tooltip-content {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: #fff;
padding: 6px 12px;
border-radius: 4px;
white-space: nowrap;
font-size: 0.875rem;
z-index: 1000;
opacity: 0.9;
}
</style>
SvelteKit actions позволяют управлять tooltip без создания лишних обёрток. Это особенно полезно для динамически создаваемых элементов.
<script>
import { tooltip } from './tooltipAction.js';
</script>
<button use:tooltip={'Нажмите для сохранения'}>Сохранить</button>
tooltipAction.js может выглядеть так:
export function tooltip(node, text) {
let tooltipEl;
function mouseEnter() {
tooltipEl = document.createElement('div');
tooltipEl.textContent = text;
tooltipEl.className = 'tooltip-content';
node.appendChild(tooltipEl);
const rect = node.getBoundingClientRect();
tooltipEl.style.position = 'absolute';
tooltipEl.style.top = `${rect.top - tooltipEl.offsetHeight}px`;
tooltipEl.style.left = `${rect.left + rect.width / 2 - tooltipEl.offsetWidth / 2}px`;
}
function mouseLeave() {
tooltipEl?.remove();
tooltipEl = null;
}
node.addEventListener('mouseenter', mouseEnter);
node.addEventListener('mouseleave', mouseLeave);
return {
destroy() {
node.removeEventListener('mouseenter', mouseEnter);
node.removeEventListener('mouseleave', mouseLeave);
}
};
}
Tooltip должен правильно адаптироваться к положению окна и размеру элемента. Для этого часто используют реактивные вычисления координат и проверку границ viewport.
$: tooltipStyle = visible
? `top: ${elementRect.top - tooltipEl.offsetHeight}px; left: ${elementRect.left + elementRect.width / 2 - tooltipEl.offsetWidth / 2}px;`
: '';
Можно использовать сторонние утилиты, например Popper.js, для более сложного позиционирования с поддержкой смещений, выравнивания по краям и автоматического изменения направления при выходе за границы экрана.
SvelteKit обеспечивает плавные анимации через встроенные transitions. Для tooltip это особенно полезно, чтобы появление и исчезновение выглядело естественно:
<script>
import { fade } from 'svelte/transition';
</script>
{#if visible}
<div class="tooltip-content" transition:fade>{{text}}</div>
{/if}
Можно настраивать длительность и easing:
transition:fade={{ duration: 200, easing: cubicOut }}
Для глобальных tooltip, когда несколько элементов должны управляться централизованно, удобно использовать Svelte store:
import { writable } from 'svelte/store';
export const tooltipStore = writable({ text: '', visible: false, x: 0, y: 0 });
В компоненте можно подписываться на store и обновлять положение tooltip в реальном времени.
click или touchstart вместо hover для
устройств с сенсорными экранами.position: fixed для улучшения
производительности при скролле.{#if}.Tooltip в SvelteKit сочетает простоту реализации и гибкость настройки благодаря реактивности, компонентной архитектуре и возможностям actions и transitions. Это позволяет создавать как базовые, так и сложные динамические подсказки с минимальным количеством кода и высокой производительностью.