Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

How to add types to custom events in svelte actions and use directive

$
0
0

I am currently looking for a way to add types to the custom events emitted from the custom action to be used in use directive I am creating. Here is the snippet.

import { z } from "zod";const acceptedNodeNames = [  //"INPUT","SELECT","TEXTAREA",];// prettier-ignoretype FormField =  | HTMLInputElement  | HTMLSelectElement  | HTMLTextAreaElement;type SubmitConfig = {  schema: {    [key: string]: z.Schema;  };};export function form(node: HTMLFormElement, { schema }: SubmitConfig) {  // store fields that needs to be validated in array  const fields = Array.from(node.children).filter(    (child) => acceptedNodeNames.includes(child.nodeName) && (child as FormField).name in schema,  ) as FormField[];  function handleInput(this: FormField) {    const { name, value } = this;    const result = schema[name].safeParse(value);    if (result.success) {      this.removeAttribute("aria-invalid");    } else {      this.setAttribute("aria-invalid", "");    }  }  // attach field listeners  for (const field of fields) {    field.addEventListener("input", handleInput);  }  function handleSubmit(e: SubmitEvent) {    e.preventDefault();    const input = fields.reduce(      (obj, field) => ({        ...obj,        [field.name]: field.value,      }),      {},    );    const result = z.object(schema).safeParse(input);    if (result.success) {      const event = new CustomEvent("okay", { detail: { ...result } });      node.dispatchEvent(event);    } else {      const errors = JSON.parse(result.error.message);      for (const error of errors) {        const field = fields.find(({ name }) => name === error.path[0]);        if (!field) continue;        field.setAttribute("aria-invalid", "");      }      const event = new CustomEvent("fail", { detail: { errors } });      node.dispatchEvent(event);    }  }  // attach form submit handler  node.addEventListener("submit", handleSubmit);  return {    destroy() {      node.removeEventListener("submit", handleSubmit);      for (const field of fields) {        field.removeEventListener("input", handleInput);      }    },  };}

It basically just validates form field and uses zod underneath. This is how I would like to use it.

<form  novalidate  method="POST"  use:form={{    schema: {      email: z.string().email(),    },  }}  on:okay={(e) => {    console.log(e.detail);  }}  on:fail={(e) => {    console.log(e.detail);  }}>...</form>

This code is already working, but my only problem is that it doesn't have types and it got some annoying squiggly lines in vscode. Is there a way at the moment to declare a type to those custom events similar to adding types in svelte components like so

 interface $$Events {    change: CustomEvent<{      page: number;      pageSize: number;    }>;  }

Thanks!


Viewing all articles
Browse latest Browse all 1541

Trending Articles