Skip to content

Authoring components

As with a regular Svelte-built custom element, set the tag name through customElement on <svelte:options>:

<svelte:options customElement="favorite-number" />

svebcomponents uses this string in the generated types and manifest. It cannot be dynamically computed.

Declare typed props with Svelte’s $props() rune:

<script lang="ts">
interface Props {
/** Number of items shown on each page. */
pageSize: number;
featured?: boolean;
}
let { pageSize, featured = false }: Props = $props();
</script>

By default, Svelte exposes each prop as a property on the custom element. svebcomponents additionally derives its attribute name, type converter, and reflection setting from the TypeScript declaration.

PropertyAttribute
pageSizepage-size
featuredfeatured

String, number, and boolean props reflect to attributes, but arrays, objects, and unresolved type references do not. Read Attribute metadata for the inference rules and overrides.

Dispatch events using Svelte’s $host() rune. Add an explicit type argument when the event carries detail:

<script lang="ts">
interface ChangeDetail {
value: string;
}
function change(value: string) {
$host().dispatchEvent(
new CustomEvent<ChangeDetail>("change", { detail: { value } }),
);
}
</script>

svebcomponents records the literal event name and the CustomEvent type argument. It cannot derive a name from a variable or infer a detail type from the value passed to detail.

Use <slot> for light DOM content:

<div class="card">
<slot name="header"></slot>
<slot></slot>
</div>
<my-card>
<h2 slot="header">Title</h2>
<p>Body</p>
</my-card>

svebcomponents records static slot names.

Svelte’s custom-element compiler puts component styles in the shadow root. Use :host for the custom element and CSS custom properties for values consumers can set:

<style>
:host {
display: inline-block;
border-radius: var(--card-radius, 4px);
}
</style>

svebcomponents records CSS custom properties that the component reads through var() and does not declare in the same stylesheet.

Document props with JSDoc as shown above. Use an @component comment for the component, slots, events, and CSS custom properties:

<!-- @component
A button with a configurable corner radius.
@slot - Button label.
@event change - Fired after the value changes.
@cssprop --button-radius - Corner radius.
-->

The analyzer uses these source patterns for generated types and manifest data:

Source patternGenerated data
Literal <svelte:options> tagCustom-element name
Typed $props() declaration and JSDocProperties, attributes, comments
Literal event name in $host().dispatchEvent(...)Event name and detail type
Static <slot> elementSlot name
External var(--name) in component CSSCSS custom property
@component documentation tagsAPI descriptions