Руководство по Svelte

Библиотека Svelte от Lily — эталонная реализация: руны Svelte 5, типизированные props, разворачивание остальных props и двусторонняя привязка с bind:value.

Что вы построите

Небольшая контактная форма — поле с меткой, кнопка отправки, двусторонняя привязка, реальное поведение клавиатуры и программы чтения с экрана — сначала голая, затем оформленная, примерно за 10 минут.

Прежде чем начать

Вам понадобятся git, Node 22 или новее и pnpm 10 или новее. Подойдёт любой проект Svelte 5 — достаточно совершенно нового npx sv create приложения.

Шаг 1 — Получите код

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-headless
pnpm install
pnpm test        # vitest — thousands of component cases
pnpm run storybook   # browse all 571 components

Компоненты находятся в src/lib/components/{Name}/, по одному каталогу на компонент с файлом .svelte , его тестами, историями и документацией рядом. Скопируйте нужные каталоги в своё приложение или зависьте от репозитория и импортируйте напрямую.

Шаг 2 — Ваш первый компонент

<script>
  import Button from "#lib/components/Button/Button.svelte";

  function save() { console.log("saved"); }
</script>

<Button onclick={save}>Save</Button>

Отображает <button class="button" type="button">. Props типизированы: type, disabled, pressed (отображает aria-pressed (отображает label ( aria-label для кнопок-переключателей),

Шаг 3 — Составьте небольшую форму

<script>
  import Form from "#lib/components/Form/Form.svelte";
  import Field from "#lib/components/Field/Field.svelte";
  import TextInput from "#lib/components/TextInput/TextInput.svelte";
  import Button from "#lib/components/Button/Button.svelte";

  let name = $state("");
</script>

<Form label="Contact form" onsubmit={handleSubmit}>
  <Field label="Full name" required>
    <TextInput id="name" label="Full name" bind:value={name} required />
  </Field>
  <Button type="submit">Save</Button>
</Form>

Field принимает видимую label как собственный prop, а не как вложенный компонент метки — передайте её один раз, на Fieldи TextInputиз label обеспечивает доступное имя. TextInput's value для переопределения), а любой дополнительный атрибут разворачивается на корне. $bindable — это prop bind:value руны, поэтому

Проверено 2026-08-29: сразу даёт вам двустороннюю привязку. svelte/server именно этот фрагмент был скомпилирован через <label for> и проверен на единственную, правильно связанную метку Label внутри Field— в более раннем черновике внутри был вложен отдельный две метки (одну пустую), потому что Field уже отображает свою собственную из входа label , что отображало Составной маршрут контактной формы — тот же шаблон, проверенный настоящими тестами e2e и axe.

Проверьте свою работу: запустите приложение, и форма выглядит голой — именно так, как задумано: оформление ещё впереди. Нажмите Tab: фокус проходит через каждый элемент управления, метка озвучивается, а отправка работает. Поведение готово; внешний вид за вами, и это следующий шаг.

Шаг 4 — Оформите её

Всё вышеперечисленное отображается как чистая структура, готовая для ваших стилей. Оформите крючки классов — .button, .text-input, .label, .field — в вашей глобальной таблице стилей, или подключите готовую тему в app.html:

<link rel="stylesheet" href="/themes/dark.css" />

Настройки для отдельного экземпляра проходят через class prop, который добавляется к базовому крючку: <Button class="wide"> отображает class="button wide".

Шаг 5 — Посмотрите, как всё работает

Пример приложения SvelteKit — тот же каталог, полностью оформленный, с живыми демонстрациями, тестами Playwright e2e и базовой линией доступности axe-core:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-sveltekit-examples
pnpm install && pnpm run dev

Дальнейшие шаги

Есть вопросы по ходу дела? Страница справки полна ответов — а если какой-то шаг можно сделать яснее, сообщите нам и мы с радостью улучшим руководство.