0
# Modules
1
2
Snabbdom modules extend the core functionality to handle different aspects of DOM elements. Six built-in modules are provided for common use cases.
3
4
## Capabilities
5
6
### Attributes Module
7
8
Manages HTML attributes on DOM elements with support for boolean attributes and XML namespaces.
9
10
```typescript { .api }
11
/**
12
* Attributes module for managing HTML attributes
13
*/
14
const attributesModule: Module;
15
16
type Attrs = Record<string, string | number | boolean>;
17
```
18
19
**Usage Example:**
20
21
```typescript
22
import { init, attributesModule, h } from "snabbdom";
23
24
const patch = init([attributesModule]);
25
26
const vnode = h("input", {
27
attrs: {
28
type: "text",
29
placeholder: "Enter name",
30
required: true, // boolean attribute
31
disabled: false // will be removed
32
}
33
});
34
```
35
36
### Class Module
37
38
Provides dynamic CSS class management with boolean flags for toggling classes.
39
40
```typescript { .api }
41
/**
42
* Class module for managing CSS classes
43
*/
44
const classModule: Module;
45
46
type Classes = Record<string, boolean>;
47
```
48
49
**Usage Example:**
50
51
```typescript
52
import { init, classModule, h } from "snabbdom";
53
54
const patch = init([classModule]);
55
56
const isActive = true;
57
const vnode = h("div", {
58
class: {
59
active: isActive,
60
inactive: !isActive,
61
"btn-primary": true,
62
hidden: false // class will be removed
63
}
64
});
65
```
66
67
### Dataset Module
68
69
Manages HTML5 data-* attributes through the HTMLElement.dataset property.
70
71
```typescript { .api }
72
/**
73
* Dataset module for managing data-* attributes
74
*/
75
const datasetModule: Module;
76
77
type Dataset = Record<string, string>;
78
```
79
80
**Usage Example:**
81
82
```typescript
83
import { init, datasetModule, h } from "snabbdom";
84
85
const patch = init([datasetModule]);
86
87
const vnode = h("button", {
88
dataset: {
89
action: "save",
90
target: "user-form",
91
userId: "123"
92
}
93
});
94
// Results in: <button data-action="save" data-target="user-form" data-user-id="123">
95
```
96
97
### Event Listeners Module
98
99
Manages DOM event listeners with efficient listener swapping and array-based handlers.
100
101
```typescript { .api }
102
/**
103
* Event listeners module for managing DOM events
104
*/
105
const eventListenersModule: Module;
106
107
type On = {
108
[N in keyof HTMLElementEventMap]?:
109
| Listener<HTMLElementEventMap[N]>
110
| Array<Listener<HTMLElementEventMap[N]>>;
111
} & {
112
[event: string]: Listener<any> | Array<Listener<any>>;
113
};
114
115
type Listener<T> = (this: VNode, ev: T, vnode: VNode) => void;
116
```
117
118
**Usage Example:**
119
120
```typescript
121
import { init, eventListenersModule, h } from "snabbdom";
122
123
const patch = init([eventListenersModule]);
124
125
function handleClick(ev: MouseEvent, vnode: VNode) {
126
console.log("Button clicked!", ev.target);
127
}
128
129
function handleMouseOver(ev: MouseEvent, vnode: VNode) {
130
console.log("Mouse over button");
131
}
132
133
const vnode = h("button", {
134
on: {
135
click: handleClick,
136
mouseover: handleMouseOver,
137
keydown: [
138
(ev: KeyboardEvent) => console.log("Key:", ev.key),
139
(ev: KeyboardEvent) => console.log("Code:", ev.code)
140
]
141
}
142
}, "Interactive Button");
143
```
144
145
### Props Module
146
147
Sets DOM element properties directly (not attributes) for form elements and custom properties.
148
149
```typescript { .api }
150
/**
151
* Props module for managing DOM element properties
152
*/
153
const propsModule: Module;
154
155
type Props = Record<string, any>;
156
```
157
158
**Usage Example:**
159
160
```typescript
161
import { init, propsModule, h } from "snabbdom";
162
163
const patch = init([propsModule]);
164
165
const vnode = h("input", {
166
props: {
167
type: "checkbox",
168
checked: true,
169
value: "option1",
170
disabled: false
171
}
172
});
173
174
// For custom elements
175
const customElement = h("my-component", {
176
props: {
177
customProperty: { complex: "object" },
178
callback: () => console.log("callback")
179
}
180
});
181
```
182
183
### Style Module
184
185
Manages CSS styles with support for animations, delayed properties, and removal transitions.
186
187
```typescript { .api }
188
/**
189
* Style module for managing CSS styles with animation support
190
*/
191
const styleModule: Module;
192
193
type VNodeStyle = ElementStyle &
194
Record<string, string> & {
195
delayed?: ElementStyle & Record<string, string>;
196
remove?: ElementStyle & Record<string, string>;
197
destroy?: ElementStyle & Record<string, string>;
198
};
199
200
type ElementStyle = Partial<CSSStyleDeclaration>;
201
```
202
203
**Usage Examples:**
204
205
```typescript
206
import { init, styleModule, h } from "snabbdom";
207
208
const patch = init([styleModule]);
209
210
// Basic styling
211
const styled = h("div", {
212
style: {
213
color: "blue",
214
fontSize: "16px",
215
backgroundColor: "#f0f0f0"
216
}
217
});
218
219
// CSS custom properties (variables)
220
const withVariables = h("div", {
221
style: {
222
"--primary-color": "#007bff",
223
"--font-size": "14px",
224
color: "var(--primary-color)"
225
}
226
});
227
228
// Delayed properties (for entrance animations)
229
const animated = h("div", {
230
style: {
231
opacity: "0",
232
transform: "translateY(-10px)",
233
transition: "all 0.3s ease",
234
delayed: {
235
opacity: "1",
236
transform: "translateY(0)"
237
}
238
}
239
});
240
241
// Remove properties (for exit animations)
242
const fadeOut = h("div", {
243
style: {
244
opacity: "1",
245
transition: "opacity 0.3s ease",
246
remove: {
247
opacity: "0"
248
}
249
}
250
});
251
```
252
253
## Module System
254
255
### Creating Custom Modules
256
257
Modules are objects that implement lifecycle hooks to extend Snabbdom functionality.
258
259
```typescript { .api }
260
interface Module {
261
pre?: PreHook;
262
create?: CreateHook;
263
update?: UpdateHook;
264
destroy?: DestroyHook;
265
remove?: RemoveHook;
266
post?: PostHook;
267
}
268
269
type PreHook = () => any;
270
type CreateHook = (emptyVNode: VNode, vNode: VNode) => any;
271
type UpdateHook = (oldVNode: VNode, vNode: VNode) => any;
272
type DestroyHook = (vNode: VNode) => any;
273
type RemoveHook = (vNode: VNode, removeCallback: () => void) => any;
274
type PostHook = () => any;
275
```
276
277
**Custom Module Example:**
278
279
```typescript
280
import { Module, VNode, VNodeData } from "snabbdom";
281
282
// Custom module for logging
283
const logModule: Module = {
284
create: (emptyVnode: VNode, vnode: VNode) => {
285
console.log("Element created:", vnode.sel);
286
},
287
update: (oldVnode: VNode, vnode: VNode) => {
288
console.log("Element updated:", vnode.sel);
289
},
290
destroy: (vnode: VNode) => {
291
console.log("Element destroyed:", vnode.sel);
292
}
293
};
294
295
// Use the custom module
296
const patch = init([logModule, classModule, styleModule]);
297
```