Компоненты форм

Компоненты форм в SvelteKit UI представляют собой абстракции для удобной работы с пользовательскими вводами, валидацией и управлением состоянием. Основная цель таких компонентов — минимизировать ручное управление DOM и состоянием, предоставляя декларативный подход к построению форм.

Управление состоянием формы

В SvelteKit состояние формы часто хранится в виде объекта, где каждый ключ соответствует полю формы. Для привязки значения к полю используется директива bind:value:

<script>
  let formData = {
    username: '',
    email: '',
    password: ''
  };
</script>

<form on:submit|preventDefault={() => handleSubmit(formData)}>
  <input type="text" bind:value={formData.username} placeholder="Имя пользователя" />
  <input type="email" bind:value={formData.email} placeholder="Email" />
  <input type="password" bind:value={formData.password} placeholder="Пароль" />
  <button type="submit">Отправить</button>
</form>

Ключевые моменты:

  • bind:value автоматически синхронизирует значение поля и состояние объекта.
  • Использование on:submit|preventDefault позволяет перехватывать событие отправки и управлять логикой обработки данных формы.

Компоненты полей

Библиотеки UI для SvelteKit предоставляют готовые компоненты полей, которые инкапсулируют поведение ввода, валидацию и стили. Наиболее часто встречаются:

  • TextInput — текстовое поле с поддержкой placeholder, маски, автозаполнения.
  • Checkbox — чекбокс с управлением состояния checked.
  • RadioGroup — группа радио-кнопок с синхронизацией выбранного значения.
  • Select — выпадающий список с возможностью мультивыбора.
  • Textarea — многострочное текстовое поле.

Пример использования компонента TextInput с кастомной валидацией:

<script>
  import { TextInput } from 'sveltekit-ui';
  
  let username = '';
  let error = '';
  
  function validate() {
    error = username.length < 3 ? 'Имя должно быть минимум 3 символа' : '';
  }
</script>

<TextInput
  bind:value={username}
  placeholder="Имя пользователя"
  on:blur={validate}
  {error}
/>

Особенности компонентов полей:

  • Поддержка событий on:blur, on:focus, on:input.
  • Возможность передачи кастомных сообщений об ошибках.
  • Стилизация через пропсы class или встроенные темы.

Валидация и управление ошибками

Современные библиотеки SvelteKit UI часто используют декларативную валидацию, позволяя описывать правила прямо в компоненте:

<TextInput
  bind:value={email}
  placeholder="Email"
  validators={[value => /\S+@\S+\.\S+/.test(value) || 'Неверный формат email']}
/>

Преимущества такого подхода:

  • Минимизация ручного кода для проверки каждого поля.
  • Автоматическое отображение ошибок рядом с полем.
  • Легкость интеграции с внешними библиотеками валидации (например, yup или zod).

Управление формой через FormProvider

Для больших форм используется паттерн FormProvider, который позволяет централизованно управлять состоянием, ошибками и отправкой формы:

<script>
  import { FormProvider, FormField, TextInput, Checkbox } from 'sveltekit-ui';

  let initialValues = { username: '', subscribe: false };

  function onSubmit(values) {
    console.log(values);
  }
</script>

<FormProvider {initialValues} on:submit={onSubmit}>
  <FormField name="username">
    <TextInput placeholder="Имя пользователя" />
  </FormField>
  
  <FormField name="subscribe">
    <Checkbox>Подписаться на новости</Checkbox>
  </FormField>
  
  <button type="submit">Сохранить</button>
</FormProvider>

Преимущества FormProvider:

  • Автоматическое связывание полей с состоянием формы.
  • Централизованная обработка ошибок.
  • Поддержка вложенных форм и динамических полей.

Динамические и повторяющиеся поля

SvelteKit UI поддерживает динамическое добавление полей, что особенно важно для массивов данных (например, список контактов):

<script>
  import { FormProvider, FormField, TextInput } from 'sveltekit-ui';
  let contacts = [''];
  
  function addContact() {
    contacts = [...contacts, ''];
  }
</script>

<FormProvider let:values>
  {#each contacts as contact, index}
    <FormField name={`contacts[${index}]`}>
      <TextInput bind:value={contacts[index]} placeholder="Контакт" />
    </FormField>
  {/each}
  <button type="button" on:click={addContact}>Добавить контакт</button>
</FormProvider>

Преимущества динамических полей:

  • Упрощение работы с массивами данных.
  • Автоматическая синхронизация состояния формы.
  • Интеграция с валидацией на уровне каждого элемента массива.

Поддержка тем и стилизация

Все компоненты форм поддерживают тематизацию и кастомные стили через пропсы:

  • class — стандартное добавление CSS-классов.
  • variant — выбор визуального варианта компонента (outline, filled, minimal).
  • size — размеры поля (sm, md, lg).
<TextInput
  bind:value={username}
  placeholder="Имя пользователя"
  variant="filled"
  size="md"
  class="my-custom-class"
/>

Тематизация позволяет поддерживать единый стиль интерфейса во всех формах приложения.

Асинхронная валидация

Некоторые библиотеки SvelteKit UI поддерживают асинхронную валидацию, например для проверки уникальности логина на сервере:

<TextInput
  bind:value={username}
  placeholder="Имя пользователя"
  asyncValidator={async value => {
    const res = await fetch(`/api/check-username?name=${value}`);
    const data = await res.json();
    return data.available || 'Имя занято';
  }}
/>

Такой подход позволяет интегрировать форму с серверной логикой без дублирования кода.

Итоговые рекомендации по использованию

  • Использовать bind:value для простых форм и FormProvider для сложных.
  • Валидацию выносить на уровень компонентов с кастомными или встроенными валидаторами.
  • Для массивов данных применять динамические поля с автоматической синхронизацией.
  • Стилевые пропсы и темы обеспечивают единообразный визуальный стиль интерфейса.

Эта архитектура компонентов форм в SvelteKit UI обеспечивает декларативный, модульный и масштабируемый подход к построению интерфейсов с минимальными усилиями по управлению состоянием и валидацией.