diff --git a/packages/core/src/__tests__/__snapshots__/alpine.test.ts.snap b/packages/core/src/__tests__/__snapshots__/alpine.test.ts.snap
index 6e9edc2831..cd6b6c6471 100644
--- a/packages/core/src/__tests__/__snapshots__/alpine.test.ts.snap
+++ b/packages/core/src/__tests__/__snapshots__/alpine.test.ts.snap
@@ -5251,6 +5251,26 @@ exports[`Alpine.js > svelte > Javascript Test > eventHandlers 1`] = `
"
`;
+exports[`Alpine.js > svelte > Javascript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+"
+`;
+
exports[`Alpine.js > svelte > Javascript Test > html 1`] = `
"
+"
+`;
+
exports[`Alpine.js > svelte > Typescript Test > html 1`] = `
"
+"
+`;
+
exports[`Html > svelte > Javascript Test > html 1`] = `
"
+"
+`;
+
exports[`Html > svelte > Typescript Test > html 1`] = `
"
+
+
+"
+`;
+
exports[`Svelte > svelte > Javascript Test > html 1`] = `
"
+
+
+"
+`;
+
exports[`Svelte > svelte > Typescript Test > html 1`] = `
""
`;
+exports[`Vue > svelte > Javascript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+"
+`;
+
exports[`Vue > svelte > Javascript Test > html 1`] = `
"
@@ -6487,6 +6503,22 @@ function log(msg = \\"hello\\") {
"
`;
+exports[`Vue > svelte > Typescript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+"
+`;
+
exports[`Vue > svelte > Typescript Test > html 1`] = `
"
diff --git a/packages/core/src/__tests__/__snapshots__/vue.test.ts.snap b/packages/core/src/__tests__/__snapshots__/vue.test.ts.snap
index 2398040e8c..89a82cf1b0 100644
--- a/packages/core/src/__tests__/__snapshots__/vue.test.ts.snap
+++ b/packages/core/src/__tests__/__snapshots__/vue.test.ts.snap
@@ -7564,6 +7564,32 @@ export default defineComponent({
"
`;
+exports[`Vue > svelte > Javascript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+
+
+"
+`;
+
exports[`Vue > svelte > Javascript Test > html 1`] = `
"
@@ -8000,6 +8026,32 @@ export default defineComponent({
"
`;
+exports[`Vue > svelte > Typescript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+
+
+"
+`;
+
exports[`Vue > svelte > Typescript Test > html 1`] = `
"
diff --git a/packages/core/src/__tests__/__snapshots__/webcomponent.test.ts.snap b/packages/core/src/__tests__/__snapshots__/webcomponent.test.ts.snap
index 087f90e59a..18da35527e 100644
--- a/packages/core/src/__tests__/__snapshots__/webcomponent.test.ts.snap
+++ b/packages/core/src/__tests__/__snapshots__/webcomponent.test.ts.snap
@@ -26981,6 +26981,179 @@ customElements.define(\\"my-component\\", MyComponent);
"
`;
+exports[`webcomponent > svelte > Javascript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+
+
+ /**
+ * Usage:
+ *
+ *
+ *
+ */
+ class MyComponent extends HTMLElement {
+
+
+ get _root() {
+ return this.shadowRoot || this;
+ }
+
+ constructor() {
+ super();
+ const self = this;
+
+
+
+
+ this.state = { clickHandler1 : self.state.clickHandler1 = event => {
+ console.log(\\"do something 1\\");
+};
+
+self.update(), clickHandler2 : function clickHandler2(event) {
+ console.log(\\"do something 2\\");
+},};
+ if (!this.props) {
+ this.props = {};
+ }
+
+
+
+
+ // used to keep track of all nodes created by show/for
+ this.nodesToDestroy = [];
+ // batch updates
+ this.pendingUpdate = false;
+
+
+
+ // Event handler for 'click' event on button-my-component-1
+ this.onButtonMyComponent1Click = (event) => {
+
+ this.state.clickHandler1(event)
+ }
+
+ // Event handler for 'click' event on button-my-component-2
+ this.onButtonMyComponent2Click = (event) => {
+
+ this.state.clickHandler2(event)
+ }
+
+
+
+
+ if (undefined) {
+ this.attachShadow({ mode: 'open' })
+ }
+ }
+
+
+
+
+ destroyAnyNodes() {
+ // destroy current view template refs before rendering again
+ this.nodesToDestroy.forEach(el => el.remove());
+ this.nodesToDestroy = [];
+ }
+
+ connectedCallback() {
+
+
+
+ this._root.innerHTML = \`
+
+ \`;
+ this.pendingUpdate = true;
+
+ this.render();
+ this.onMount();
+ this.pendingUpdate = false;
+ this.update();
+
+ }
+
+
+
+
+
+ onMount() {
+
+ }
+
+ onUpdate() {
+
+ }
+
+ update() {
+ if (this.pendingUpdate === true) {
+ return;
+ }
+ this.pendingUpdate = true;
+ this.render();
+ this.onUpdate();
+ this.pendingUpdate = false;
+ }
+
+ render() {
+
+
+ // re-rendering needs to ensure that all nodes generated by for/show are refreshed
+ this.destroyAnyNodes();
+ this.updateBindings();
+
+
+ }
+
+
+ updateBindings() {
+
+
+ this._root.querySelectorAll(\\"[data-el='button-my-component-1']\\").forEach((el) => {
+ ;
+el.removeEventListener('click', this.onButtonMyComponent1Click);
+;
+el.addEventListener('click', this.onButtonMyComponent1Click)
+ })
+
+
+
+
+
+ this._root.querySelectorAll(\\"[data-el='button-my-component-2']\\").forEach((el) => {
+ ;
+el.removeEventListener('click', this.onButtonMyComponent2Click);
+;
+el.addEventListener('click', this.onButtonMyComponent2Click)
+ })
+
+
+ }
+
+ // Helper to render content
+ renderTextNode(el, text) {
+ const textNode = document.createTextNode(text);
+ if (el?.scope) {
+ textNode.scope = el.scope;
+ }
+ if (el?.context) {
+ textNode.context = el.context;
+ }
+ el.after(textNode);
+ this.nodesToDestroy.push(el.nextSibling);
+ }
+
+
+
+
+ }
+
+ customElements.define('my-component', MyComponent);
+ "
+`;
+
exports[`webcomponent > svelte > Javascript Test > html 1`] = `
"/**
* Usage:
@@ -29220,6 +29393,179 @@ customElements.define(\\"my-component\\", MyComponent);
"
`;
+exports[`webcomponent > svelte > Typescript Test > fatArrowFunctions 1`] = `
+"
+
+
+
+
+
+
+ /**
+ * Usage:
+ *
+ *
+ *
+ */
+ class MyComponent extends HTMLElement {
+
+
+ get _root() {
+ return this.shadowRoot || this;
+ }
+
+ constructor() {
+ super();
+ const self = this;
+
+
+
+
+ this.state = { clickHandler1 : self.state.clickHandler1 = event => {
+ console.log(\\"do something 1\\");
+};
+
+self.update(), clickHandler2 : function clickHandler2(event) {
+ console.log(\\"do something 2\\");
+},};
+ if (!this.props) {
+ this.props = {};
+ }
+
+
+
+
+ // used to keep track of all nodes created by show/for
+ this.nodesToDestroy = [];
+ // batch updates
+ this.pendingUpdate = false;
+
+
+
+ // Event handler for 'click' event on button-my-component-1
+ this.onButtonMyComponent1Click = (event) => {
+
+ this.state.clickHandler1(event)
+ }
+
+ // Event handler for 'click' event on button-my-component-2
+ this.onButtonMyComponent2Click = (event) => {
+
+ this.state.clickHandler2(event)
+ }
+
+
+
+
+ if (undefined) {
+ this.attachShadow({ mode: 'open' })
+ }
+ }
+
+
+
+
+ destroyAnyNodes() {
+ // destroy current view template refs before rendering again
+ this.nodesToDestroy.forEach(el => el.remove());
+ this.nodesToDestroy = [];
+ }
+
+ connectedCallback() {
+
+
+
+ this._root.innerHTML = \`
+
+ \`;
+ this.pendingUpdate = true;
+
+ this.render();
+ this.onMount();
+ this.pendingUpdate = false;
+ this.update();
+
+ }
+
+
+
+
+
+ onMount() {
+
+ }
+
+ onUpdate() {
+
+ }
+
+ update() {
+ if (this.pendingUpdate === true) {
+ return;
+ }
+ this.pendingUpdate = true;
+ this.render();
+ this.onUpdate();
+ this.pendingUpdate = false;
+ }
+
+ render() {
+
+
+ // re-rendering needs to ensure that all nodes generated by for/show are refreshed
+ this.destroyAnyNodes();
+ this.updateBindings();
+
+
+ }
+
+
+ updateBindings() {
+
+
+ this._root.querySelectorAll(\\"[data-el='button-my-component-1']\\").forEach((el) => {
+ ;
+el.removeEventListener('click', this.onButtonMyComponent1Click);
+;
+el.addEventListener('click', this.onButtonMyComponent1Click)
+ })
+
+
+
+
+
+ this._root.querySelectorAll(\\"[data-el='button-my-component-2']\\").forEach((el) => {
+ ;
+el.removeEventListener('click', this.onButtonMyComponent2Click);
+;
+el.addEventListener('click', this.onButtonMyComponent2Click)
+ })
+
+
+ }
+
+ // Helper to render content
+ renderTextNode(el, text) {
+ const textNode = document.createTextNode(text);
+ if (el?.scope) {
+ textNode.scope = el.scope;
+ }
+ if (el?.context) {
+ textNode.context = el.context;
+ }
+ el.after(textNode);
+ this.nodesToDestroy.push(el.nextSibling);
+ }
+
+
+
+
+ }
+
+ customElements.define('my-component', MyComponent);
+ "
+`;
+
exports[`webcomponent > svelte > Typescript Test > html 1`] = `
"/**
* Usage:
diff --git a/packages/core/src/__tests__/syntax/svelte/fat-arrow.raw.svelte b/packages/core/src/__tests__/syntax/svelte/fat-arrow.raw.svelte
new file mode 100644
index 0000000000..a53eb7b80a
--- /dev/null
+++ b/packages/core/src/__tests__/syntax/svelte/fat-arrow.raw.svelte
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/packages/core/src/__tests__/test-generator.ts b/packages/core/src/__tests__/test-generator.ts
index b8b0519c6f..f987400088 100644
--- a/packages/core/src/__tests__/test-generator.ts
+++ b/packages/core/src/__tests__/test-generator.ts
@@ -130,6 +130,7 @@ const SVELTE_SYNTAX_TESTS: Tests = {
slots: getRawFile('./syntax/svelte/slots.raw.svelte'),
style: getRawFile('./syntax/svelte/style.raw.svelte'),
textExpressions: getRawFile('./syntax/svelte/text-expressions.raw.svelte'),
+ fatArrowFunctions: getRawFile('./syntax/svelte/fat-arrow.raw.svelte'),
};
const BASIC_TESTS: Tests = {
diff --git a/packages/core/src/parsers/svelte/instance/index.ts b/packages/core/src/parsers/svelte/instance/index.ts
index 137bd9201a..678187836d 100644
--- a/packages/core/src/parsers/svelte/instance/index.ts
+++ b/packages/core/src/parsers/svelte/instance/index.ts
@@ -115,8 +115,12 @@ const handleStatement: InstanceHandler = (json, node, parent) => {
};
export function parseInstance(ast: Ast, json: SveltosisComponent) {
+ const nodeList :BaseNode[] = []
+ let currentIndex :number = 0
walk(ast.instance as BaseNode, {
enter(node, parent) {
+ nodeList.push(node) // memorize node, for easier traversal
+ currentIndex++
switch (node.type) {
case 'ImportDeclaration':
handleImportDeclaration(json, node as ImportDeclaration);
@@ -127,6 +131,12 @@ export function parseInstance(ast: Ast, json: SveltosisComponent) {
case 'ExpressionStatement':
handleExpressionStatement(json, node as ExpressionStatement, parent);
break;
+ case 'ArrowFunctionExpression':
+ const parentIndexModifier :number = 3
+ // TODO: May cause problems on VariableDeclarations like `const foo, bar = () => {}` or on destructured Variables..
+ parent.type === 'VariableDeclarator' && handleFunctionDeclaration(json, nodeList[currentIndex - parentIndexModifier] as FunctionDeclaration);
+ // Do nothing if this was an IIFE
+ break;
case 'FunctionDeclaration':
handleFunctionDeclaration(json, node as FunctionDeclaration);
break;
diff --git a/packages/core/src/parsers/svelte/instance/references.ts b/packages/core/src/parsers/svelte/instance/references.ts
index ed9f64d85d..32e397fc4e 100644
--- a/packages/core/src/parsers/svelte/instance/references.ts
+++ b/packages/core/src/parsers/svelte/instance/references.ts
@@ -62,6 +62,12 @@ export function parseReferences(json: SveltosisComponent, node: VariableDeclarat
code = parseObjectExpression(json, declaration.init);
break;
}
+ case 'ArrowFunctionExpression': {
+ code = generate(node);
+ type = 'function';
+
+ break;
+ }
case 'FunctionExpression': {
declaration.init.id = declaration.id as Identifier;
code = generate(declaration.init);