# Tsurih

Svelte form validation library

- Minimalistic 🚐
- Type safe 🛟
- Small size 📦
- Ability to use custom validators ☘️
- Strategies 🎖️
- Helper functions 💪
- Focused on DX ❤️

Example 👇

```jsx
<script lang="ts">
  import { get } from "svelte/store";
  import { tsurih, debounce, validators } from "tsurih";
  import type { TConfig, TContext } from "tsurih";

  const debounced = debounce(() => {
    return new Promise<boolean>((res) =>
      setTimeout(() => {
        console.log("🚂");
        res(true);
      })
    );
  }, 2000);

  const customValidators = {
    debounce: (message?: string) => {
      return async (ctx: TContext<any, any, TConfig<any, any>>) => {
        const result = await debounced();

        const values = get(ctx.config.values);

        if (!result) {
          // ❌ Error
          return message || "Field is not valid";
        }

        // ✅ Success
        return "";
      };
    },
  };

  const form = tsurih({
      field1: true,
      field2: "",
    })
  .setSchema({
    field1: [validators.required()],
    field2: [
      validators.required(),
      (ctx) => {
        const values = get(ctx.config.values);

        if (!values.field1) {
          // ❌ Error
          return "Field is not valid";
        }

        // ✅ Success
        return "";
      },
      customValidators.debounce(),
    ],
  })
  .setStrategy("blur");

  $: watchOnlyField1 = $values.field1;

  $: {
    watchOnlyField1;
    form.revalidate("field2");
  }

  const { errors, isSubmitting, values } = form;
</script>

<form
  use:form.reg
  on:submit="{form.onSubmit((values) => {
    console.log(values);
  })}"
>
  <input
    type="checkbox"
    bind:checked="{$values.field1}"
    name="{form.fields.field1}"
  />

  {#if $errors.field1}
    <span>{$errors.field1}</span>
  {/if}

  <input bind:value="{$values.field2}" name="{form.fields.field2}" />

  {#if $errors.field2}
    <span>{$errors.field2}</span>
  {/if}

  {#if $isSubmitting}
    Submitting...
  {/if}

  <button type="submit">Submit</button>
</form>
```

☘️ tsurih also provides validators, isString, isNumber, isArray, isObject, debounce utilities

☘️ "validators" utility which has standard min, max, required, regexp, optionalMin, optionalRegexp.

☘️ An additional validator "optional" is not needed as all default fields are optional. But if you, for example, want min or regexp to be checked only if a value is present, use optionMin or optionalRegexp . If you are writing your own validator which should be optional, then it should have an if(!ctx.value) return "" condition

## Author

[Vladislav Yemelyanov](https://twitter.com/@hardwayder)

Released under the MIT License.
