Skip to content

Commit

Permalink
add docs for handleEvent object syntax (#866)
Browse files Browse the repository at this point in the history
  • Loading branch information
titoBouzout authored Sep 25, 2024
1 parent 793a9ba commit b3f39c8
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 27 deletions.
8 changes: 6 additions & 2 deletions src/middleware/legacy-routes-redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ const LEGACY_ROUTES = {
"/references/api-reference/special-jsx-attributes/classList": "/reference/jsx-attributes/classlist",
"/references/api-reference/special-jsx-attributes/innerHTML-or-textContent": "/reference/jsx-attributes/innerhtml-or-textcontent",
"/references/api-reference/special-jsx-attributes/on_": "/reference/jsx-attributes/on_",
"/references/api-reference/special-jsx-attributes/on_-and-oncapture_": "/reference/jsx-attributes/on-and-oncapture",
"/references/api-reference/special-jsx-attributes/on_-and-oncapture_": "/reference/jsx-attributes/on",

"/references/api-reference/special-jsx-attributes/once": "/reference/jsx-attributes/once",
"/references/api-reference/special-jsx-attributes/prop_": "/reference/jsx-attributes/prop",
"/references/api-reference/special-jsx-attributes/ref": "/reference/jsx-attributes/ref",
Expand Down Expand Up @@ -102,7 +103,10 @@ const LEGACY_ROUTES = {
"/references/concepts/reactivity/tracking": "/concepts/intro-to-reactivity#subscribers",
"/references/concepts/ssr/async-ssr": "/guides/fetching-data",
"/references/concepts/ssr/simple-client-fetching-ssr": "/guides/fetching-data",
"/references/concepts/state-management/context": "/guides/complex-state-management#state-sharing"
"/references/concepts/state-management/context": "/guides/complex-state-management#state-sharing",

// solid-docs-next moves/new location for old pages/solid api updates
"/reference/jsx-attributes/on-and-oncapture": "/reference/jsx-attributes/on",

} as const;

Expand Down
4 changes: 2 additions & 2 deletions src/routes/concepts/components/event-handlers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Event handlers are functions that are called in response to specific events occu

Solid provides two ways to add event listeners to the browser:

- [`on:__`](/reference/jsx-attributes/on-and-oncapture): adds an event listener to the `element`. This is also known as a _native event_.
- [`on:__`](/reference/jsx-attributes/on): adds an event listener to the `element`. This is also known as a _native event_.
- [`on__`](/reference/jsx-attributes/on_): adds an event listener to the `document` and dispatches it to the `element`. This can be referred to as a _delegated event_.

Delegated events flow through the [_component tree_](/concepts/components/basics#component-trees), and save some resources by performing better on commonly used events.
Expand Down Expand Up @@ -85,7 +85,7 @@ This is especially useful when working with a large number of elements, such as
Supported events such as `click`, `input` and `keydown` are just a few examples that are optimized in this way.
To view the full list see the [references below](#list-of-delegated-events).

If you need to attach an event listener to an element that is not supported by Solid's event delegation, such as a custom event in a [custom element](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements), you can use the [`on:__`](/reference/jsx-attributes/on-and-oncapture) form.
If you need to attach an event listener to an element that is not supported by Solid's event delegation, such as a custom event in a [custom element](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements), you can use the [`on:__`](/reference/jsx-attributes/on) form.

```tsx
<div on:customEvent={handleCustomEvent} />
Expand Down
26 changes: 20 additions & 6 deletions src/routes/configuration/typescript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ The following alternative also works when using `Show`:

### Custom event handlers

To handle custom events in Solid, you can use the attributes `on:___` and `oncapture:___`.
To handle custom events in Solid, you can use the attribute `on:___`.
Typing these events requires an extension of Solid's JSX namespace.

```tsx
Expand All @@ -678,29 +678,43 @@ declare module "solid-js" {
interface CustomEvents {
Name: NameEvent; // Matches `on:Name`
}
interface CustomCaptureEvents {
Name: NameEvent; // Matches `oncapture:Name`
}
}
}

// Usage
<div on:Name={(event) => console.log("name is", event.detail.name)} />;
```

<Callout>New in v1.9.0</Callout>

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<HTMLDivElement, Event> = {
once: true,
handleEvent: (event) => {
console.log("will fire only once");
},
}

// Usage
<div on:click={handler} />;
```

<Callout>
**Note**:
By default, using native events like `mousemove` with the `on` prefix — for example, `<div on:mousemove={e => {}} />` — will trigger a TypeScript error.
This occurs because these native events are not part of Solid's custom event type definitions.
To solve this, `CustomEvents` and `CustomCaptureEvents` interfaces can be extended to include events from the `HTMLElementEventMap`:
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 {}
interface CustomCaptureEvents extends HTMLElementEventMap {}
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion src/routes/reference/jsx-attributes/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"bool.mdx",
"innerhtml-or-textcontent.mdx",
"on_.mdx",
"on-and-oncapture.mdx",
"on.mdx",
"once.mdx",
"prop.mdx",
"ref.mdx",
Expand Down
14 changes: 0 additions & 14 deletions src/routes/reference/jsx-attributes/on-and-oncapture.mdx

This file was deleted.

35 changes: 35 additions & 0 deletions src/routes/reference/jsx-attributes/on.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: on:*
order: 4
---

For events with capital letters, listener options, or if you need to attach event handlers directly to a DOM element instead of optimized delegating via the document, use `on:*` in place of `on*`.

```tsx
<div on:DOMContentLoaded={(e) => console.log("Welcome!")} />
```

This directly attaches an event handler (via [`addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)) to the `div`.

<Callout>New in v1.9.0</Callout>

An aditional special syntax that allows full control of [`capture`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#capture), [`passive`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#passive), [`once`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#once) and [`signal`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#signal) is an intersection or combination of `EventListenerObject` & `AddEventListenerOptions`, as follows:

```tsx
const handler = {
handleEvent(e) {
console.log(e)
},
once:true,
passive:false,
capture:true
}

<div on:wheel={handler} />

// or inline

<div on:click={{passive:true, handleEvent(e) => console.log("Weeeee!")}} />
```

This new syntax replaces the now deprecated `oncapture:` and it's future proof for any posible new event listener options.
4 changes: 2 additions & 2 deletions src/routes/reference/jsx-attributes/on_.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Event handlers in Solid typically take the form of `onclick` or `onClick` depend

Conceptually, this example attaches a `click` event listener (via [`addEventListener`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)) to the `div`. However, Solid actually handles common UI events that bubble and are composed (such as `click`) at the document level, and then synthetically implements delegation (capturing and bubbling). This improves performance for these common events by reducing the number of event handlers.

Note that `onClick` handles the event `click`; in general, event names get mapped to lower case. If you need to work with event names containing capital letters, see [`on:`](/reference/jsx-attributes/on-and-oncapture) which attaches event handlers directly (also avoiding fancy delegation via document).
Note that `onClick` handles the event `click`; in general, event names get mapped to lower case. If you need to work with event names containing capital letters, or use listener options such once, passive, capture see [`on:`](/reference/jsx-attributes/on) which attaches event handlers directly (also avoiding fancy delegation via document).

Solid also supports passing a two-element array to the event handler to bind a value to the first argument of the event handler. This doesn't use `bind` or create an additional closure, so it is a highly optimized way of delegating events.

Expand All @@ -22,7 +22,7 @@ function handler(itemId, e) {

<ul>
<For each={state.list}>{(item) => <li onClick={[handler, item.id]} />}</For>
</ul>
</ul>;
```

Events are never rebound and the bindings are not reactive, as it is expensive to attach and detach listeners. Since event handlers are called like any other function each time an event fires, there is no need for reactivity; shortcut your handler if desired.
Expand Down

0 comments on commit b3f39c8

Please sign in to comment.