-
-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support custom events on native DOM elements #431
Comments
Don't know if there is a way to make it only applies to elements with the action. but you can make it globally available like this. declare namespace svelte.JSX {
interface HTMLAttributes<T> {
onswipemove?: (event: CustomEvent<number> & { target: EventTarget & T }) => any;
}
} |
We could also enhance our typings with "fall back to |
Thanks, letting the user explicitly type the action or explicitly choose when to fall back to |
I had a look at this again and now I'm split on what's the best way forward. Option 1: Silence errorWe could silence the error if it's a Option 2: Add
|
My latest idea for this is to
Edit: I just realized this would break people who enhanced the definition with their own, because we don't know of those and would still transform to the |
Svelte is very dynamic in its nature. One feature is to add actions to DOM elements which in turn means additional events could be dispatched on that element. For the default namespace, transform unknown events on an element with an action so that they are treated as custom events. sveltejs#431
Hey there, I was wondering if the solution suggested by @jasonlyu123 is still the only fix for this problem? |
It's still the solution, yes. I would appreciate some feedback on the three options listed in my comment above. I lean more and more towards option 3 since it matches the dynamic nature of Svelte the best, and typos are very rare I guess. |
@dummdidumm Personally, I'm an everything-should-be-as-type-safe-as-possible kinda guy, so I think rather than falling back to Now, I have no idea how difficult or tricky this would be to implement. It might actually be a terrible idea. Let me know what you think. If this isn't feasible, I agree that the 3rd approach among the ones you proposed in this comment would be the sanest. |
Yes what you describe would be ideal, but from a typing perspective I don't see a way to accomplish it, because one can only retrieve the return type of the function. One possibility would be to check if there's a property on the function which is only used for type checking, similar to how Angular does it. But even if we do that, then there's the bubble thing, which is just impossible in my mind to do, because we more or less have to statically analyze everything as a whole, and even that might not work for all cases. |
We could use the enhanced type signatures to tell |
what about returning some metadata from the action itself i.e.: return {
... // destroy, update, etc.
events: {
allowAll: false,
definitions: [
{ name: "panstart", maxRate: 3 },
...
]
}
} another option would be to include them as parameters: type ClickEventDetails = HeldClickedEventDetails & { secondsSinceLast: number }
type ClickHeldEventDetails = { count: number }
type ClickHoldReleasedEventDetails = ClickEventDetails & { totalHoldSeconds: number }
function extraClickEvents(node: Node, countableClick: CustomEvent<ClickEventDetais>, clickHeld: CustomEvent<ClickHeldEventDetails>, clickHoldReleased: CustomEvent<ClickHoldReleasedDetails>) {
...
node.dispatchEvent(nameof(countableClick).toLower(), countableClick.setDetails({ count: ..., secondsSinceLast: ... })) // toLower just represents the concept of lowercasing.
...
} then: <div use:extraclickevents on:countableclick={...} ...> |
I like the "use return type to hint at this"-idea. How this could be implemented:
The limitation of this is that you can create actions which coordinate across multiple/parent nodes and therefore only works if the event is listened to on the same node the action was applied to. |
I do think it would be too narrow. What if I'm invoking some other event through the normal dom methods? What if the event originates from a child element? To handle this, I've resorted to manually adding & removing event listeners to element references. Not ideal. |
Dumping this here for myself for later on: A way when using the new transformation on how to get the types of an action onto the element where the action is applied: type SvelteAction<U extends any, El extends any> = (node: El, args:U) => {
update?: (args:U) => void,
destroy?: () => void,
attributes?: Record<string, any>,
events?: Record<string, any>
} | void
export type ValuesOf<T> = T[keyof T];
export type ObjectValuesOf<T extends Object> = Exclude<
Exclude<Extract<ValuesOf<T>, object>, never>,
Array<any>
>;
declare function createElement<Elements extends IntrinsicElements, Key extends keyof Elements, Actions extends Record<string, SvelteActionReturn>>(
element: Key,
actions: Actions,
attrs: Elements[Key] & ObjectValuesOf<
{[ActionKey in keyof Actions]:
{[AttrKey in keyof Actions[ActionKey]['attributes']]: Actions[ActionKey]['attributes'][AttrKey] } &
{[EvtKey in keyof Actions[ActionKey]['events'] as `on:${EvtKey & string}`]: Actions[ActionKey]['events'][EvtKey]
}
}>
): Key extends keyof ElementTagNameMap ? ElementTagNameMap[Key] : Key extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[Key] : HTMLElement; This monstrosity will allow events and attributes returned by the action type to be added as attributes in addition to the intrinsic attributes. |
Another place where this falls down is bubbled native events. In my app I am listening to the And in this case, the JSX method only works with |
The error is correct. The type of Input event is only |
Is your feature request related to a problem? Please describe.
I get the following error when I'm trying to add custom events on native DOM elements:
The custom events are dispatched to a
div
element using Sveltes actions/use directive https://svelte.dev/examples#actions).Describe the solution you'd like
Be able to type check for custom events dispatched using Svelte actions on native DOM elements.
Describe alternatives you've considered
I could try to convert the div to an individual Svelte component but preferably it should work on native DOM elements as well.
Additional context
This is how I listen to the custom events:
Related Pull Request for custom events on Svelte components: #303
The text was updated successfully, but these errors were encountered: