Skip to content

Commit 8d7dc29

Browse files
committed
Component event buble
1 parent 73d0197 commit 8d7dc29

File tree

10 files changed

+50
-11
lines changed

10 files changed

+50
-11
lines changed

packages/svelte2tsx/src/nodes/event-handler.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import { Node } from "estree-walker";
22

33
export function createEventHandlerTransformer() {
4-
const events = new Map<string, string>();
4+
const events = new Map<string, string | string[]>();
55

66
const handleEventHandler = (node: Node, parent: Node) => {
77
const eventName = node.name;
88

9-
// pass-through
9+
const handleEventHandlerBubble = () => {
10+
const componentEventDef = `__sveltets_instanceOf(${parent.name})`;
11+
const exp = `__sveltets_bubbleEventDef(${componentEventDef}, '${eventName}')`;
12+
13+
const exist = events.get(eventName);
14+
events.set(eventName, exist ? [].concat(exist, exp) : exp);
15+
};
16+
17+
// pass-through/ bubble
1018
if (!node.expression) {
1119
if (parent.type === "InlineComponent") {
12-
// TODO: component
20+
handleEventHandlerBubble();
1321
} else {
1422
events.set(
1523
eventName,

packages/svelte2tsx/src/svelte2tsx.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type TemplateProcessResult = {
4242
moduleScriptTag: Node;
4343
/** To be added later as a comment on the default class export */
4444
componentDocumentation: string | null;
45-
events: Map<string, string>;
45+
events: Map<string, string | string[]>;
4646
};
4747

4848
class Scope {
@@ -542,7 +542,7 @@ function processInstanceScriptContent(str: MagicString, script: Node): InstanceS
542542
if (
543543
(ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent)) &&
544544
parent.operator !==
545-
ts.SyntaxKind.ExclamationToken /* `!$store` does not need processing */
545+
ts.SyntaxKind.ExclamationToken /* `!$store` does not need processing */
546546
) {
547547
let simpleOperator: string;
548548
if (parent.operator === ts.SyntaxKind.PlusPlusToken) {
@@ -844,8 +844,8 @@ function addComponentExport(
844844

845845
const statement = `\n\n${doc}export default class ${
846846
className ? `${className} ` : ''
847-
}{\n $$prop_def = ${propDef}\n $$slot_def = render().slots` +
848-
`\n $on = __sveltets_eventDef(render().events).$on\n}`;
847+
}{\n $$prop_def = ${propDef}\n $$slot_def = render().slots` +
848+
`\n $on = __sveltets_eventDef(render().events).$on\n}`;
849849

850850
str.append(statement);
851851
}
@@ -905,7 +905,7 @@ function createRenderFunction(
905905
scriptTag: Node,
906906
scriptDestination: number,
907907
slots: Map<string, Map<string, string>>,
908-
events: Map<string, string>,
908+
events: Map<string, string | string[]>,
909909
exportedNames: ExportedNames,
910910
uses$$props: boolean,
911911
uses$$restProps: boolean,
@@ -945,9 +945,18 @@ function createRenderFunction(
945945
})
946946
.join(', ') +
947947
'}';
948-
const eventsDef = '{' + Array.from(events.entries())
949-
.map(([evnetName, expression]) => `'${evnetName}':${expression}`)
950-
.join(', ') + '}';
948+
949+
const eventMapEntryToString = ([evnetName, expression]: [
950+
string,
951+
string | string[]
952+
]) =>
953+
`'${evnetName}':${
954+
Array.isArray(expression) ? `[${expression}]` : expression
955+
}`;
956+
const eventsDef =
957+
"{" +
958+
Array.from(events.entries()).map(eventMapEntryToString).join(", ") +
959+
"}";
951960

952961
const returnString = `\nreturn { props: ${createPropsStr(
953962
exportedNames,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<></>;function render() {
2+
<><Button ></Button>
3+
<Radio ></Radio></>
4+
return { props: {}, slots: {}, events: {'click':[__sveltets_bubbleEventDef(__sveltets_instanceOf(Button), 'click'),__sveltets_bubbleEventDef(__sveltets_instanceOf(Radio), 'click')]} }}
5+
6+
export default class Input__SvelteComponent_ {
7+
$$prop_def = __sveltets_partial(render().props)
8+
$$slot_def = render().slots
9+
$on = __sveltets_eventDef(render().events).$on
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<Button on:click></Button>
2+
<Radio on:click></Radio>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<></>;function render() {
2+
<><Button ></Button></>
3+
return { props: {}, slots: {}, events: {'click':__sveltets_bubbleEventDef(__sveltets_instanceOf(Button), '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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Button on:click></Button>

0 commit comments

Comments
 (0)