Модальные окна являются ключевым элементом интерфейсов, позволяя отображать важную информацию, формы или подтверждения действий, блокируя при этом взаимодействие с остальной частью страницы. В SvelteKit модальные компоненты реализуются с использованием реактивных переменных, условного рендеринга и библиотек UI, которые предоставляют готовые стилизованные элементы.
В Svelte условный рендеринг выполняется через конструкцию
{#if ...}{/if}. Основная логика открытия модального окна
заключается в хранении состояния isOpen и контроле его
изменения:
<script>
let isOpen = false;
function openModal() {
isOpen = true;
}
function closeModal() {
isOpen = false;
}
</script>
<button on:click={openModal}>Открыть модальное окно</button>
{#if isOpen}
<div class="modal-backdrop" on:click={closeModal}>
<div class="modal-content" on:click|stopPropagation>
<h2>Заголовок модального окна</h2>
<p>Содержимое модального окна.</p>
<button on:click={closeModal}>Закрыть</button>
</div>
</div>
{/if}
Ключевые моменты:
on:click|stopPropagation предотвращает закрытие окна
при клике на его содержимое.modal-backdrop служит затемнённым фоном и ловит клики
вне окна.Библиотеки компонентов, такие как Svelte Material UI (SMUI), Flowbite-Svelte или Svelte Headless UI, предоставляют готовые модальные компоненты с расширенными возможностями: анимациями, доступностью для клавиатуры и стилями по умолчанию.
Пример модального окна с использованием SMUI:
<script>
import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@smui/dialog';
let open = false;
</script>
<Button on:click={() => open = true}>Открыть диалог</Button>
<Dialog bind:open>
<DialogTitle>Диалоговое окно</DialogTitle>
<DialogContent>
<p>Здесь может быть форма или уведомление.</p>
</DialogContent>
<DialogActions>
<Button on:click={() => open = false}>Отмена</Button>
<Button on:click={() => { /* действие */ open = false }}>Подтвердить</Button>
</DialogActions>
</Dialog>
Особенности подхода через UI-библиотеки:
SvelteKit предоставляет встроенные функции анимации через директиву
transition. Для плавного появления модального окна
используют, например, fade или fly:
<script>
import { fade, fly } from 'svelte/transition';
let isOpen = false;
</script>
<button on:click={() => isOpen = true}>Открыть</button>
{#if isOpen}
<div class="backdrop" on:click={() => isOpen = false} transition:fade>
<div class="modal" on:click|stopPropagation transition:fly={{ y: 20, duration: 300 }}>
<h2>Модальное окно с анимацией</h2>
<button on:click={() => isOpen = false}>Закрыть</button>
</div>
</div>
{/if}
Рекомендации по анимациям:
fade используется для затемнённого фона.fly позволяет окну «вылетать» из точки появления.duration и easing настраиваются
индивидуально для плавности.В больших приложениях рекомендуется хранить состояние модальных окон в store, чтобы управлять их открытием глобально и передавать данные между компонентами:
// modalStore.js
import { writable } from 'svelte/store';
export const modal = writable({ isOpen: false, content: null });
// App.svelte
<script>
import { modal } from './modalStore';
import Modal from './Modal.svelte';
</script>
<Modal />
<button on:click={() => modal.set({ isOpen: true, content: 'Привет, мир!' })}>
Открыть модальное окно
</button>
Преимущества использования store:
Правильная реализация модальных окон требует соблюдения стандартов доступности:
role="dialog" для контейнера.aria-modal="true" чтобы информировать вспомогательные
технологии о блокировке фона.Пример с добавлением доступности:
<div class="modal" role="dialog" aria-modal="true">
<h2 id="modal-title">Доступное модальное окно</h2>
<p id="modal-desc">Описание содержимого окна.</p>
</div>
Модальные окна в SvelteKit при правильной организации становятся мощным инструментом для взаимодействия пользователя с приложением, сочетая реактивность, управляемость и визуальную выразительность интерфейса.