Skip to content

Commit

Permalink
Forward svelte custom events
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Nov 30, 2023
1 parent 1c2a65a commit 0039cfb
Show file tree
Hide file tree
Showing 8 changed files with 457 additions and 63 deletions.
52 changes: 41 additions & 11 deletions src/svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,27 @@ onMount(() => {
}
}

const events = [];
if (declaration.events) {
for (const event of declaration.events) {
events.push(`on:${event.name}`);
}
}

const markup = definition.extend
? `<${definition.extend} bind:this={__ref} {...$$restProps} is="${definition.name}">
? `<${definition.extend}
bind:this={__ref}
is="${definition.name}"
{...$$restProps}
${events.join('\n ')}
>
<slot />
</${definition.extend}>`
: `<${definition.name} bind:this={__ref} {...$$restProps}>
: `<${definition.name}
bind:this={__ref}
{...$$restProps}
${events.join('\n ')}
>
<slot />
</${definition.name}>`;

Expand All @@ -221,11 +237,11 @@ ${markup}`;

function generateSvelteTypings(entry: Entry) {
const { packageJson, definition, declaration } = entry;
let declContents = `import { SvelteComponent } from 'svelte';
import { ${declaration.name} as Base${declaration.name} } from '${packageJson.name}';
`;
let imports = `import { SvelteComponent } from 'svelte';
import { ${declaration.name} as Base${declaration.name} } from '${packageJson.name}';
`;
if (definition.extend) {
declContents += `import { ${getAttributes(definition.extend).split('<')[0]} } from 'svelte/elements';\n`;
imports += `import { ${getAttributes(definition.extend).split('<')[0]} } from 'svelte/elements';\n`;
}

let propertiesTypings = '';
Expand All @@ -246,17 +262,31 @@ import { ${declaration.name} as Base${declaration.name} } from '${packageJson.na
}
}

declContents += `
let eventsTypings = '';
if (declaration.events) {
imports += `import { EventHandler } from 'svelte/elements';\n`;

for (const event of declaration.events) {
propertiesTypings += `'on:${event.name}'?: EventHandler<CustomEvent>;\n`;
eventsTypings += `'${event.name}': CustomEvent;\n`;
}
}

const declContents = `
declare const __propDef: {
props: ${definition.extend ? `${getAttributes(definition.extend)} & ` : ''}{
${propertiesTypings
.trim()
.split('\n')
.map((line) => ` ${line}`)
.join('\n')}
},
};
events: {
[evt: string]: CustomEvent<any>;
${eventsTypings
.trim()
.split('\n')
.map((line) => ` ${line}`)
.join('\n')}
};
slots: {};
};
Expand All @@ -266,12 +296,12 @@ export type ${declaration.name}Events = typeof __propDef.events;
export type ${declaration.name}Slots = typeof __propDef.slots;
export default class ${declaration.name} extends SvelteComponent<${declaration.name}Props, ${declaration.name}Events, ${
declaration.name
}Slots > {
}Slots> {
}
export {};
`;

return declContents;
return `${imports}${declContents}`;
}

export async function transformSvelte(entry: Entry, options: SvelteTransformOptions) {
Expand Down
7 changes: 7 additions & 0 deletions test/svelte/cem.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { dnaPlugins } from '@chialab/manifest-analyzer-dna-plugin';

export default {
plugins: dnaPlugins(),
globs: ['index.ts'],
dependencies: false,
};
51 changes: 30 additions & 21 deletions test/svelte/custom-elements.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"modules": [
{
"kind": "javascript-module",
"path": "src/index.ts",
"path": "index.ts",
"declarations": [
{
"kind": "class",
Expand All @@ -16,34 +16,39 @@
"name": "stringProp",
"type": {
"text": "string | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "booleanProp",
"type": {
"text": "boolean | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "numericProp",
"type": {
"text": "number | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "objectProp",
"type": {
"text": "object | undefined"
},
"description": ""
}
}
],
"events": [
{
"name": "stringchange"
}
],
"superclass": {
"name": "Component",
"package": "@chialab/dna"
},
"tagName": "test-element",
"customElement": true
},
Expand All @@ -57,34 +62,38 @@
"name": "stringProp",
"type": {
"text": "string | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "booleanProp",
"type": {
"text": "boolean | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "numericProp",
"type": {
"text": "number | undefined"
},
"description": ""
}
},
{
"kind": "field",
"name": "objectProp",
"type": {
"text": "object | undefined"
},
"description": ""
}
}
],
"events": [
{
"name": "stringchange"
}
],
"superclass": {
"module": "index.ts"
},
"tagName": "test-link",
"customElement": true
}
Expand All @@ -95,23 +104,23 @@
"name": "TestElement",
"declaration": {
"name": "TestElement",
"module": "src/index.ts"
"module": "index.ts"
}
},
{
"kind": "custom-element-definition",
"name": "test-element",
"declaration": {
"name": "TestElement",
"module": "src/index.ts"
"module": "index.ts"
}
},
{
"kind": "js",
"name": "TestLink",
"declaration": {
"name": "TestLink",
"module": "src/index.ts"
"module": "index.ts"
}
},
{
Expand All @@ -120,7 +129,7 @@
"extend": "a",
"declaration": {
"name": "TestLink",
"module": "src/index.ts"
"module": "index.ts"
}
}
]
Expand Down
11 changes: 10 additions & 1 deletion test/svelte/element.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { afterEach, describe, expect, test } from 'vitest';
import { tick } from 'svelte';
import { afterEach, describe, expect, test, vi } from 'vitest';
import TestElement from './components/TestElement.svelte';

