@beeanco/svelte-form

Easy forms in svelte

Documentation

Installation

With node.js installed, use npm to install this package and its peer dependencies:

npm install @beeanco/svelte-form yup

Usage

Basically you only need to use the createForm function to create a form using a yup schema and an action in your svelte component, and use it with the <Form /> component:

<script>
  import { createForm, Form } from '@beeanco/svelte-form';
  import { object, string } from 'yup';

  // Create a yup schema for your form
  const schema = object().shape({
    username: string().required(),
    password: string().required(),
  });

  // The action to run
  async function action(values) {
    console.info(values);
  }

  // Create the form object
  const form = createForm({ schema, action });
</script>

<Form {form}>
  <!-- Your inputs... -->
</Form>

The easiest way to add inputs and buttons to this form is to use @beeanco/svelte-bulma, which contains svelte components for the bulma CSS framework. Don't forget to npm install @beeanco/svelte-bulma!

<!-- LoginForm.svelte -->
<script>
  import { createForm, Form, FieldContext } from '@beeanco/svelte-form';
  import { FormField, ErrorMessage, SubmitField } from '@beeanco/svelte-bulma';
  import { object, string } from 'yup';

  // Create a yup schema for your form
  // (https://www.npmjs.com/package/yup)
  const schema = object().shape({
    username: string().label('Username').required(),
    password: string().label('Password').required(),
  });

  // The function to call with the resulting object
  async function action(values) {
    console.info('A user wants to log in with these credentials:', values);

    // You can call your API here...
    await new Promise((resolve) => setTimeout(resolve, 200));

    // ...and errors thrown here are reported.
    if (Math.random() > 0.5) {
      throw new Error('nope...');
    }
  }

  // Create the form object
  const form = createForm({ schema, action });

  // Get the field stores
  const { value: nameValue, error: nameError } = form.fields.get('username');
  const { value: passwordValue, error: passwordError } = form.fields.get('password');
</script>

<h1>Login to continue</h1>

<Form {form}>
  <FormField name="username" placeholder="Your Username" />
  <FormField name="password" placeholder="Your Password" />

  <ErrorMessage />

  <SubmitField label="Submit" />
</Form>

Of course you can use this package with other CSS frameworks as well. Just use the stores returned by the createForm function.

Complete example without bulma:

<!-- LoginForm.svelte -->
<script>
  import { createForm, Form } from '@beeanco/svelte-form';
  import { object, string } from 'yup';

  // Create a yup schema for your form
  // (https://www.npmjs.com/package/yup)
  const schema = object().shape({
    username: string().required(),
    password: string().required(),
  });

  // The function to call with the resulting object
  async function action(values) {
    console.info('A user wants to log in with these credentials:', values);

    // You can call your API here...
    await new Promise((resolve) => setTimeout(resolve, 200));

    // ...and errors thrown here are reported.
    if (Math.random() > 0.5) {
      throw new Error('nope...');
    }
  }

  // Create the form object
  const form = createForm({ schema, action });

  // Get the field stores
  const { value: nameValue, error: nameError } = form.fields.get('username');
  const { value: passwordValue, error: passwordError } = form.fields.get('password');
</script>

<h1>Login to continue</h1>

<!-- The <Form /> component sets up the svelte contexts -->
<Form {form} let:error let:submitting>
  <!-- let:values is also available -->

  <label>
    Username
    <input type="text" bind:value={$nameValue} />

    {#if $nameError}
      <strong>{$nameError.message}</strong>
    {/if}
  </label>

  <label>
    Password
    <input type="password" bind:value={$passwordValue} />

    {#if $passwordError}
      <strong>{$passwordError.message}</strong>
    {/if}
  </label>

  <label>
    {#if error}
      <strong>Oops! {error.message}</strong>
    {/if}

    {#if submitting}
      <i>Submitting...</i>
    {:else}
      <button type="submit">log in</button>
    {/if}
  </label>
</Form>

<style>
  /* Minimal styling */
  label {
    display: block;
  }
</style>