Skip to content

Commit b171f2b

Browse files
committed
type check event bubbled from element on component
1 parent ec27301 commit b171f2b

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

packages/svelte2tsx/src/htmlxtojsx.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const stripDoctype = (str: MagicString) => {
2626
if (result) str.remove(result.index, result.index + result[0].length);
2727
};
2828

29-
// eslint-disable-next-line max-len
3029
export function convertHtmlxToJsx(
3130
str: MagicString,
3231
ast: Node,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Node } from 'estree-walker';
2+
3+
export function createEventHandlerTransformer() {
4+
const events = new Map<string, string>();
5+
6+
const handleEventHandler = (node: Node, parent: Node) => {
7+
const eventName = node.name;
8+
9+
// pass-through
10+
if (!node.expression) {
11+
if (parent.type === "Element") {
12+
events.set(eventName, `__sveltets_mapElementEvent('${eventName}')`);
13+
}
14+
}
15+
};
16+
17+
return {
18+
handleEventHandler,
19+
getEvents: () => events
20+
};
21+
}

packages/svelte2tsx/src/svelte2tsx.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { parseHtmlx } from './htmlxparser';
66
import { convertHtmlxToJsx } from './htmlxtojsx';
77
import { Node } from 'estree-walker';
88
import * as ts from 'typescript';
9+
import { createEventHandlerTransformer } from './nodes/event-handler';
910

1011
function AttributeValueAsJsExpression(htmlx: string, attr: Node): string {
1112
if (attr.value.length == 0) return "''"; //wut?
@@ -41,6 +42,7 @@ type TemplateProcessResult = {
4142
moduleScriptTag: Node;
4243
/** To be added later as a comment on the default class export */
4344
componentDocumentation: string | null;
45+
events: Map<string, string>;
4446
};
4547

4648
class Scope {
@@ -278,6 +280,8 @@ function processSvelteTemplate(str: MagicString): TemplateProcessResult {
278280
str.remove(node.start, node.end);
279281
};
280282

283+
const { handleEventHandler, getEvents } = createEventHandlerTransformer();
284+
281285
const onHtmlxWalk = (node: Node, parent: Node, prop: string) => {
282286
if (
283287
prop == 'params' &&
@@ -314,6 +318,9 @@ function processSvelteTemplate(str: MagicString): TemplateProcessResult {
314318
case 'ArrowFunctionExpression':
315319
enterArrowFunctionExpression();
316320
break;
321+
case 'EventHandler':
322+
handleEventHandler(node, parent);
323+
break;
317324
case 'VariableDeclarator':
318325
isDeclaration = true;
319326
break;
@@ -358,6 +365,7 @@ function processSvelteTemplate(str: MagicString): TemplateProcessResult {
358365
moduleScriptTag,
359366
scriptTag,
360367
slots,
368+
events: getEvents(),
361369
uses$$props,
362370
uses$$restProps,
363371
componentDocumentation,
@@ -897,6 +905,7 @@ function createRenderFunction(
897905
scriptTag: Node,
898906
scriptDestination: number,
899907
slots: Map<string, Map<string, string>>,
908+
events: Map<string, string>,
900909
exportedNames: ExportedNames,
901910
uses$$props: boolean,
902911
uses$$restProps: boolean,
@@ -936,10 +945,13 @@ function createRenderFunction(
936945
})
937946
.join(', ') +
938947
'}';
948+
const eventsDef = '{' + Array.from(events.entries())
949+
.map(([evnetName, expression]) => `'${evnetName}':${expression}`)
950+
.join(', ') + '}';
939951

940952
const returnString = `\nreturn { props: ${createPropsStr(
941953
exportedNames,
942-
)}, slots: ${slotsAsDef}, events: {} }}`;
954+
)}, slots: ${slotsAsDef}, events: ${eventsDef} }}`;
943955
str.append(returnString);
944956
}
945957

@@ -979,6 +991,7 @@ export function svelte2tsx(svelte: string, options?: { filename?: string; strict
979991
slots,
980992
uses$$props,
981993
uses$$restProps,
994+
events,
982995
componentDocumentation,
983996
} = processSvelteTemplate(str);
984997

@@ -1018,6 +1031,7 @@ export function svelte2tsx(svelte: string, options?: { filename?: string; strict
10181031
scriptTag,
10191032
instanceScriptTarget,
10201033
slots,
1034+
events,
10211035
exportedNames,
10221036
uses$$props,
10231037
uses$$restProps,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<></>;function render() {
2+
<><button onclick={undefined}></button></>
3+
return { props: {}, slots: {}, events: {'click':__sveltets_mapElementEvent('click')} }}
4+
5+
export default class Input__SvelteComponent_ {
6+
$$prop_def = __sveltets_partial(render().props)
7+
$$slot_def = render().slots
8+
$on = __sveltets_eventDef(render().events).$on
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button on:click></button>

0 commit comments

Comments
 (0)