let host: HTMLElement;
Expand All @@ -9,6 +10,7 @@ describe('Element', () => {
});

test('mount component', async () => {
const spy = vi.fn();
host = document.createElement('div');
host.setAttribute('id', 'host');
document.body.appendChild(host);
Expand All @@ -21,7 +23,14 @@ describe('Element', () => {
objectProp: { test: true },
},
});
instance.$on('stringchange', spy);
expect(instance).toBeTruthy();
expect(host.innerHTML).toMatchSnapshot();
expect(spy).not.toHaveBeenCalled();
instance.$$set({
stringProp: 'changed',
});
await tick();
expect(spy).toHaveBeenCalled();
});
});
54 changes: 27 additions & 27 deletions test/svelte/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Component, customElement, HTML, html } from '@chialab/dna';
import { Component, customElement, HTML, html, property } from '@chialab/dna';

/**
* @fires stringchange
*/
@customElement('test-element')
export class TestElement extends Component {
static get properties() {
return {
stringProp: String,
booleanProp: Boolean,
numericProp: Number,
objectProp: Object,
};
}

declare stringProp?: string;
declare booleanProp?: boolean;
declare numericProp?: number;
declare objectProp?: object;
@property({
event: 'stringchange',
})
stringProp?: string;
@property()
booleanProp?: boolean;
@property()
numericProp?: number;
@property()
objectProp?: object;

render() {
return html`
Expand All @@ -26,23 +26,23 @@ export class TestElement extends Component {
}
}

/**
* @fires stringchange
*/
@customElement('test-link', {
extends: 'a',
})
export class TestLink extends HTML.Anchor {
static get properties() {
return {
stringProp: String,
booleanProp: Boolean,
numericProp: Number,
objectProp: Object,
};
}

declare stringProp?: string;
declare booleanProp?: boolean;
declare numericProp?: number;
declare objectProp?: object;
@property({
event: 'stringchange',
})
stringProp?: string;
@property()
booleanProp?: boolean;
@property()
numericProp?: number;
@property()
objectProp?: object;

render() {
return html`
Expand Down
11 changes: 10 additions & 1 deletion test/svelte/link.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { afterEach, describe, expect, test } from 'vitest';
import { tick } from 'svelte';
import { afterEach, describe, expect, test, vi } from 'vitest';
import TestLink from './components/TestLink.svelte';

let host: HTMLElement;
Expand All @@ -9,6 +10,7 @@ describe('Link', () => {
});

test('mount component', async () => {
const spy = vi.fn();
host = document.createElement('div');
host.setAttribute('id', 'host');
document.body.appendChild(host);
Expand All @@ -21,7 +23,14 @@ describe('Link', () => {
objectProp: { test: true },
},
});
instance.$on('stringchange', spy);
expect(instance).toBeTruthy();
expect(host.innerHTML).toMatchSnapshot();
expect(spy).not.toHaveBeenCalled();
instance.$$set({
stringProp: 'changed',
});
await tick();
expect(spy).toHaveBeenCalled();
});
});
8 changes: 6 additions & 2 deletions test/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
"private": true,
"main": "index.ts",
"scripts": {
"prepare": "rimraf 'components' && plasma --framework svelte --outdir components -y",
"manifest": "custom-elements-manifest analyze --config cem.config.js",
"generate": "plasma --framework svelte --outdir components -y",
"prepare": "rimraf 'components' && yarn manifest && yarn generate",
"test": "vitest"
},
"devDependencies": {
"@chialab/dna": "^4.0.0-alpha.0",
"@chialab/plasma": "file:./../..",
"@chialab/manifest-analyzer-dna-plugin": "^3.0.1-alpha.0",
"@chialab/plasma": "file:../..",
"@custom-elements-manifest/analyzer": "^0.9.0",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"jsdom": "^23.0.0",
"rimraf": "^5.0.5",
Expand Down
Loading

0 comments on commit 0039cfb

Please sign in to comment.