Модальные окна (modals) являются ключевым элементом интерфейсов, обеспечивая контекстное взаимодействие с пользователем без перехода на другие страницы. В SvelteKit их реализация строится на компонентной архитектуре с использованием реактивных переменных и событий.
Для начала создается компонент Modal.svelte:
<script>
export let isOpen = false;
export let title = '';
export let onCl ose = () => {};
</script>
{#if isOpen}
<div class="modal-backdrop" on:click="{onClose}"></div>
<div class="modal">
<header class="modal-header">
<h2>{title}</h2>
<button class="close-button" on:click="{onClose}">×</button>
</header>
<div class="modal-body">
<slot></slot>
</div>
</div>
{/if}
<style>
.modal-backdrop {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
}
.modal {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
background: #fff;
border-radius: 8px;
width: 400px;
max-width: 90%;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
border-bottom: 1px solid #ddd;
}
.modal-body {
padding: 1rem;
}
.close-button {
background: transparent;
border: none;
font-size: 1.5rem;
cursor: pointer;
}
</style>
Ключевые моменты:
isOpen — реактивная переменная, управляющая видимостью
модального окна.onClose — callback-функция для закрытия окна.<slot> для вставки динамического
контента внутрь модального окна.В родительском компоненте создается переменная состояния и методы открытия и закрытия:
<script>
import Modal from './Modal.svelte';
let showModal = false;
function openModal() {
showModal = true;
}
function closeModal() {
showModal = false;
}
</script>
<button on:click="{openModal}">Открыть модальное окно</button>
<Modal isOpen="{showModal}" title="Пример модального окна" onCl ose="{closeModal}">
<p>Содержимое модального окна можно менять динамически.</p>
</Modal>
Использование реактивного состояния showModal
обеспечивает синхронизацию UI с внутренней логикой приложения без
сторонних библиотек управления состоянием.
Уведомления (notifications) и всплывающие подсказки (toasts) служат для краткого информирования пользователя о результатах действий или событиях системы. В SvelteKit их удобно реализовать с помощью store и компонентной системы.
// notifications.js
import { writable } from 'svelte/store';
export const notifications = writable([]);
export function addNotification({ message, type = 'info', duration = 3000 }) {
const id = Date.now();
notifications.update(n => [...n, { id, message, type }]);
setTimeout(() => removeNotification(id), duration);
}
export function removeNotification(id) {
notifications.update(n => n.filter(notification => notification.id !== id));
}
Особенности:
writable store позволяет реактивно
отображать список уведомлений.id, что упрощает
удаление.duration задает автоматическое скрытие уведомления
через заданное время.<script>
import { notifications, removeNotification } from './notifications.js';
import { fly } from 'svelte/transition';
</script>
<div class="notifications-container">
{#each $notifications as notif (notif.id)}
<div class="notification {notif.type}" transition:fly="{{ y: -20, duration: 300 }}">
<span>{notif.message}</span>
<button class="close" on:click="{() => removeNotification(notif.id)}">×</button>
</div>
{/each}
</div>
<style>
.notifications-container {
position: fixed;
top: 1rem;
right: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
z-index: 1000;
}
.notification {
padding: 0.75rem 1rem;
border-radius: 6px;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
.notification.info { background: #3498db; }
.notification.success { background: #2ecc71; }
.notification.warning { background: #f1c40f; color: #000; }
.notification.error { background: #e74c3c; }
.close {
background: transparent;
border: none;
font-size: 1rem;
cursor: pointer;
color: inherit;
}
</style>
<script>
import { addNotification } from './notifications.js';
function showSuccess() {
addNotification({ message: 'Данные успешно сохранены', type: 'success' });
}
function showError() {
addNotification({ message: 'Ошибка при сохранении', type: 'error' });
}
</script>
<button on:click="{showSuccess}">Показать успех</button>
<button on:click="{showError}">Показать ошибку</button>
Преимущества такой архитектуры:
Модальные окна и уведомления часто работают совместно. Например, при подтверждении действия в модальном окне можно сразу показывать уведомление:
<Modal isOpen="{showModal}" title="Удаление элемента" onCl ose="{closeModal}">
<p>Вы действительно хотите удалить этот элемент?</p>
<button on:click="{() => { deleteItem(); addNotification({ message: 'Элемент удален', type: 'success' }); closeModal(); }}">
Подтвердить
</button>
</Modal>
Ключевые моменты интеграции:
store
уведомлений.isOpen предотвращает
утечку событий и обеспечивает правильное управление UI.SvelteKit предоставляет встроенные transition и animate функции, которые легко интегрируются с модальными окнами и уведомлениями:
<div class="modal" transition:fade="{{ duration: 250 }}">
fade, fly, slide —
стандартные эффекты, которые можно комбинировать.tweened или spring.slot и store это
обеспечивает гибкость и масштабируемость интерфейса.Модальные окна и notifications в SvelteKit строятся вокруг реактивных переменных, store и компонентного подхода, что обеспечивает простоту управления состоянием, легкость интеграции и масштабируемость UI.