Complete TypeScript type definitions reference for Svelte 5, covering HTML/SVG element types, event handlers, ARIA attributes, and component utilities.
Module: svelte/elements
These utilities help you work with component types in a type-safe manner.
interface Component<
Props extends Record<string, any> = {},
Exports extends Record<string, any> = {},
Bindings extends keyof Props | '' = string
>Represents a Svelte 5 component function with typed props, exports, and bindable properties.
Type Parameters:
Props - Component properties interfaceExports - Values exposed via export declarationsBindings - Keys from Props that can be bound with bind:Example:
import type { Component } from 'svelte';
// Declare a component type
export const MyButton: Component<
{ label: string; disabled?: boolean },
{ focus(): void },
'disabled'
>;type ComponentProps<Comp extends SvelteComponent | Component<any, any>>Extracts the props type from a component. Essential for creating wrapper components or generic utilities.
Example:
import type { ComponentProps } from 'svelte';
import MyComponent from './MyComponent.svelte';
// Get props type from component
type Props = ComponentProps<typeof MyComponent>;
// Use in generic function
function withProps<TComponent extends Component<any>>(
component: TComponent,
props: ComponentProps<TComponent>
) {
// ...
}interface Snippet<Parameters extends unknown[] = []>Type for #snippet blocks that can be passed to components as props. Parameters define the expected arguments as a tuple.
Example:
import type { Snippet } from 'svelte';
interface Props {
// Snippet with no parameters
header?: Snippet;
// Snippet expecting a single object parameter
item: Snippet<[{ id: number; name: string }]>;
// Snippet with multiple parameters
row: Snippet<[number, string, boolean]>;
}
let { header, item, row }: Props = $props();Usage in template:
{#if header}
{@render header()}
{/if}
{#each items as data}
{@render item(data)}
{/each}The svelte/elements module exports comprehensive TypeScript types for all HTML elements. Each element type extends the base HTMLAttributes<T> interface with element-specific properties.
interface HTMLButtonAttributes extends HTMLAttributes<HTMLButtonElement>Attributes for <button> elements with form integration and accessibility.
Specific Properties:
disabled?: boolean - Disables the buttonform?: string - Associates with form by IDformaction?: string - Override form action URLformenctype?: string - Override form encoding typeformmethod?: string - Override form method (GET/POST)formnovalidate?: boolean - Skip form validationformtarget?: string - Override form targetname?: string - Button name for form submissiontype?: 'submit' | 'reset' | 'button' - Button behavior typevalue?: string - Value sent on form submissionExample:
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
let buttonProps: HTMLButtonAttributes = {
type: 'submit',
disabled: false,
onclick: (e) => console.log('clicked', e.currentTarget)
};
</script>
<button {...buttonProps}>Submit</button>interface HTMLInputAttributes extends HTMLAttributes<HTMLInputElement>Comprehensive attributes for <input> elements covering all input types.
Specific Properties:
accept?: string - File type filter (file inputs)alt?: string - Alternative text (image inputs)autocomplete?: string - Browser autocomplete hintcapture?: boolean | string - Camera capture mode (file inputs)checked?: boolean - Checked state (checkbox/radio)disabled?: boolean - Disables the inputform?: string - Associates with form by IDlist?: string - ID of datalist for suggestionsmax?: number | string - Maximum valuemaxlength?: number - Maximum character lengthmin?: number | string - Minimum valueminlength?: number - Minimum character lengthmultiple?: boolean - Allow multiple selectionsname?: string - Input name for form submissionpattern?: string - Validation regex patternplaceholder?: string - Placeholder textreadonly?: boolean - Prevents editingrequired?: boolean - Marks as required fieldsize?: number - Visual width in charactersstep?: number | string - Value increment steptype?: string - Input type (text, email, number, etc.)value?: string | number - Input valueExample:
<script lang="ts">
import type { HTMLInputAttributes } from 'svelte/elements';
let emailInput: HTMLInputAttributes = {
type: 'email',
required: true,
placeholder: 'user@example.com',
autocomplete: 'email',
oninput: (e) => {
const target = e.currentTarget as HTMLInputElement;
console.log(target.value);
}
};
</script>
<input {...emailInput} bind:value={email} />interface HTMLFormAttributes extends HTMLAttributes<HTMLFormElement>Attributes for <form> elements controlling submission behavior.
Specific Properties:
acceptCharset?: string - Character encoding for submissionaction?: string - Form submission URLautocomplete?: string - Form-wide autocomplete behaviorenctype?: string - Encoding type for POST requestsmethod?: string - HTTP method (GET/POST)name?: string - Form namenovalidate?: boolean - Skip validation on submittarget?: string - Where to display responseExample:
<script lang="ts">
import type { HTMLFormAttributes } from 'svelte/elements';
let formProps: HTMLFormAttributes = {
method: 'POST',
action: '/api/submit',
novalidate: false,
onsubmit: async (e) => {
e.preventDefault();
const form = e.currentTarget as HTMLFormElement;
const data = new FormData(form);
// Handle submission
}
};
</script>
<form {...formProps}>
<!-- form fields -->
</form>interface HTMLAnchorAttributes extends HTMLAttributes<HTMLAnchorElement>Attributes for <a> link elements.
Specific Properties:
download?: string - Prompts download with filenamehref?: string - Link destination URLhreflang?: string - Language of linked resourcemedia?: string - Media query for link relevanceping?: string - Space-separated URLs to pingreferrerpolicy?: ReferrerPolicy - Referrer header policyrel?: string - Relationship to linked resourcetarget?: string - Where to open link (_blank, _self, etc.)type?: string - MIME type of linked resourceExample:
<script lang="ts">
import type { HTMLAnchorAttributes } from 'svelte/elements';
let linkProps: HTMLAnchorAttributes = {
href: '/dashboard',
target: '_blank',
rel: 'noopener noreferrer',
onclick: (e) => {
console.log('navigating to', e.currentTarget.href);
}
};
</script>
<a {...linkProps}>Go to Dashboard</a>interface HTMLImgAttributes extends HTMLAttributes<HTMLImageElement>Attributes for <img> elements with modern image features.
Specific Properties:
alt?: string - Alternative text (required for accessibility)crossorigin?: 'anonymous' | 'use-credentials' - CORS modedecoding?: 'async' | 'auto' | 'sync' - Decode hintheight?: number | string - Display heightloading?: 'eager' | 'lazy' - Loading strategyreferrerpolicy?: ReferrerPolicy - Referrer header policysizes?: string - Size hints for responsive imagessrc?: string - Image source URLsrcset?: string - Responsive image sourceswidth?: number | string - Display widthExample:
<script lang="ts">
import type { HTMLImgAttributes } from 'svelte/elements';
let imgProps: HTMLImgAttributes = {
src: '/images/hero.jpg',
alt: 'Hero image description',
loading: 'lazy',
width: 800,
height: 600,
onload: () => console.log('Image loaded'),
onerror: () => console.error('Failed to load image')
};
</script>
<img {...imgProps} />interface HTMLDivAttributes extends HTMLAttributes<HTMLDivElement>Generic container element attributes. Since <div> has no specific attributes, this is essentially HTMLAttributes<HTMLDivElement>.
interface HTMLSpanAttributes extends HTMLAttributes<HTMLSpanElement>Inline container element attributes. Like div, extends only base attributes.
interface HTMLTableAttributes extends HTMLAttributes<HTMLTableElement>Attributes for <table> elements.
Specific Properties:
align?: string - (Deprecated) Table alignmentbgcolor?: string - (Deprecated) Background colorborder?: number | string - (Deprecated) Border widthcellpadding?: number | string - (Deprecated) Cell paddingcellspacing?: number | string - (Deprecated) Cell spacingframe?: string - (Deprecated) Frame visibilityrules?: string - (Deprecated) Rules visibilitysummary?: string - (Deprecated) Table summarywidth?: number | string - (Deprecated) Table widthNote: Most specific table attributes are deprecated. Use CSS for styling instead.
Additional form-related element types:
All HTML element attribute types follow the pattern HTML[Element]Attributes:
HTMLAnchorAttributes // <a>
HTMLAreaAttributes // <area>
HTMLAudioAttributes // <audio>
HTMLBaseAttributes // <base>
HTMLBlockquoteAttributes // <blockquote>
HTMLButtonAttributes // <button>
HTMLCanvasAttributes // <canvas>
HTMLColAttributes // <col>
HTMLColgroupAttributes // <colgroup>
HTMLDataAttributes // <data>
HTMLDetailsAttributes // <details>
HTMLDialogAttributes // <dialog>
HTMLDivAttributes // <div>
HTMLEmbedAttributes // <embed>
HTMLFieldsetAttributes // <fieldset>
HTMLFormAttributes // <form>
HTMLHtmlAttributes // <html>
HTMLIframeAttributes // <iframe>
HTMLImgAttributes // <img>
HTMLInputAttributes // <input>
HTMLInsAttributes // <ins>
HTMLDelAttributes // <del>
HTMLKeygenAttributes // <keygen>
HTMLLabelAttributes // <label>
HTMLLiAttributes // <li>
HTMLLinkAttributes // <link>
HTMLMapAttributes // <map>
HTMLMenuAttributes // <menu>
HTMLMetaAttributes // <meta>
HTMLMeterAttributes // <meter>
HTMLObjectAttributes // <object>
HTMLOlAttributes // <ol>
HTMLOptgroupAttributes // <optgroup>
HTMLOptionAttributes // <option>
HTMLOutputAttributes // <output>
HTMLParamAttributes // <param>
HTMLProgressAttributes // <progress>
HTMLQuoteAttributes // <q>
HTMLScriptAttributes // <script>
HTMLSelectAttributes // <select>
HTMLSlotAttributes // <slot>
HTMLSourceAttributes // <source>
HTMLSpanAttributes // <span>
HTMLStyleAttributes // <style>
HTMLTableAttributes // <table>
HTMLTdAttributes // <td>
HTMLTemplateAttributes // <template>
HTMLTextareaAttributes // <textarea>
HTMLThAttributes // <th>
HTMLTimeAttributes // <time>
HTMLTrackAttributes // <track>
HTMLVideoAttributes // <video>
HTMLWebViewAttributes // <webview>SVG element types provide comprehensive typing for Scalable Vector Graphics elements in Svelte.
interface SVGAttributes<T extends EventTarget> extends AriaAttributes, DOMAttributes<T>Base interface for all SVG elements. Includes common SVG attributes and presentation properties.
Common SVG Properties:
clip-path?: string - Clipping path referencecolor?: string - Color for current elementfill?: string - Fill color/patternfill-opacity?: number | string - Fill opacityfill-rule?: 'nonzero' | 'evenodd' | 'inherit' - Fill algorithmstroke?: string - Stroke color/patternstroke-dasharray?: string | number - Dash patternstroke-dashoffset?: number | string - Dash offsetstroke-linecap?: 'butt' | 'round' | 'square' | 'inherit' - Line cap stylestroke-linejoin?: 'miter' | 'round' | 'bevel' | 'inherit' - Line join stylestroke-opacity?: number | string - Stroke opacitystroke-width?: number | string - Stroke widthtransform?: string - Transform operationsopacity?: number | string - Overall opacitytype SVGCircleAttributes = SVGAttributes<SVGCircleElement>Attributes for <circle> elements.
Example:
<script lang="ts">
import type { SVGCircleAttributes } from 'svelte/elements';
let circleProps: SVGCircleAttributes = {
cx: 50,
cy: 50,
r: 40,
fill: 'blue',
stroke: 'black',
'stroke-width': 2,
onclick: (e) => console.log('Circle clicked')
};
</script>
<svg viewBox="0 0 100 100">
<circle {...circleProps} />
</svg>type SVGPathAttributes = SVGAttributes<SVGPathElement>Attributes for <path> elements, the most versatile SVG drawing element.
Example:
<script lang="ts">
import type { SVGPathAttributes } from 'svelte/elements';
let pathProps: SVGPathAttributes = {
d: 'M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80',
fill: 'transparent',
stroke: 'purple',
'stroke-width': 3,
onmouseover: (e) => {
e.currentTarget.setAttribute('stroke', 'red');
}
};
</script>
<svg viewBox="0 0 200 200">
<path {...pathProps} />
</svg>type SVGRectAttributes = SVGAttributes<SVGRectElement>Attributes for <rect> rectangle elements.
Example:
<script lang="ts">
import type { SVGRectAttributes } from 'svelte/elements';
let rectProps: SVGRectAttributes = {
x: 10,
y: 10,
width: 80,
height: 60,
rx: 5, // rounded corners
ry: 5,
fill: 'lightblue',
stroke: 'navy'
};
</script>
<svg viewBox="0 0 100 100">
<rect {...rectProps} />
</svg>type SVGLineAttributes = SVGAttributes<SVGLineElement>Attributes for <line> elements.
Example:
<script lang="ts">
import type { SVGLineAttributes } from 'svelte/elements';
let lineProps: SVGLineAttributes = {
x1: 0,
y1: 0,
x2: 100,
y2: 100,
stroke: 'black',
'stroke-width': 2
};
</script>
<svg viewBox="0 0 100 100">
<line {...lineProps} />
</svg>type SVGEllipseAttributes = SVGAttributes<SVGEllipseElement>Attributes for <ellipse> elements.
Example:
<script lang="ts">
import type { SVGEllipseAttributes } from 'svelte/elements';
let ellipseProps: SVGEllipseAttributes = {
cx: 50,
cy: 50,
rx: 40, // x-axis radius
ry: 25, // y-axis radius
fill: 'yellow',
stroke: 'orange'
};
</script>
<svg viewBox="0 0 100 100">
<ellipse {...ellipseProps} />
</svg>type SVGPolygonAttributes = SVGAttributes<SVGPolygonElement>Attributes for <polygon> closed shape elements.
Example:
<script lang="ts">
import type { SVGPolygonAttributes } from 'svelte/elements';
// Star shape
let polygonProps: SVGPolygonAttributes = {
points: '50,15 61,35 82,35 66,48 73,68 50,55 27,68 34,48 18,35 39,35',
fill: 'gold',
stroke: 'darkorange',
'stroke-width': 2
};
</script>
<svg viewBox="0 0 100 100">
<polygon {...polygonProps} />
</svg>All SVG elements use SVGAttributes<SVG[Element]Element>:
SVGAttributes<SVGSVGElement> // <svg>
SVGAttributes<SVGCircleElement> // <circle>
SVGAttributes<SVGEllipseElement> // <ellipse>
SVGAttributes<SVGLineElement> // <line>
SVGAttributes<SVGPathElement> // <path>
SVGAttributes<SVGPolygonElement> // <polygon>
SVGAttributes<SVGPolylineElement> // <polyline>
SVGAttributes<SVGRectElement> // <rect>
SVGAttributes<SVGGElement> // <g>
SVGAttributes<SVGDefsElement> // <defs>
SVGAttributes<SVGClipPathElement> // <clipPath>
SVGAttributes<SVGLinearGradientElement> // <linearGradient>
SVGAttributes<SVGRadialGradientElement> // <radialGradient>
SVGAttributes<SVGStopElement> // <stop>
SVGAttributes<SVGTextElement> // <text>
SVGAttributes<SVGTSpanElement> // <tspan>
SVGAttributes<SVGImageElement> // <image>
SVGAttributes<SVGUseElement> // <use>
SVGAttributes<SVGSymbolElement> // <symbol>
SVGAttributes<SVGMarkerElement> // <marker>
SVGAttributes<SVGMaskElement> // <mask>
SVGAttributes<SVGPatternElement> // <pattern>
SVGAttributes<SVGFilterElement> // <filter>
// ... and all filter effect elementsEvent handler types provide strongly-typed event handling with proper currentTarget typing.
type EventHandler<E extends Event = Event, T extends EventTarget = Element> = (
event: E & { currentTarget: EventTarget & T }
) => anyGeneric event handler type. The event object's currentTarget is typed to the specific element type.
type MouseEventHandler<T extends EventTarget> = EventHandler<MouseEvent, T>Handles all mouse-related events: click, dblclick, mousedown, mouseup, mousemove, mouseenter, mouseleave, mouseover, mouseout.
Example:
<script lang="ts">
import type { MouseEventHandler } from 'svelte/elements';
const handleClick: MouseEventHandler<HTMLButtonElement> = (e) => {
console.log('Button clicked at', e.clientX, e.clientY);
console.log('Button element:', e.currentTarget); // Typed as HTMLButtonElement
};
</script>
<button onclick={handleClick}>Click me</button>type KeyboardEventHandler<T extends EventTarget> = EventHandler<KeyboardEvent, T>Handles keyboard events: keydown, keyup, keypress.
Example:
<script lang="ts">
import type { KeyboardEventHandler } from 'svelte/elements';
const handleKeydown: KeyboardEventHandler<HTMLInputElement> = (e) => {
if (e.key === 'Enter') {
console.log('Enter pressed:', e.currentTarget.value);
}
};
</script>
<input type="text" onkeydown={handleKeydown} />type FormEventHandler<T extends EventTarget> = EventHandler<Event, T>
type ChangeEventHandler<T extends EventTarget> = EventHandler<Event, T>Handles form-related events: input, change, reset, invalid, formdata.
Example:
<script lang="ts">
import type { FormEventHandler, ChangeEventHandler } from 'svelte/elements';
const handleInput: FormEventHandler<HTMLInputElement> = (e) => {
console.log('Input value:', e.currentTarget.value);
};
const handleChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
console.log('Selected:', e.currentTarget.value);
};
const handleSubmit: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
console.log('Form submitted:', Object.fromEntries(formData));
};
</script>
<form onsubmit={handleSubmit}>
<input type="text" oninput={handleInput} />
<select onchange={handleChange}>
<option value="a">Option A</option>
<option value="b">Option B</option>
</select>
<button type="submit">Submit</button>
</form>type FocusEventHandler<T extends EventTarget> = EventHandler<FocusEvent, T>Handles focus-related events: focus, blur, focusin, focusout.
Example:
<script lang="ts">
import type { FocusEventHandler } from 'svelte/elements';
const handleFocus: FocusEventHandler<HTMLInputElement> = (e) => {
e.currentTarget.style.borderColor = 'blue';
};
const handleBlur: FocusEventHandler<HTMLInputElement> = (e) => {
e.currentTarget.style.borderColor = '';
};
</script>
<input onfocus={handleFocus} onblur={handleBlur} />type TouchEventHandler<T extends EventTarget> = EventHandler<TouchEvent, T>Handles touch events: touchstart, touchmove, touchend, touchcancel.
Example:
<script lang="ts">
import type { TouchEventHandler } from 'svelte/elements';
let startX = 0;
const handleTouchStart: TouchEventHandler<HTMLDivElement> = (e) => {
startX = e.touches[0].clientX;
};
const handleTouchMove: TouchEventHandler<HTMLDivElement> = (e) => {
const currentX = e.touches[0].clientX;
const diff = currentX - startX;
e.currentTarget.style.transform = `translateX(${diff}px)`;
};
</script>
<div ontouchstart={handleTouchStart} ontouchmove={handleTouchMove}>
Swipeable element
</div>type PointerEventHandler<T extends EventTarget> = EventHandler<PointerEvent, T>Handles unified pointer events (mouse, touch, pen): pointerdown, pointerup, pointermove, pointerenter, pointerleave, pointerover, pointerout, pointercancel, gotpointercapture, lostpointercapture.
Example:
<script lang="ts">
import type { PointerEventHandler } from 'svelte/elements';
const handlePointerDown: PointerEventHandler<HTMLCanvasElement> = (e) => {
const canvas = e.currentTarget;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Draw at pointer position
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.fillRect(x - 2, y - 2, 4, 4);
}
};
</script>
<canvas onpointerdown={handlePointerDown} />type DragEventHandler<T extends EventTarget> = EventHandler<DragEvent, T>Handles drag-and-drop events: drag, dragstart, dragend, dragenter, dragleave, dragover, drop.
Example:
<script lang="ts">
import type { DragEventHandler } from 'svelte/elements';
const handleDragOver: DragEventHandler<HTMLDivElement> = (e) => {
e.preventDefault();
e.currentTarget.style.backgroundColor = 'lightblue';
};
const handleDrop: DragEventHandler<HTMLDivElement> = (e) => {
e.preventDefault();
e.currentTarget.style.backgroundColor = '';
const data = e.dataTransfer?.getData('text/plain');
console.log('Dropped:', data);
};
</script>
<div ondragover={handleDragOver} ondrop={handleDrop}>
Drop zone
</div>type AnimationEventHandler<T extends EventTarget> = EventHandler<AnimationEvent, T>
type TransitionEventHandler<T extends EventTarget> = EventHandler<TransitionEvent, T>Handles CSS animation and transition events.
Example:
<script lang="ts">
import type { AnimationEventHandler, TransitionEventHandler } from 'svelte/elements';
const handleAnimationEnd: AnimationEventHandler<HTMLDivElement> = (e) => {
console.log('Animation ended:', e.animationName);
};
const handleTransitionEnd: TransitionEventHandler<HTMLDivElement> = (e) => {
console.log('Transition ended:', e.propertyName);
};
</script>
<div onanimationend={handleAnimationEnd} ontransitionend={handleTransitionEnd}>
Animated element
</div>type ClipboardEventHandler<T> // copy, cut, paste
type CompositionEventHandler<T> // compositionstart, compositionupdate, compositionend
type WheelEventHandler<T> // wheel
type UIEventHandler<T> // scroll, resize
type GamepadEventHandler<T> // gamepadconnected, gamepaddisconnected
type MessageEventHandler<T> // message, messageerror
type ToggleEventHandler<T> // toggle, beforetoggle (popover)ARIA (Accessible Rich Internet Applications) types ensure accessibility compliance.
type AriaRole =
| 'alert' | 'alertdialog' | 'application' | 'article' | 'banner'
| 'button' | 'cell' | 'checkbox' | 'columnheader' | 'combobox'
| 'complementary' | 'contentinfo' | 'definition' | 'dialog'
| 'directory' | 'document' | 'feed' | 'figure' | 'form'
| 'grid' | 'gridcell' | 'group' | 'heading' | 'img'
| 'link' | 'list' | 'listbox' | 'listitem' | 'log'
| 'main' | 'marquee' | 'math' | 'menu' | 'menubar'
| 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' | 'navigation'
| 'none' | 'note' | 'option' | 'presentation' | 'progressbar'
| 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup'
| 'rowheader' | 'scrollbar' | 'search' | 'searchbox'
| 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch'
| 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term'
| 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree'
| 'treegrid' | 'treeitem'
| (string & {})Defines the semantic role of an element for assistive technologies. The union with (string & {}) allows custom roles while preserving autocomplete.
Example:
<script lang="ts">
import type { AriaRole } from 'svelte/elements';
let role: AriaRole = 'button';
</script>
<div role={role} tabindex="0">
Custom button
</div>interface AriaAttributesComplete set of WAI-ARIA 1.1 attributes for accessibility.
State Attributes:
aria-busy?: Booleanish - Element is being modifiedaria-checked?: boolean | 'false' | 'mixed' | 'true' - Checkbox/radio statearia-disabled?: Booleanish - Element is disabledaria-expanded?: Booleanish - Expandable element statearia-hidden?: Booleanish - Element is hidden from accessibility treearia-invalid?: boolean | 'false' | 'true' | 'grammar' | 'spelling' - Validation statearia-pressed?: boolean | 'false' | 'mixed' | 'true' - Toggle button statearia-readonly?: Booleanish - Element is read-onlyaria-required?: Booleanish - Field is requiredaria-selected?: Booleanish - Selection stateRelationship Attributes:
aria-activedescendant?: string - ID of active descendantaria-controls?: string - IDs of controlled elementsaria-describedby?: string - IDs of describing elementsaria-details?: string - ID of detailed descriptionaria-errormessage?: string - ID of error messagearia-flowto?: string - IDs for reading orderaria-labelledby?: string - IDs of labeling elementsaria-owns?: string - IDs of owned elementsWidget Attributes:
aria-autocomplete?: 'none' | 'inline' | 'list' | 'both' - Autocomplete behavioraria-haspopup?: boolean | 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' - Popup typearia-level?: number - Hierarchical levelaria-modal?: Booleanish - Element is modalaria-multiline?: Booleanish - Textbox is multilinearia-multiselectable?: Booleanish - Multiple selection allowedaria-orientation?: 'horizontal' | 'vertical' - Element orientationaria-placeholder?: string - Placeholder textaria-valuemax?: number - Maximum valuearia-valuemin?: number - Minimum valuearia-valuenow?: number - Current valuearia-valuetext?: string - Human-readable value textLive Region Attributes:
aria-atomic?: Booleanish - Announce entire region or just changesaria-live?: 'off' | 'assertive' | 'polite' - Live region priorityaria-relevant?: string - Types of changes to announceDrag-and-Drop Attributes:
aria-dropeffect?: 'none' | 'copy' | 'execute' | 'link' | 'move' | 'popup' - Drop operationaria-grabbed?: Booleanish - Element is grabbedGrid Attributes:
aria-colcount?: number - Total columnsaria-colindex?: number - Column indexaria-colspan?: number - Columns spannedaria-rowcount?: number - Total rowsaria-rowindex?: number - Row indexaria-rowspan?: number - Rows spannedExample:
<script lang="ts">
import type { AriaAttributes } from 'svelte/elements';
let expanded = $state(false);
let triggerAttrs: AriaAttributes = {
'aria-expanded': expanded,
'aria-controls': 'dropdown-menu',
'aria-haspopup': 'menu'
};
let menuAttrs: AriaAttributes = {
'aria-hidden': !expanded,
'aria-labelledby': 'menu-trigger'
};
</script>
<button id="menu-trigger" {...triggerAttrs} onclick={() => expanded = !expanded}>
Menu
</button>
<div id="dropdown-menu" role="menu" {...menuAttrs}>
<div role="menuitem">Item 1</div>
<div role="menuitem">Item 2</div>
</div>interface DOMAttributes<T extends EventTarget>Base interface for all DOM elements, providing:
on: and on syntax)oncapture suffix)bind:clientWidth, bind:clientHeight, etc.)children property for Snippet typeEvent Handler Properties:
All standard DOM events are available in three forms:
'on:click'?: MouseEventHandler<T> // Svelte syntax
onclick?: MouseEventHandler<T> // Standard syntax
onclickcapture?: MouseEventHandler<T> // Capture phaseDimensional Bindings:
readonly 'bind:contentRect'?: DOMRectReadOnly
readonly 'bind:contentBoxSize'?: Array<ResizeObserverSize>
readonly 'bind:borderBoxSize'?: Array<ResizeObserverSize>
readonly 'bind:devicePixelContentBoxSize'?: Array<ResizeObserverSize>
readonly 'bind:clientWidth'?: number
readonly 'bind:clientHeight'?: numberExample:
<script lang="ts">
import type { DOMAttributes } from 'svelte/elements';
let width = $state(0);
let height = $state(0);
let divProps: DOMAttributes<HTMLDivElement> = {
onclick: (e) => console.log('Clicked'),
'on:mouseover': (e) => console.log('Mouse over'),
onclickcapture: (e) => console.log('Click captured')
};
</script>
<div
{...divProps}
bind:clientWidth={width}
bind:clientHeight={height}
>
Size: {width} x {height}
</div>interface HTMLAttributes<T extends EventTarget> extends AriaAttributes, DOMAttributes<T>Base for all HTML elements. Includes all standard HTML global attributes:
Core Attributes:
id?: string - Unique identifierclass?: string - CSS classesstyle?: string - Inline stylestitle?: string - Advisory informationMetadata:
accesskey?: string - Keyboard shortcutcontenteditable?: Booleanish | 'inherit' - Editable contentdir?: 'ltr' | 'rtl' | 'auto' - Text directiondraggable?: Booleanish - Draggable elementhidden?: boolean | 'hidden' | 'until-found' - Hidden elementlang?: string - Language codespellcheck?: Booleanish - Spell checkingtabindex?: number - Tab ordertranslate?: 'yes' | 'no' - Translation behaviorMicrodata:
itemid?: string - Microdata item IDitemprop?: string - Microdata propertyitemref?: string - Microdata referencesitemscope?: boolean - Microdata scopeitemtype?: string - Microdata typeCustom Data:
[key: data-${string}]: any - Data attributes (data-*)Svelte Directives:
use?: Action - Apply action directivetransition?: TransitionFn - Transition effectin?: TransitionFn - Intro transitionout?: TransitionFn - Outro transitionanimate?: AnimationFn - Animation on reordering<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
interface Props extends HTMLButtonAttributes {
variant?: 'primary' | 'secondary';
loading?: boolean;
}
let {
variant = 'primary',
loading = false,
children,
...buttonProps
}: Props = $props();
</script>
<button
{...buttonProps}
class="btn btn-{variant}"
disabled={buttonProps.disabled || loading}
>
{#if loading}
Loading...
{:else}
{@render children?.()}
{/if}
</button><script lang="ts">
import type { Action } from 'svelte/action';
import type { HTMLInputAttributes } from 'svelte/elements';
interface TooltipParams {
text: string;
position?: 'top' | 'bottom';
}
const tooltip: Action<HTMLElement, TooltipParams> = (node, params) => {
let tooltipEl: HTMLDivElement | null = null;
function show() {
tooltipEl = document.createElement('div');
tooltipEl.textContent = params.text;
tooltipEl.className = `tooltip tooltip-${params.position ?? 'top'}`;
document.body.appendChild(tooltipEl);
}
function hide() {
tooltipEl?.remove();
tooltipEl = null;
}
node.addEventListener('mouseenter', show);
node.addEventListener('mouseleave', hide);
return {
update(newParams) {
params = newParams;
},
destroy() {
hide();
node.removeEventListener('mouseenter', show);
node.removeEventListener('mouseleave', hide);
}
};
};
let inputProps: HTMLInputAttributes = {
type: 'text',
placeholder: 'Enter text...'
};
</script>
<input {...inputProps} use:tooltip={{ text: 'This is a tooltip' }} /><script lang="ts" generics="T extends HTMLElement">
import type { HTMLAttributes, MouseEventHandler } from 'svelte/elements';
interface Props extends HTMLAttributes<T> {
element?: keyof HTMLElementTagNameMap;
onCustomClick?: MouseEventHandler<T>;
}
let {
element = 'div',
onCustomClick,
children,
...attrs
}: Props = $props();
const handleClick: MouseEventHandler<T> = (e) => {
console.log('Internal handling:', e.currentTarget);
onCustomClick?.(e);
};
</script>
<svelte:element this={element} {...attrs} onclick={handleClick}>
{@render children?.()}
</svelte:element><script lang="ts">
import type {
HTMLFormAttributes,
FormEventHandler,
ChangeEventHandler
} from 'svelte/elements';
let formData = $state({
username: '',
email: '',
role: 'user'
});
const handleSubmit: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault();
console.log('Submitted:', formData);
};
const handleUsernameInput: FormEventHandler<HTMLInputElement> = (e) => {
formData.username = e.currentTarget.value;
};
const handleEmailInput: FormEventHandler<HTMLInputElement> = (e) => {
formData.email = e.currentTarget.value;
};
const handleRoleChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
formData.role = e.currentTarget.value;
};
</script>
<form onsubmit={handleSubmit}>
<input
type="text"
name="username"
value={formData.username}
oninput={handleUsernameInput}
required
/>
<input
type="email"
name="email"
value={formData.email}
oninput={handleEmailInput}
required
/>
<select
name="role"
value={formData.role}
onchange={handleRoleChange}
>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
<button type="submit">Submit</button>
</form><script lang="ts">
import type { SVGAttributes } from 'svelte/elements';
interface Props {
size?: number;
color?: string;
onclick?: SVGAttributes<SVGSVGElement>['onclick'];
}
let { size = 24, color = 'currentColor', onclick }: Props = $props();
let svgAttrs: SVGAttributes<SVGSVGElement> = {
width: size,
height: size,
viewBox: '0 0 24 24',
fill: 'none',
stroke: color,
'stroke-width': 2,
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
onclick
};
</script>
<svg {...svgAttrs}>
<path d="M12 2L2 7l10 5 10-5-10-5z" />
<path d="M2 17l10 5 10-5M2 12l10 5 10-5" />
</svg><script lang="ts">
import type { HTMLAttributes, AriaAttributes, KeyboardEventHandler } from 'svelte/elements';
interface Props extends HTMLAttributes<HTMLDivElement> {
label: string;
checked?: boolean;
onToggle?: (checked: boolean) => void;
}
let { label, checked = $bindable(false), onToggle, ...attrs }: Props = $props();
const toggle = () => {
checked = !checked;
onToggle?.(checked);
};
const handleKeydown: KeyboardEventHandler<HTMLDivElement> = (e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
toggle();
}
};
let ariaAttrs: AriaAttributes = {
'aria-checked': checked,
'aria-label': label
};
</script>
<div
{...attrs}
{...ariaAttrs}
role="checkbox"
tabindex="0"
onclick={toggle}
onkeydown={handleKeydown}
>
{checked ? '☑' : '☐'} {label}
</div>When creating wrapper components, extend the appropriate element type:
import type { HTMLButtonAttributes } from 'svelte/elements';
interface CustomButtonProps extends HTMLButtonAttributes {
variant: 'primary' | 'secondary';
}Prefer specific event handler types over generic ones:
// Good - specific typing
const handleClick: MouseEventHandler<HTMLButtonElement> = (e) => {
e.currentTarget // HTMLButtonElement
};
// Avoid - generic typing
const handleClick = (e: Event) => {
(e.target as HTMLButtonElement) // requires casting
};Event handlers receive currentTarget with the correct element type:
const handleInput: FormEventHandler<HTMLInputElement> = (e) => {
const value = e.currentTarget.value; // No casting needed
const checked = e.currentTarget.checked; // TypeScript knows this is an input
};Always include ARIA attributes when creating custom interactive elements:
let attrs: AriaAttributes & HTMLAttributes<HTMLDivElement> = {
role: 'button',
tabindex: 0,
'aria-pressed': pressed,
'aria-label': 'Custom button'
};Use tuple types for snippet parameters:
interface Props {
// Single parameter
item: Snippet<[{ id: number; name: string }]>;
// Multiple parameters
cell: Snippet<[number, number, string]>;
// No parameters
header: Snippet;
}Last Updated: 2026-01-08 Svelte Version: 5.46.1