Búsqueda de sitios web

Evento de acción personalizada tipo Svelte (svelte-kit) con TypeScript


Estoy usando la acción clickOutside abajo.

export function clickOutside(node: HTMLElement) {
 function detect({ target }: MouseEvent) {
   if (!node.contains(target as Node)) {
     node.dispatchEvent(new CustomEvent('clickoutside'));
    }
  }
   document.addEventListener('click', detect, { passive: true, capture: true });
   return {
     destroy() {
       document.removeEventListener('click', detect);
    },
  };

Este es el error que todavía obtengo, cuando paso el cursor sobre on:clickoutside={() => {}}

Type '{ onclickoutside: () => void; class: string; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onclickoutside' does not exist on type 'HTMLProps<HTMLDivElement>'}

Probé esto en svelte kit app.d.ts

declare namespace svelte.JSX {
  interface HTMLAttributes<T> {
    clickoutside?: (event: CustomEvent) => void;
  }
}

También probé HTMLProps<T> y HTMLProps<HTMLDivElement> y muchas otras variaciones y nada funciona. Reinicié el servidor de ts 25 veces, así que no es eso. Este es el enlace para la documentación

Y no, esto no es un duplicado porque literalmente revisé todas las otras respuestas y no funcionan. como esta: ejemplo

Respuesta #1

De hecho, acabo de tener el mismo problema, y los documentos ofrecen una gran solución. Lo que hice fue modificar mi app.d.ts para incluir mi interfaz. Aquí está mi acción:

import { browser } from '$app/environment'

let iob: IntersectionObserver

const initializeIob = () => {
  console.log('called')

  iob = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      const customEventName = entry.isIntersecting
        ? 'viewportEnter'
        : 'viewportExit'
      entry.target.dispatchEvent(new CustomEvent(customEventName))
    })
  })
}

const viewport = (element: HTMLElement) => {
  if (!iob && browser) initializeIob()

  iob.observe(element)

  return {
    destroy() {
      iob.unobserve(element)
    },
  }
}

export default viewport

Puedes ver que tengo viewportEnter que debe usarse con on: en mi elemento HTML. El archivo àpp.d.ts modificado se ve así:

declare global {
  namespace App {
    // interface Error {}
    // interface Locals {}
    // interface PageData {}
    // interface Platform {}
  }
  namespace svelteHTML {
    interface HTMLAttributes<T> {
      'on:viewportEnter'?: (event: CustomEvent) => void
      'on:viewportExit'?: (event: CustomEvent) => void
    }
  }
}

export {}

usándolo en mi elemento html

<h1
  style="text-align: center;"
  use:viewport
  on:viewportEnter={() => {
    console.log("Entered");
  }}
  on:viewportExit={() => {
    console.log("Exit");
  }}
>
  Hello Actions with Intersection observer!
</h1>

y funciona como se espera.

Respuesta #2

La declaración correcta actual debería ser:

declare namespace svelteHTML {
    interface HTMLAttributes<T> {
        'on:clickoutside'?: (event: CustomEvent) => void;
    }
}

(Las versiones anteriores usaban un espacio de nombres/tipos diferente, consulte la guía de migración.)

Artículos relacionados