poppa / sveltekit-svg

SvelteKit plugin that makes it possible to import SVG files as Svelte components, inline SVG code or urls
MIT License
235 stars 23 forks source link

Use events on components #29

Closed YummYume closed 1 year ago

YummYume commented 1 year ago

Hello. Thank you for making this, it works like a charm.

I would really like however if we could also use regular Svelte events on imported components, as it does not seem like this is currently possible.

<script lang="ts">
    import Logo from '$components/icon/logo.svg?component';
</script>

<Logo on:mouseover={() => console.log('hovered')} /> // doesn't work

<svg on:mouseover={() => console.log('hovered')}>...</svg> // works

Or am I missing something?

Also as a side note, I think you should update your Typescript example by using something like the newly added svelte/elements types instead of ConstructorOfATypedSvelteComponent (which isn't recommended) :

declare module '*svg?component' {
  import type { ComponentType, SvelteComponentTyped } from 'svelte';
  import type { SVGAttributes } from 'svelte/elements';

  const content: ComponentType<SvelteComponentTyped<SVGAttributes<SVGSVGElement>>>;

  export default content;
}

This way you get full intellisense support like a normal svg tag.

poppa commented 1 year ago

Thanks for your feedback @YummYume.

I've fixed the type declaration. Thanks for the sample code 👍

Regarding propagating events on imported Svelte component, we'll that doesn't work on any component unless you specifically propagate the event from the imported component, right, because to my knowledge the event has to be attached to a DOM node. In your example <svg /> is a DOM node, hence it's working as expected.

Unless you can point me to some other plugin that solves this I'm afraid I will let this feature request be dormant until more people request it.

But I'm also more than happy to accept a PR for this feature.

YummYume commented 1 year ago

Hey, @poppa thanks for the response.

I understand the current situation is a bit complicated because there is no way to propagate all the events automatically to the svg DOM element. I looked at https://github.com/hperrin/svelte-material-ui/blob/273ded17c978ece3dd87f32a58dd9839e5c61325/components/forwardEvents.js to see how a library like SMUI does it but it seems pretty hacky.

As a solution, you can propagate all events by hand or add a prop which contains all the events you want to listen to. Either way, it doesn't seem like a proper way to do things in my opinion.

I suppose it's perfectly fine to add a parent node around the component as a workaround, it just needs to be carefully implemented (especially for accessibility).

Thanks for making things clear 👌

poppa commented 1 year ago

If someone finds a way to implement this without hacks I'm more than happy to re-open this issue 👍