Nutritious Pumpkin Meal

    @thatconference/sveltejs-forms

    2.1.4 • Public • Published

    sveltejs-forms

    npm npm bundle size npm

    GitHub Actions Status codecov

    Declarative forms for Svelte.

    DEMO

    Features

    • optional schema-based validation through Yup
    • access to nested properties using paths
    • supports custom components
    • provides Input, Select, Choice components to reduce boilerplate

    Install

    $ npm i sveltejs-forms

    or

    $ yarn add sveltejs-forms

    How to use

    With provided Input, Select, Choice helper components

    <script>
      import { Form, Input, Select, Choice } from 'sveltejs-forms';
      import yup from 'yup@0.27';
    
      function handleSubmit({ detail: { values, setSubmitting, resetForm } }) {
        setTimeout(() => {
          console.log(values);
          setSubmitting(false);
          resetForm({
            user: { email: 'test@user.com' }, // optional
          });
        }, 2000);
    
        /**
         * {
         *   user: {
         *    email: 'email@example.com'
         *   },
         *   password: '123456',
         *   language: 'svelte',
         *   os: 'osx,linux'
         * }
         */
      }
    
      function handleReset() {
        console.log('form has been reset');
      }
    
      const schema = yup.object().shape({
        user: yup.object().shape({
          email: yup
            .string()
            .required()
            .email(),
        }),
        password: yup.string().min(4),
        language: yup.string().required(),
        os: yup.string(),
      });
    
      const langOptions = [
        { id: 'svelte', title: 'Svelte' },
        { id: 'react', title: 'React' },
        { id: 'angular', title: 'Angular' },
      ];
    
      const osOptions = [
        { id: 'macos', title: 'macOS' },
        { id: 'linux', title: 'Linux 🐧' },
        { id: 'windows', title: 'Windows' },
      ];
    
      const initialValues = {
        language: 'svelte',
      };
    </script>
    
    <style>
      :global(.sveltejs-forms) {
        background-color: #f8f8f8;
        display: inline-block;
        padding: 1rem;
        border: 1px solid #ccc;
        border-radius: 5px;
      }
    
      :global(label) {
        font-size: 0.8rem;
        color: #888;
        margin-bottom: 0.2rem;
      }
    
      :global(.message) {
        font-size: 0.8rem;
        color: #888;
        margin: 0.2rem 0;
        color: #f56565;
      }
    
      :global(input[type='text']),
      :global(textarea),
      :global(select) {
        width: 100%;
        background-color: white;
        margin: 0;
      }
    
      :global(input[type='checkbox'] + label) {
        display: inline-block;
        margin-right: 2rem;
      }
    
      :global(.field) {
        margin-bottom: 1rem;
      }
    	
      button {
        border-radius: 5px;
        padding: 0.5rem 1rem;
        margin-right: 1rem;
        color: white;
      }
    
      button[type='reset'] {
        background-color: #f56565;
      }
    
      button[type='submit'] {
        background-color: #48bb78;
        width: 80px;
      }
    </style>
    
    <Form
      {schema}  <!-- optional -->
      {initialValues} <!-- optional -->
      validateOnBlur={false} <!-- optional, default: true -->
      validateOnChange={false} <!-- optional, default: true -->
      on:submit={handleSubmit}
      on:reset={handleReset}
      let:isSubmitting
      let:isValid
    >
      <Input
        name="user.email" <!-- nested field -->
        label="Email Address"
        value="test@user.com" <!-- initial value -->
        placeholder="e.g. user@example.com" />
      <Input name="password" type="password" placeholder="Password" />
      <Select name="language" options={langOptions} />
      <Choice
        name="os"
        options={osOptions}
        disabled
        multiple />
      <button type="reset">Reset</button>
      <button type="submit" disabled={isSubmitting}>Sign in</button>
      <div>The form is valid: {isValid}</div>
    </Form>

    With custom component:

    <script>
      import { Form } from 'sveltejs-forms';
      import Select from 'svelte-select';
      import yup from 'yup@0.27';
    
      let svelteSelect;
    
      function handleSubmit({ detail: { values, setSubmitting, resetForm } }) {
        setTimeout(() => {
          console.log(values);
          setSubmitting(false);
          svelteSelect.handleClear();
          resetForm();
        }, 2000);
      }
    
      const schema = yup.object().shape({
        food: yup.string().required()
      });
    
      let items = [
        { value: 'chocolate', label: 'Chocolate' },
        { value: 'pizza', label: 'Pizza' },
        { value: 'cake', label: 'Cake' },
        { value: 'chips', label: 'Chips' },
        { value: 'ice-cream', label: 'Ice Cream' },
      ];
    </script>
    
    <Form
      {schema}
      on:submit={handleSubmit}
      let:isSubmitting
      let:setValue
      let:values
      let:errors
      let:touched>
    
      <Select
        {items}
        bind:this={svelteSelect}
        inputAttributes="{{ name: 'food' }}"
        hasError="{touched['food'] && errors['food']}"
        on:select="{({ detail }) => setValue('food', detail.value)}"
        on:clear="{() => setValue('food', '')}"
        selectedValue="{items.find(item => item.value === values['food'])}"/>
    
      <button type="submit" disabled={isSubmitting}>Submit</button>
    </Form>

    Slot props

    Name Type
    isSubmitting boolean
    isValid boolean
    setValue(path, value) function
    touchField(path) function
    validate() function
    values object
    errors object
    touched object

    Contributions

    All contributions are welcome.

    Install

    npm i @thatconference/sveltejs-forms

    DownloadsWeekly Downloads

    0

    Version

    2.1.4

    License

    MIT

    Unpacked Size

    328 kB

    Total Files

    15

    Last publish

    Collaborators

    • csell5
    • brettski