From bd5812f569131618aeabad5533cf8f8730f0ff15 Mon Sep 17 00:00:00 2001 From: harshagarwalnyu Date: Mon, 1 Jun 2026 08:05:24 +0400 Subject: [PATCH 1/2] docs: restructure TypeScript event handling sections - Move custom/native on: event docs into API types > Event handling - Add dedicated section for on: directive with subsections for custom and native events - Convert native events callout to a proper subsection - Promote Forcing properties and Custom directives headings to h3 so they appear in the page outline Closes #569 --- src/routes/(3)configuration/(1)typescript.mdx | 165 +++++++++--------- 1 file changed, 83 insertions(+), 82 deletions(-) diff --git a/src/routes/(3)configuration/(1)typescript.mdx b/src/routes/(3)configuration/(1)typescript.mdx index dc1f21a585..a0af7bad8a 100644 --- a/src/routes/(3)configuration/(1)typescript.mdx +++ b/src/routes/(3)configuration/(1)typescript.mdx @@ -442,6 +442,86 @@ In the type signature `JSX.EventHandler`, `currentTarget` will consistentl However, the type of target could be more generic, potentially any DOM element. For specific events like `Input` and `Focus` that are directly associated with input elements, the target will have the type `HTMLInputElement`. +#### The `on:` directive + +The `on:___` attribute provides low-level access to native DOM `addEventListener`, allowing custom event types and listener options. + +##### Custom events + +To handle custom events, extend Solid's JSX namespace with the `CustomEvents` interface: + +```tsx +class NameEvent extends CustomEvent { + type: "Name"; + detail: { name: string }; + + constructor(name: string) { + super("Name", { detail: { name } }); + } +} + +declare module "solid-js" { + namespace JSX { + interface CustomEvents { + Name: NameEvent; // Matches `on:Name` + } + } +} + +// Usage +
console.log("name is", event.detail.name)} />; +``` + +:::note + +New in v1.9.0 +::: + +It is now possible to use the intersection `EventListenerObject & AddEventListenerOptions` to provide listener options as follows: + +```tsx +import type { JSX } from "solid-js" + +const handler: JSX.EventHandlerWithOptions = { + once: true, + handleEvent: (event) => { + console.log("will fire only once"); + }, +} + +// Usage +
; +``` + +##### Using native events with `on:` + +By default, using native events like `mousemove` with the `on` prefix — for example, `
{}} />` — will trigger a TypeScript error. +This occurs because these native events are not part of Solid's custom event type definitions. +To solve this, the `CustomEvents` interface can be extended to include events from the `HTMLElementEventMap`. + +To include all native events: + +```ts +declare module "solid-js" { + namespace JSX { + interface CustomEvents extends HTMLElementEventMap {} + } +} +``` + +To include specific native events, you can choose certain events (e.g. `mousemove` and `pointermove`): + +```ts +declare module "solid-js" { + namespace JSX { + interface CustomEvents extends Pick< + HTMLElementEventMap, + "mousemove" | "pointermove" + > {} + } +} +``` + ### `ref` attribute #### Basics @@ -632,86 +712,7 @@ The following alternative also works when using `Show`: ## Advanced JSX attributes and directives -### Custom event handlers - -To handle custom events in Solid, you can use the attribute `on:___`. -Typing these events requires an extension of Solid's JSX namespace. - -```tsx -class NameEvent extends CustomEvent { - type: "Name"; - detail: { name: string }; - - constructor(name: string) { - super("Name", { detail: { name } }); - } -} - -declare module "solid-js" { - namespace JSX { - interface CustomEvents { - Name: NameEvent; // Matches `on:Name` - } - } -} - -// Usage -
console.log("name is", event.detail.name)} />; -``` - -:::note - -New in v1.9.0 -::: - -It is now possible to use the intersection `EventListenerObject & AddEventListenerOptions` to provide listener options as follows: - -```tsx -import type { JSX } from "solid-js" - -const handler: JSX.EventHandlerWithOptions = { - once: true, - handleEvent: (event) => { - console.log("will fire only once"); - }, -} - -// Usage -
; -``` - -:::note -**Note**: -By default, using native events like `mousemove` with the `on` prefix — for example, `
{}} />` — will trigger a TypeScript error. -This occurs because these native events are not part of Solid's custom event type definitions. -To solve this, the `CustomEvents` interface can be extended to include events from the `HTMLElementEventMap`: - -To include all native events: - -```ts -declare module "solid-js" { - namespace JSX { - interface CustomEvents extends HTMLElementEventMap {} - } -} -``` - -To include specific native events, you can choose certain events (e.g. `mousemove` and `pointermove`): - -```ts -declare module "solid-js" { - namespace JSX { - interface CustomEvents extends Pick< - HTMLElementEventMap, - "mousemove" | "pointermove" - > {} - } -} -``` - -::: - -#### Forcing properties and custom attributes +### Forcing properties and custom attributes In Solid, the `prop:___` directive allows explicit property setting, which is useful for retaining the original data types like objects or arrays. `attr:___` directive allows custom attributes, on the other hand, and it is effective for handling string-based HTML attributes. @@ -738,7 +739,7 @@ declare module "solid-js" { ``` -#### Custom directives +### Custom directives In Solid, custom directives can be applied using the `use:___` attribute, which usually accepts a target element and a JSX attribute value. The traditional `Directives` interface types these values directly (i.e. the type of `value` in `
`). @@ -823,7 +824,7 @@ While the `Directives` interface can limit the value type passed via JSX attribu
``` -##### Addressing import issues with directives +#### Addressing import issues with directives If directives are imported from a separate file or module, TypeScript might mistakenly remove the import thinking it is a type. From 8a1566ec3f9a63594bd0fe38194a328525e06368 Mon Sep 17 00:00:00 2001 From: harshagarwalnyu Date: Mon, 1 Jun 2026 08:09:54 +0400 Subject: [PATCH 2/2] docs: address copilot review feedback on typescript page - Use CustomEvent<{name: string}> generic instead of field declarations - Fix semicolon and whitespace in EventHandlerWithOptions example - Change on prefix to on: prefix for clarity - Note that HTMLElementEventMap covers HTML element events only --- src/routes/(3)configuration/(1)typescript.mdx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/routes/(3)configuration/(1)typescript.mdx b/src/routes/(3)configuration/(1)typescript.mdx index a0af7bad8a..826ef02684 100644 --- a/src/routes/(3)configuration/(1)typescript.mdx +++ b/src/routes/(3)configuration/(1)typescript.mdx @@ -451,10 +451,7 @@ The `on:___` attribute provides low-level access to native DOM `addEventListener To handle custom events, extend Solid's JSX namespace with the `CustomEvents` interface: ```tsx -class NameEvent extends CustomEvent { - type: "Name"; - detail: { name: string }; - +class NameEvent extends CustomEvent<{ name: string }> { constructor(name: string) { super("Name", { detail: { name } }); } @@ -480,9 +477,9 @@ declare module "solid-js" { It is now possible to use the intersection `EventListenerObject & AddEventListenerOptions` to provide listener options as follows: ```tsx -import type { JSX } from "solid-js" +import type { JSX } from "solid-js"; -const handler: JSX.EventHandlerWithOptions = { +const handler: JSX.EventHandlerWithOptions = { once: true, handleEvent: (event) => { console.log("will fire only once"); @@ -495,9 +492,9 @@ const handler: JSX.EventHandlerWithOptions = { ##### Using native events with `on:` -By default, using native events like `mousemove` with the `on` prefix — for example, `
{}} />` — will trigger a TypeScript error. +By default, using native events like `mousemove` with the `on:` prefix — for example, `
{}} />` — will trigger a TypeScript error. This occurs because these native events are not part of Solid's custom event type definitions. -To solve this, the `CustomEvents` interface can be extended to include events from the `HTMLElementEventMap`. +To solve this, the `CustomEvents` interface can be extended to include events from the `HTMLElementEventMap` (which covers HTML element events — not `Document` or `Window` events). To include all native events: