Skip to content

Commit

Permalink
Add support for svelte.
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Nov 23, 2023
1 parent e9e3da8 commit 41ded18
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 57 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-pugs-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chialab/dna': major
---

Add support for `svelte`.
116 changes: 111 additions & 5 deletions docs/guide/integrations.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,121 @@
# Integrations

### Typescript, JSX, HTMLElementTagNameMap, IntrinsicElements

TypeScript supports JSX syntax, and it is able to provide typechecking and hints for component properties if you register the tag name to the DNA's `JSX.CustomElements` interface. The JSX typings provided by DNA will make it automatically available as [`IntrinsicElement`](https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements) and to the [`HTMLElementTagNameMap`](https://www.typescriptlang.org/docs/handbook/dom-manipulation.html#documentcreateelement) interface.

::: code-group

```tsx [app.tsx]
import { render } from '@chialab/dna';
import './x-card';

render(
<x-card
firstName="Alan"
age={24}
/>,
document.body
);
```

```tsx [x-card.tsx]
import { builtin, Component, customElement } from '@chialab/dna';

@customElement('x-card')
class Card extends Component {
// ...
}

@customElement('x-link', { extends: 'a' })
class Link extends builtin.HTMLAnchorElement {
// ...
}

declare module '@chialab/dna' {
namespace JSX {
interface CustomElements {
'x-card': Card;
'x-link': Link & {
extends: 'a';
};
}
}
}
```

:::

## Frameworks

