Headless компоненты — это компоненты, которые предоставляют функциональность и логику, не навязывая визуальный стиль. В контексте SvelteKit и библиотеки Melt UI они позволяют создавать интерфейсы с полной кастомизацией внешнего вида, сохраняя при этом корректное управление состоянием, доступностью и событиями.
Состояние отдельно от отображения Melt UI разделяет логическую часть компонента и его рендеринг. Headless-компонент управляет состоянием (например, открытие/закрытие модального окна, выбор элементов в списке), но не задаёт стили.
Аccessibility по умолчанию Компоненты Melt UI
реализуют ARIA-атрибуты, клавиатурную навигацию и другие практики
доступности. Например, Dropdown headless-компонент
обеспечивает правильное поведение при навигации с клавиатуры без
необходимости ручного внедрения обработчиков.
Composable API Каждый headless-компонент
предоставляет составные подкомпоненты и функции для
управления состоянием, что позволяет гибко строить интерфейс. Например,
useDialog() возвращает методы open,
close и состояние isOpen, которые можно
интегрировать с любым HTML или Svelte компонентом.
<script lang="ts">
import { createDialog } from '@melt-ui/dialog';
const dialog = createDialog();
</script>
<button on:click={dialog.open}>Открыть диалог</button>
{#if dialog.isOpen}
<div role="dialog" aria-modal="true">
<h2>Заголовок модального окна</h2>
<p>Содержимое диалога с полностью настраиваемым стилем.</p>
<button on:click={dialog.close}>Закрыть</button>
</div>
{/if}
createDialog() управляет состоянием и событиями.role="dialog" и aria-modal="true"
обеспечивают корректную доступность.<script lang="ts">
import { createDropdown } from '@melt-ui/dropdown';
const dropdown = createDropdown();
</script>
<div>
<button on:click={dropdown.toggle} aria-haspopup="listbox" aria-expanded={dropdown.isOpen}>
Выбрать элемент
</button>
{#if dropdown.isOpen}
<ul role="listbox">
{#each ['Элемент 1', 'Элемент 2', 'Элемент 3'] as item}
<li role="option" on:click={() => dropdown.select(item)}>
{item}
</li>
{/each}
</ul>
{/if}
</div>
createDropdown() предоставляет методы
toggle, select, close и состояние
isOpen.Headless компоненты Melt UI для форм позволяют управлять состоянием input, select, checkbox, radio, сохраняя ARIA-совместимость:
<script lang="ts">
import { createCheckbox } from '@melt-ui/checkbox';
const checkbox = createCheckbox({ checked: false });
</script>
<label>
<input type="checkbox" bind:checked={checkbox.checked} on:change={checkbox.toggle} />
Согласен с условиями
</label>
createCheckbox() управляет состоянием
checked и событиями.Melt UI позволяет комбинировать headless-компоненты через слоты и render props, сохраняя контроль над визуальной частью:
<script lang="ts">
import { createTabs } from '@melt-ui/tabs';
const tabs = createTabs();
</script>
<div>
{#each tabs.list as tab}
<button on:click={() => tabs.select(tab.id)} class:active={tabs.selected === tab.id}>
{tab.label}
</button>
{/each}
<div>
{#each tabs.list as tab}
{#if tabs.selected === tab.id}
<div>{tab.content}</div>
{/if}
{/each}
</div>
</div>
$:) для
интеграции с headless API, минимизируя количество лишнего кода.Headless подход Melt UI превращает SvelteKit проекты в гибкую платформу для кастомных интерфейсов с полной доступностью и управлением состоянием, без ограничений готовой визуальной реализации.