4

i'm using clickOutside action bellow.

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);
    },
  };

This is the error that i still get, when i hover over on:clickoutside={() => {}}

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

I tried this in svelte kit app.d.ts

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

i tried also HTMLProps<T> and HTMLProps<HTMLDivElement> and many other variations and nothing works. I restarted ts server 25 times so it's not that. this is the link for docs

And no, this is not a duplicate because i literally went through all the other answers and they don't work. like this one: example

H.B.
  • 166,899
  • 29
  • 327
  • 400
dankobgd
  • 367
  • 3
  • 9
  • 31

2 Answers2

5

I actually just had the same issue, and the docs do offer a great solution. what I did was to modify my app.d.ts to include my interface. here is my action:

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

you can see that I have viewportEnter that needs to be used with on: in my html element The modified àpp.d.ts` looks like this:

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 {}

using it in my html element

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

and it works as expected.

Mohamad Ojail
  • 51
  • 1
  • 5
2

The correct current declaration should be:

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

(Older versions used a different namespace/types, see migration guide.)

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 1
    doesn't work, i tried that already. very strange – dankobgd Jul 18 '22 at 16:11
  • Do you get the error when running `svelte-check`? Are your packages and the Svelte extension up to date? You can also try to restart the Svelte language server, there is a command for that if you use the VS Code extension. – H.B. Jul 18 '22 at 16:16
  • yes all up to date, i also tried interface DOMAttributes { clickoutside?: (event: CustomEvent) => void; } that doesn't work. i restarted svelte and ts server and deleted all node_modules and .svelte-kit and every cache and still have an error. who cares ill leave it as it is, its not big of a deal for now, i will fix it later most likely by an accident. Thanks for help – dankobgd Jul 18 '22 at 16:22