DNA uses its own render to handle slotted nodes in the light DOM. So, we run tests for integration with other frontend frameworks like React, Angular, Lit and Vue. Here is a list of passing tests and known issues:
DNA composition is based on Quantum, which is [tested across different frameworks](https://github.com/chialab/quantum/tree/main/tests).

| Framwework | Update a property | Slot text | Slot elements | Named slots |
| ---------- | :---------------: | :-------: | :-----------: | :---------: |
| React | 🚧 | 🚧 | 🚧 | 🚧 |
| Lit | 🚧 | 🚧 | 🚧 | 🚧 |
| Vue | 🚧 | 🚧 | 🚧 | 🚧 |
| Angular | 🚧 | 🚧 | 🚧 | 🚧 |
| React |||||
| Lit |||||
| Vue |||||
| Angular |||||
| Svelte |||||

### Svelte integration

Import DNA typings in your `app.d.ts` in order to enable integrated support with svelte:

::: code-group

```ts [app.d.ts]
import '@chialab/dna/frameworks/svelte';

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}

export {};
```

```ts [hello-world.ts]
import { Component, customElement, html, property } from '@chialab/dna';

@customElement('hello-world')
export class HelloWorld extends Component {
@property({
type: String,
})
name?: string;

render() {
return html`Hello ${this.name || 'world'}!`;
}
}

declare module '@chialab/dna' {
namespace JSX {
interface CustomElements {
'hello-world': HelloWorld;
}
}
}
```

```svelte [+page.svelte]
<script lang="ts">
import './hello-world';
</script>
<hello-world
name={2} // [!code error] Type 'number' is not assignable to type 'string'.
/>
```

:::

## View libraries

Expand Down
46 changes: 0 additions & 46 deletions docs/guide/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,49 +101,3 @@ module.exports = {
addons: ['@storybook/addon-a11y', '@storybook/addon-essentials', '@chialab/storybook-addon-dna'],
};
```

### Typescript, JSX, HTMLElementTagNameMap, IntrinsicElements

TypeScript supports JSX syntax, and it is able to provide typechecking and hints for component properties if you register the tag name to the DNA's `JSX.CustomElements` interface. The JSX typings provided by DNA will make it automatically available as [`IntrinsicElement`](https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements) and to the [`HTMLElementTagNameMap`](https://www.typescriptlang.org/docs/handbook/dom-manipulation.html#documentcreateelement) interface.

::: code-group

```tsx [app.tsx]
import { render } from '@chialab/dna';
import './x-card';

render(
<x-card
firstName="Alan"
age={24}
/>,
document.body
);
```

```tsx [x-card.tsx]
import { builtin, Component, customElement } from '@chialab/dna';

@customElement('x-card')
class Card extends Component {
// ...
}

@customElement('x-link', { extends: 'a' })
class Link extends builtin.HTMLAnchorElement {
// ...
}

declare module '@chialab/dna' {
namespace JSX {
interface CustomElements {
'x-card': Card;
'x-link': Link & {
extends: 'a';
};
}
}
}
```

:::
125 changes: 125 additions & 0 deletions frameworks/svelte.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* eslint-disable @typescript-eslint/no-namespace, @typescript-eslint/no-empty-interface */

import type {
HTMLAnchorAttributes,
HTMLAreaAttributes,
HTMLAttributes,
HTMLAudioAttributes,
HTMLBaseAttributes,
HTMLBlockquoteAttributes,
HTMLButtonAttributes,
HTMLCanvasAttributes,
HTMLColAttributes,
HTMLColgroupAttributes,
HTMLDataAttributes,
HTMLDelAttributes,
HTMLDetailsAttributes,
HTMLDialogAttributes,
HTMLEmbedAttributes,
HTMLFieldsetAttributes,
HTMLFormAttributes,
HTMLHtmlAttributes,
HTMLIframeAttributes,
HTMLImgAttributes,
HTMLInputAttributes,
HTMLInsAttributes,
HTMLKeygenAttributes,
HTMLLabelAttributes,
HTMLLiAttributes,
HTMLLinkAttributes,
HTMLMapAttributes,
HTMLMenuAttributes,
HTMLMetaAttributes,
HTMLMeterAttributes,
HTMLObjectAttributes,
HTMLOlAttributes,
HTMLOptgroupAttributes,
HTMLOptionAttributes,
HTMLOutputAttributes,
HTMLParamAttributes,
HTMLProgressAttributes,
HTMLQuoteAttributes,
HTMLScriptAttributes,
HTMLSelectAttributes,
HTMLSlotAttributes,
HTMLSourceAttributes,
HTMLStyleAttributes,
HTMLTableAttributes,
HTMLTdAttributes,
HTMLTextareaAttributes,
HTMLThAttributes,
HTMLTimeAttributes,
HTMLTrackAttributes,
HTMLVideoAttributes,
HTMLWebViewAttributes,
} from 'svelte/elements';
import type { JSXInternal, Props } from '../types/JSX';

type IntrinsicElementAttributes = {
a: HTMLAnchorAttributes;
area: HTMLAreaAttributes;
audio: HTMLAudioAttributes;
base: HTMLBaseAttributes;
blockquote: HTMLBlockquoteAttributes;
button: HTMLButtonAttributes;
canvas: HTMLCanvasAttributes;
col: HTMLColAttributes;
colgroup: HTMLColgroupAttributes;
data: HTMLDataAttributes;
del: HTMLDelAttributes;
details: HTMLDetailsAttributes;
dialog: HTMLDialogAttributes;
embed: HTMLEmbedAttributes;
fieldset: HTMLFieldsetAttributes;
form: HTMLFormAttributes;
html: HTMLHtmlAttributes;
iframe: HTMLIframeAttributes;
img: HTMLImgAttributes;
input: HTMLInputAttributes;
ins: HTMLInsAttributes;
keygen: HTMLKeygenAttributes;
label: HTMLLabelAttributes;
li: HTMLLiAttributes;
link: HTMLLinkAttributes;
map: HTMLMapAttributes;
menu: HTMLMenuAttributes;
meta: HTMLMetaAttributes;
meter: HTMLMeterAttributes;
object: HTMLObjectAttributes;
ol: HTMLOlAttributes;
optgroup: HTMLOptgroupAttributes;
option: HTMLOptionAttributes;
output: HTMLOutputAttributes;
param: HTMLParamAttributes;
progress: HTMLProgressAttributes;
q: HTMLQuoteAttributes;
script: HTMLScriptAttributes;
select: HTMLSelectAttributes;
slot: HTMLSlotAttributes;
source: HTMLSourceAttributes;
style: HTMLStyleAttributes;
table: HTMLTableAttributes;
td: HTMLTdAttributes;
textarea: HTMLTextareaAttributes;
th: HTMLThAttributes;
time: HTMLTimeAttributes;
track: HTMLTrackAttributes;
video: HTMLVideoAttributes;
webview: HTMLWebViewAttributes;
};

/**
* Extend the SvelteHTMLElements interface for svelte support.
*/
declare module 'svelte/elements' {
type DNASvelteHTMLElements = {
[K in keyof JSXInternal.CustomElements]: ('extends' extends keyof JSXInternal.CustomElements[K]
? JSXInternal.CustomElements[K] extends keyof IntrinsicElementAttributes
? IntrinsicElementAttributes[JSXInternal.CustomElements[K]]
: HTMLAttributes<JSXInternal.CustomElements[K]>
: HTMLAttributes<JSXInternal.CustomElements[K]>) &
Props<JSXInternal.CustomElements[K]>;
};

export interface SvelteHTMLElements extends DNASvelteHTMLElements {}
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
"default": "./dist/dna.js"
},
"./jsx-runtime": "./jsx-runtime.js",
"./jsx-dev-runtime": "./jsx-runtime.js"
"./jsx-dev-runtime": "./jsx-runtime.js",
"./frameworks/*": "./frameworks/*.d.ts"
},
"files": [
"dist",
"types",
"frameworks",
"jsx-runtime.js",
"jsx-runtime.d.ts",
"LICENSE",
Expand Down Expand Up @@ -72,6 +74,7 @@
"rimraf": "^5.0.2",
"rxjs": "^7.8.1",
"saucelabs": "^7.4.0",
"svelte": "^4.2.7",
"typescript": "^5.0.0",
"vitepress": "^1.0.0-rc.25",
"vitest": "^1.0.0-beta.5",
Expand Down
Loading

0 comments on commit 41ded18

Please sign in to comment.