From 5fe799c1ab669b995bc483b25c07cb033eb25ed2 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Sat, 8 Aug 2020 08:16:46 +0200 Subject: [PATCH] (fix) bubble events (#433) * (fix) bubble events Added new property $$events_def to bubble events Also removed some obsolete types * add union type for multiple events --- packages/svelte2tsx/README.md | 6 +--- .../svelte2tsx/src/nodes/event-handler.ts | 22 ++++-------- packages/svelte2tsx/svelte-shims.d.ts | 35 +++++++++++-------- .../event-bubble-component-multi/expected.tsx | 2 +- .../event-bubble-component/expected.tsx | 2 +- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/packages/svelte2tsx/README.md b/packages/svelte2tsx/README.md index 29719f59a..59dcbd286 100644 --- a/packages/svelte2tsx/README.md +++ b/packages/svelte2tsx/README.md @@ -36,11 +36,7 @@ function render() { return { props: { world }, slots: {}, events: {} }; } -export default class { - $$prop_def = __sveltets_partial(render().props); - $$slot_def = render().slots - $on = __sveltets_eventDef(render().events).$on; -} +export default class _World_ extends createSvelte2TsxComponent(__sveltets_partial(render)) {} ``` with a v3 SourceMap back to the original source. diff --git a/packages/svelte2tsx/src/nodes/event-handler.ts b/packages/svelte2tsx/src/nodes/event-handler.ts index 9a83c5be8..cdb334beb 100644 --- a/packages/svelte2tsx/src/nodes/event-handler.ts +++ b/packages/svelte2tsx/src/nodes/event-handler.ts @@ -8,7 +8,8 @@ export function createEventHandlerTransformer() { const handleEventHandlerBubble = () => { const componentEventDef = `__sveltets_instanceOf(${parent.name})`; - const exp = `__sveltets_bubbleEventDef(${componentEventDef}.$on, '${eventName}')`; + // eslint-disable-next-line max-len + const exp = `__sveltets_bubbleEventDef(${componentEventDef}.$$events_def, '${eventName}')`; const exist = events.get(eventName); events.set(eventName, exist ? [].concat(exist, exp) : exp); @@ -19,10 +20,7 @@ export function createEventHandlerTransformer() { if (parent.type === 'InlineComponent') { handleEventHandlerBubble(); } else { - events.set( - eventName, - getEventDefExpressionForNonCompoent(eventName, parent) - ); + events.set(eventName, getEventDefExpressionForNonCompoent(eventName, parent)); } } }; @@ -47,17 +45,11 @@ function getEventDefExpressionForNonCompoent(eventName: string, ele: Node) { } export function eventMapToString(events: Map) { - return '{' + - Array.from(events.entries()).map(eventMapEntryToString).join(', ') + - '}'; - + return '{' + Array.from(events.entries()).map(eventMapEntryToString).join(', ') + '}'; } -function eventMapEntryToString([eventName, expression]: [ - string, - string | string[] -]) { +function eventMapEntryToString([eventName, expression]: [string, string | string[]]) { return `'${eventName}':${ - Array.isArray(expression) ? `[${expression}]` : expression - }`; + Array.isArray(expression) ? `__sveltets_unionType(${expression.join(',')})` : expression + }`; } diff --git a/packages/svelte2tsx/svelte-shims.d.ts b/packages/svelte2tsx/svelte-shims.d.ts index b25f26b55..b94d2c829 100644 --- a/packages/svelte2tsx/svelte-shims.d.ts +++ b/packages/svelte2tsx/svelte-shims.d.ts @@ -14,6 +14,11 @@ declare class Svelte2TsxComponent< * and does not exist at runtime. Don't use this property. */ $$prop_def: Props; + /** + * @internal This is for type checking capabilities only + * and does not exist at runtime. Don't use this property. + */ + $$events_def: Events; /** * @internal This is for type checking capabilities only * and does not exist at runtime. Don't use this property. @@ -41,7 +46,7 @@ declare class Svelte2TsxComponent< * Causes the callback function to be called whenever the component dispatches an event. * A function is returned that will remove the event listener when called. */ - $on(event: K, handler: (e: SvelteExtractEvent) => any): void; + $on(event: K, handler: (e: Events[K]) => any): void; /** * Causes the callback function to be called whenever the component dispatches an event. * A function is returned that will remove the event listener when called. @@ -87,14 +92,7 @@ type SvelteAnimation = (node: Element, move: { from: DOMRect, t type SvelteAllProps = { [index: string]: any } type SvelteRestProps = { [index: string]: any } type SvelteStore = { subscribe: (run: (value: T) => any, invalidate?: any) => any } -type SvelteEventRecord = Record -type SvelteExtractEvent = T extends any[] ? T[number] : T; -type SvelteOnEvent = ( - event: K, - handler: (e: SvelteExtractEvent) => any -) => () => void; -type SvelteRestEvent = (event: string, handler: (e: CustomEvent) => any) => () => void -type SvelteOnAllEvent = SvelteOnEvent & SvelteRestEvent + declare var process: NodeJS.Process & { browser: boolean } @@ -124,7 +122,7 @@ declare function __sveltets_any(dummy: any): any; declare function __sveltets_empty(dummy: any): {}; declare function __sveltets_componentType(): AConstructorTypeOf> declare function __sveltets_invalidate(getValue: () => T): T -declare function __sveltets_eventDef(def: T): SvelteOnAllEvent + declare function __sveltets_mapWindowEvent( event: K ): HTMLBodyElementEventMap[K]; @@ -143,11 +141,18 @@ declare function __sveltets_mapElementTag( declare function __sveltets_mapElementTag( tag: any ): HTMLElement; -declare function __sveltets_bubbleEventDef< - T extends SvelteEventRecord, - TEvent, - TKey extends keyof T = TEvent extends keyof T ? TEvent : string ->(on: SvelteOnAllEvent, event: TEvent): T[TKey]; + +declare function __sveltets_bubbleEventDef( + events: Events, eventKey: K +): Events[K]; +declare function __sveltets_bubbleEventDef( + events: any, eventKey: string +): any; + +declare function __sveltets_unionType(t1: T1, t2: T2): T1 | T2; +declare function __sveltets_unionType(t1: T1, t2: T2, t3: T3): T1 | T2 | T3; +declare function __sveltets_unionType(t1: T1, t2: T2, t3: T3, t4: T4): T1 | T2 | T3 | T4; +declare function __sveltets_unionType(...types: any[]): any; declare function __sveltets_awaitThen( promise: PromiseLike, diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-multi/expected.tsx b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-multi/expected.tsx index f4e062ba2..b22c016de 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-multi/expected.tsx +++ b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component-multi/expected.tsx @@ -1,7 +1,7 @@ <>;function render() { <> -return { props: {}, slots: {}, getters: {}, events: {'click':[__sveltets_bubbleEventDef(__sveltets_instanceOf(Button).$on, 'click'),__sveltets_bubbleEventDef(__sveltets_instanceOf(Radio).$on, 'click')]} }} +return { props: {}, slots: {}, getters: {}, events: {'click':__sveltets_unionType(__sveltets_bubbleEventDef(__sveltets_instanceOf(Button).$$events_def, 'click'),__sveltets_bubbleEventDef(__sveltets_instanceOf(Radio).$$events_def, 'click'))} }} export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(render)) { } diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component/expected.tsx b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component/expected.tsx index 988a8f5ba..e31369a2a 100644 --- a/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component/expected.tsx +++ b/packages/svelte2tsx/test/svelte2tsx/samples/event-bubble-component/expected.tsx @@ -1,6 +1,6 @@ <>;function render() { <> -return { props: {}, slots: {}, getters: {}, events: {'click':__sveltets_bubbleEventDef(__sveltets_instanceOf(Button).$on, 'click')} }} +return { props: {}, slots: {}, getters: {}, events: {'click':__sveltets_bubbleEventDef(__sveltets_instanceOf(Button).$$events_def, 'click')} }} export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(render)) { }