foldkit 0.129.0 → 0.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/THIRD-PARTY-NOTICES.md +30 -0
  2. package/dist/brand/brand.d.ts +25 -0
  3. package/dist/brand/brand.d.ts.map +1 -0
  4. package/dist/brand/brand.js +50 -0
  5. package/dist/brand/index.d.ts +2 -0
  6. package/dist/brand/index.d.ts.map +1 -0
  7. package/dist/brand/index.js +1 -0
  8. package/dist/brand/public.d.ts +2 -0
  9. package/dist/brand/public.d.ts.map +1 -0
  10. package/dist/brand/public.js +1 -0
  11. package/dist/canvas/view.d.ts.map +1 -1
  12. package/dist/canvas/view.js +1 -1
  13. package/dist/devTools/protocol.d.ts +1 -1
  14. package/dist/devTools/protocol.d.ts.map +1 -1
  15. package/dist/devTools/protocol.js +1 -1
  16. package/dist/devTools/store.js +2 -2
  17. package/dist/devTools/webSocketBridge.d.ts +1 -1
  18. package/dist/devTools/webSocketBridge.js +1 -1
  19. package/dist/html/index.d.ts +18 -18
  20. package/dist/html/index.d.ts.map +1 -1
  21. package/dist/html/index.js +530 -460
  22. package/dist/html/lazy.d.ts +1 -1
  23. package/dist/html/lazy.d.ts.map +1 -1
  24. package/dist/html/lazy.js +11 -2
  25. package/dist/propsModule.d.ts +1 -1
  26. package/dist/propsModule.d.ts.map +1 -1
  27. package/dist/propsModule.js +6 -1
  28. package/dist/runtime/runtime.d.ts.map +1 -1
  29. package/dist/runtime/runtime.js +468 -278
  30. package/dist/snabbdom/attributes.d.ts +4 -0
  31. package/dist/snabbdom/attributes.d.ts.map +1 -0
  32. package/dist/snabbdom/attributes.js +63 -0
  33. package/dist/snabbdom/class.d.ts +4 -0
  34. package/dist/snabbdom/class.d.ts.map +1 -0
  35. package/dist/snabbdom/class.js +31 -0
  36. package/dist/snabbdom/dataset.d.ts +4 -0
  37. package/dist/snabbdom/dataset.d.ts.map +1 -0
  38. package/dist/snabbdom/dataset.js +42 -0
  39. package/dist/snabbdom/eventlisteners.d.ts +11 -0
  40. package/dist/snabbdom/eventlisteners.d.ts.map +1 -0
  41. package/dist/snabbdom/eventlisteners.js +85 -0
  42. package/dist/snabbdom/h.d.ts +11 -0
  43. package/dist/snabbdom/h.d.ts.map +1 -0
  44. package/dist/snabbdom/h.js +61 -0
  45. package/dist/snabbdom/hooks.d.ts +24 -0
  46. package/dist/snabbdom/hooks.d.ts.map +1 -0
  47. package/dist/snabbdom/hooks.js +1 -0
  48. package/dist/snabbdom/htmldomapi.d.ts +34 -0
  49. package/dist/snabbdom/htmldomapi.d.ts.map +1 -0
  50. package/dist/snabbdom/htmldomapi.js +111 -0
  51. package/dist/snabbdom/index.d.ts +15 -0
  52. package/dist/snabbdom/index.d.ts.map +1 -0
  53. package/dist/snabbdom/index.js +9 -0
  54. package/dist/snabbdom/init.d.ts +14 -0
  55. package/dist/snabbdom/init.d.ts.map +1 -0
  56. package/dist/snabbdom/init.js +486 -0
  57. package/dist/snabbdom/is.d.ts +3 -0
  58. package/dist/snabbdom/is.d.ts.map +1 -0
  59. package/dist/snabbdom/is.js +7 -0
  60. package/dist/snabbdom/module.d.ts +11 -0
  61. package/dist/snabbdom/module.d.ts.map +1 -0
  62. package/dist/snabbdom/module.js +1 -0
  63. package/dist/snabbdom/props.d.ts +2 -0
  64. package/dist/snabbdom/props.d.ts.map +1 -0
  65. package/dist/snabbdom/props.js +1 -0
  66. package/dist/snabbdom/style.d.ts +9 -0
  67. package/dist/snabbdom/style.d.ts.map +1 -0
  68. package/dist/snabbdom/style.js +123 -0
  69. package/dist/snabbdom/tovnode.d.ts +4 -0
  70. package/dist/snabbdom/tovnode.d.ts.map +1 -0
  71. package/dist/snabbdom/tovnode.js +69 -0
  72. package/dist/snabbdom/vnode.d.ts +46 -0
  73. package/dist/snabbdom/vnode.d.ts.map +1 -0
  74. package/dist/snabbdom/vnode.js +13 -0
  75. package/dist/vdom.d.ts +2 -2
  76. package/dist/vdom.d.ts.map +1 -1
  77. package/dist/vdom.js +1 -1
  78. package/package.json +7 -5
  79. package/dist/runtime/messagePriority.d.ts +0 -17
  80. package/dist/runtime/messagePriority.d.ts.map +0 -1
  81. package/dist/runtime/messagePriority.js +0 -33
  82. package/dist/runtime/renderLoop.d.ts +0 -27
  83. package/dist/runtime/renderLoop.d.ts.map +0 -1
  84. package/dist/runtime/renderLoop.js +0 -25
@@ -1,6 +1,6 @@
1
- import { Array, Context, Data, Effect, Fiber, Function, Match, Option, Predicate, Stream, String, pipe, } from 'effect';
2
- import { h } from 'snabbdom';
1
+ import { Array, Context, Data, Effect, Fiber, Function, Option, Stream, } from 'effect';
3
2
  import { MountTracker } from '../mount/index.js';
3
+ import { VNodeDataMask, h, vnodeDataMaskKey, } from '../snabbdom/index.js';
4
4
  import { isChildAttribute } from './childAttribute.js';
5
5
  import { checkScheduledLeave, clearDragZoneAfterDrop, getDragZoneState, processDragEnter, processDragLeave, } from './dragZoneTracking.js';
6
6
  import { clearRuntime, requireBoundaryMappers, requireDispatch, requireRuntimeContext, requireUnmountResolver, setRuntime, } from './runtimeSingleton.js';
@@ -87,18 +87,46 @@ export { Prop, OnCustomEvent };
87
87
  const setData = (ctx, key, value) => {
88
88
  ctx.data[key] = value;
89
89
  };
90
- const updateData = (ctx, key, value) => {
91
- const existing = ctx.data[key];
92
- if (existing === undefined) {
93
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
94
- ctx.data[key] = value;
90
+ const addVNodeDataMask = (ctx, dataMask) => {
91
+ ctx.data[vnodeDataMaskKey] = (ctx.data[vnodeDataMaskKey] ?? 0) | dataMask;
92
+ };
93
+ const setModuleData = (ctx, key, value, dataMask) => {
94
+ ctx.data[key] = value;
95
+ addVNodeDataMask(ctx, dataMask);
96
+ };
97
+ // NOTE: single-key fast paths. The bulk of attribute handlers set exactly
98
+ // one prop, attr, or event handler; writing it directly into the vnode data
99
+ // avoids allocating a `{ key: value }` literal and merging it per attribute.
100
+ const setDataProp = (ctx, key, value) => {
101
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
102
+ const props = (ctx.data.props ??= {});
103
+ props[key] = value;
104
+ addVNodeDataMask(ctx, VNodeDataMask.Props);
105
+ };
106
+ const setDataAttr = (ctx, key, value) => {
107
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
108
+ const attrs = (ctx.data.attrs ??= {});
109
+ attrs[key] = value;
110
+ addVNodeDataMask(ctx, VNodeDataMask.Attrs);
111
+ };
112
+ const addDataOn = (ctx, eventName, handler) => {
113
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
114
+ const on = (ctx.data.on ??= {});
115
+ addVNodeDataMask(ctx, VNodeDataMask.On);
116
+ const existingHandler = on[eventName];
117
+ if (existingHandler === undefined) {
118
+ on[eventName] = handler;
95
119
  }
96
120
  else {
97
- Object.assign(existing, value);
121
+ // NOTE: chain in registration order, mirroring updateDataOn.
122
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
123
+ const previous = existingHandler;
124
+ on[eventName] = (...args) => {
125
+ previous(...args);
126
+ handler(...args);
127
+ };
98
128
  }
99
129
  };
100
- const updateDataProps = (ctx, props) => updateData(ctx, 'props', props);
101
- const updateDataAttrs = (ctx, attrs) => updateData(ctx, 'attrs', attrs);
102
130
  // Event handlers chain per DOM event in spread order. Without this,
103
131
  // `Object.assign` would silently drop earlier handlers for the same
104
132
  // event when a consumer spreads published ChildAttributes alongside
@@ -108,6 +136,7 @@ const updateDataAttrs = (ctx, attrs) => updateData(ctx, 'attrs', attrs);
108
136
  // earlier handler throws, later handlers do not run (mirroring native
109
137
  // exception propagation, not silently swallowing bugs).
110
138
  const updateDataOn = (ctx, on) => {
139
+ addVNodeDataMask(ctx, VNodeDataMask.On);
111
140
  if (ctx.data.on === undefined) {
112
141
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
113
142
  ctx.data.on = on;
@@ -135,40 +164,55 @@ const updateDataOn = (ctx, on) => {
135
164
  }
136
165
  };
137
166
  const updatePropsWithPostpatch = (ctx, propName, value) => {
138
- updateDataProps(ctx, { [propName]: value });
139
- ctx.postpatchProps.push({ propName, value });
167
+ setDataProp(ctx, propName, value);
168
+ ctx.getPostpatchProps().push({ propName, value });
140
169
  };
141
- // NOTE: Built once at module load. The matcher dispatches on `_tag` and
142
- // returns a thunk that applies the resulting mutation to a per-VNode
143
- // BuildContext. Per-attribute cost drops from O(matcher arms) closure
144
- // allocations to one thunk. `Attribute<unknown>` is the runtime-erased
145
- // shape. Message is purely a TypeScript parameter at this level and
146
- // DispatchSync already accepts unknown.
147
- const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
148
- Key: ({ value }) => (ctx) => setData(ctx, 'key', value),
149
- Class: ({ value }) => {
150
- const classObject = pipe(value, String.split(/\s+/), Array.filter(String.isNonEmpty), Array.reduce({}, (acc, className) => ({
151
- ...acc,
152
- [className]: true,
153
- })));
154
- return (ctx) => setData(ctx, 'class', classObject);
155
- },
156
- Id: ({ value }) => (ctx) => updateDataProps(ctx, { id: value }),
157
- Title: ({ value }) => (ctx) => updateDataProps(ctx, { title: value }),
158
- Lang: ({ value }) => (ctx) => updateDataProps(ctx, { lang: value }),
159
- Dir: ({ value }) => (ctx) => updateDataProps(ctx, { dir: value }),
160
- Tabindex: ({ value }) => (ctx) => updateDataProps(ctx, { tabIndex: value }),
161
- Hidden: ({ value }) => (ctx) => updateDataProps(ctx, { hidden: value }),
162
- Contenteditable: ({ value }) => (ctx) => updateDataAttrs(ctx, { contenteditable: value }),
163
- Draggable: ({ value }) => (ctx) => updateDataProps(ctx, { draggable: value }),
164
- Accesskey: ({ value }) => (ctx) => updateDataAttrs(ctx, { accesskey: value }),
165
- Translate: ({ value }) => (ctx) => updateDataAttrs(ctx, { translate: value }),
166
- Inert: ({ value }) => (ctx) => updateDataProps(ctx, { inert: value }),
167
- Popover: ({ value }) => (ctx) => updateDataAttrs(ctx, { popover: value }),
168
- Popovertarget: ({ value }) => (ctx) => updateDataAttrs(ctx, { popovertarget: value }),
169
- Popovertargetaction: ({ value }) => (ctx) => updateDataAttrs(ctx, { popovertargetaction: value }),
170
- OnClick: ({ message }) => (ctx) => updateDataOn(ctx, { click: () => ctx.dispatch(message) }),
171
- OnClickFocus: ({ focusSelector, message }) => (ctx) => updateDataOn(ctx, {
170
+ // NOTE: class strings repeat heavily across elements and renders, so the
171
+ // parsed class object is cached per distinct string. Cached objects are
172
+ // shared across vnodes; snabbdom's classModule only reads them, and the
173
+ // Class handler installs them via `setData` (never merged into), so sharing
174
+ // is safe. Class strings interpolated from model data can take unboundedly
175
+ // many values, so the cache clears at a size cap instead of retaining every
176
+ // string for the page lifetime; the render after a clear re-parses and
177
+ // re-caches what it actually uses.
178
+ const CLASS_OBJECT_CACHE_LIMIT = 10_000;
179
+ const classObjectCache = new Map();
180
+ const classObjectFor = (value) => {
181
+ const cached = classObjectCache.get(value);
182
+ if (cached !== undefined) {
183
+ return cached;
184
+ }
185
+ const classObject = {};
186
+ for (const className of value.split(/\s+/)) {
187
+ if (className !== '') {
188
+ classObject[className] = true;
189
+ }
190
+ }
191
+ if (classObjectCache.size >= CLASS_OBJECT_CACHE_LIMIT) {
192
+ classObjectCache.clear();
193
+ }
194
+ classObjectCache.set(value, classObject);
195
+ return classObject;
196
+ };
197
+ const attributeHandlers = {
198
+ Key: ({ value }, ctx) => setData(ctx, 'key', value),
199
+ Class: ({ value }, ctx) => setModuleData(ctx, 'class', classObjectFor(value), VNodeDataMask.Class),
200
+ Id: ({ value }, ctx) => setDataProp(ctx, 'id', value),
201
+ Title: ({ value }, ctx) => setDataProp(ctx, 'title', value),
202
+ Lang: ({ value }, ctx) => setDataProp(ctx, 'lang', value),
203
+ Dir: ({ value }, ctx) => setDataProp(ctx, 'dir', value),
204
+ Tabindex: ({ value }, ctx) => setDataProp(ctx, 'tabIndex', value),
205
+ Hidden: ({ value }, ctx) => setDataProp(ctx, 'hidden', value),
206
+ Contenteditable: ({ value }, ctx) => setDataAttr(ctx, 'contenteditable', value),
207
+ Draggable: ({ value }, ctx) => setDataProp(ctx, 'draggable', value),
208
+ Accesskey: ({ value }, ctx) => setDataAttr(ctx, 'accesskey', value),
209
+ Translate: ({ value }, ctx) => setDataAttr(ctx, 'translate', value),
210
+ Inert: ({ value }, ctx) => setDataProp(ctx, 'inert', value),
211
+ Popover: ({ value }, ctx) => setDataAttr(ctx, 'popover', value),
212
+ Popovertarget: ({ value }, ctx) => setDataAttr(ctx, 'popovertarget', value),
213
+ Popovertargetaction: ({ value }, ctx) => setDataAttr(ctx, 'popovertargetaction', value),
214
+ OnClick: ({ message }, ctx) => addDataOn(ctx, 'click', () => ctx.dispatch(message)),
215
+ OnClickFocus: ({ focusSelector, message }, ctx) => updateDataOn(ctx, {
172
216
  click: () => {
173
217
  const focusTarget = document.querySelector(focusSelector);
174
218
  if (focusTarget instanceof HTMLElement) {
@@ -177,61 +221,61 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
177
221
  ctx.dispatch(message);
178
222
  },
179
223
  }),
180
- OnDoubleClick: ({ message }) => (ctx) => updateDataOn(ctx, { dblclick: () => ctx.dispatch(message) }),
181
- OnMouseDown: ({ message }) => (ctx) => updateDataOn(ctx, { mousedown: () => ctx.dispatch(message) }),
182
- OnMouseUp: ({ message }) => (ctx) => updateDataOn(ctx, { mouseup: () => ctx.dispatch(message) }),
183
- OnMouseEnter: ({ message }) => (ctx) => updateDataOn(ctx, { mouseenter: () => ctx.dispatch(message) }),
184
- OnMouseLeave: ({ message }) => (ctx) => updateDataOn(ctx, { mouseleave: () => ctx.dispatch(message) }),
185
- OnMouseOver: ({ message }) => (ctx) => updateDataOn(ctx, { mouseover: () => ctx.dispatch(message) }),
186
- OnMouseOut: ({ message }) => (ctx) => updateDataOn(ctx, { mouseout: () => ctx.dispatch(message) }),
187
- OnMouseMove: ({ message }) => (ctx) => updateDataOn(ctx, { mousemove: () => ctx.dispatch(message) }),
188
- OnPointerMove: ({ f }) => (ctx) => updateDataOn(ctx, {
224
+ OnDoubleClick: ({ message }, ctx) => addDataOn(ctx, 'dblclick', () => ctx.dispatch(message)),
225
+ OnMouseDown: ({ message }, ctx) => addDataOn(ctx, 'mousedown', () => ctx.dispatch(message)),
226
+ OnMouseUp: ({ message }, ctx) => addDataOn(ctx, 'mouseup', () => ctx.dispatch(message)),
227
+ OnMouseEnter: ({ message }, ctx) => addDataOn(ctx, 'mouseenter', () => ctx.dispatch(message)),
228
+ OnMouseLeave: ({ message }, ctx) => addDataOn(ctx, 'mouseleave', () => ctx.dispatch(message)),
229
+ OnMouseOver: ({ message }, ctx) => addDataOn(ctx, 'mouseover', () => ctx.dispatch(message)),
230
+ OnMouseOut: ({ message }, ctx) => addDataOn(ctx, 'mouseout', () => ctx.dispatch(message)),
231
+ OnMouseMove: ({ message }, ctx) => addDataOn(ctx, 'mousemove', () => ctx.dispatch(message)),
232
+ OnPointerMove: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
189
233
  pointermove: (event) => {
190
- const maybeMessage = f(event.screenX, event.screenY, event.pointerType);
234
+ const maybeMessage = toMaybeMessage(event.screenX, event.screenY, event.pointerType);
191
235
  if (Option.isSome(maybeMessage)) {
192
236
  ctx.dispatch(maybeMessage.value);
193
237
  }
194
238
  },
195
239
  }),
196
- OnPointerLeave: ({ f }) => (ctx) => updateDataOn(ctx, {
240
+ OnPointerLeave: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
197
241
  pointerleave: (event) => {
198
- const maybeMessage = f(event.pointerType);
242
+ const maybeMessage = toMaybeMessage(event.pointerType);
199
243
  if (Option.isSome(maybeMessage)) {
200
244
  ctx.dispatch(maybeMessage.value);
201
245
  }
202
246
  },
203
247
  }),
204
- OnPointerDown: ({ f }) => (ctx) => updateDataOn(ctx, {
248
+ OnPointerDown: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
205
249
  pointerdown: (event) => {
206
- const maybeMessage = f(event.pointerType, event.button, event.screenX, event.screenY, event.timeStamp, event.clientX, event.clientY);
250
+ const maybeMessage = toMaybeMessage(event.pointerType, event.button, event.screenX, event.screenY, event.timeStamp, event.clientX, event.clientY);
207
251
  if (Option.isSome(maybeMessage)) {
208
252
  ctx.dispatch(maybeMessage.value);
209
253
  }
210
254
  },
211
255
  }),
212
- OnPointerUp: ({ f }) => (ctx) => updateDataOn(ctx, {
256
+ OnPointerUp: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
213
257
  pointerup: (event) => {
214
- const maybeMessage = f(event.screenX, event.screenY, event.pointerType, event.timeStamp);
258
+ const maybeMessage = toMaybeMessage(event.screenX, event.screenY, event.pointerType, event.timeStamp);
215
259
  if (Option.isSome(maybeMessage)) {
216
260
  ctx.dispatch(maybeMessage.value);
217
261
  }
218
262
  },
219
263
  }),
220
- OnKeyDown: ({ f }) => (ctx) => updateDataOn(ctx, {
221
- keydown: (event) => ctx.dispatch(f(event.key, keyboardModifiers(event))),
264
+ OnKeyDown: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
265
+ keydown: (event) => ctx.dispatch(toMessage(event.key, keyboardModifiers(event))),
222
266
  }),
223
- OnKeyDownPreventDefault: ({ f }) => (ctx) => updateDataOn(ctx, {
267
+ OnKeyDownPreventDefault: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
224
268
  keydown: (event) => {
225
- const maybeMessage = f(event.key, keyboardModifiers(event));
269
+ const maybeMessage = toMaybeMessage(event.key, keyboardModifiers(event));
226
270
  if (Option.isSome(maybeMessage)) {
227
271
  event.preventDefault();
228
272
  ctx.dispatch(maybeMessage.value);
229
273
  }
230
274
  },
231
275
  }),
232
- OnKeyDownFocus: ({ f }) => (ctx) => updateDataOn(ctx, {
276
+ OnKeyDownFocus: ({ f: toMaybeFocusAndMessage }, ctx) => updateDataOn(ctx, {
233
277
  keydown: (event) => {
234
- const maybeResult = f(event.key, keyboardModifiers(event));
278
+ const maybeResult = toMaybeFocusAndMessage(event.key, keyboardModifiers(event));
235
279
  if (Option.isSome(maybeResult)) {
236
280
  event.preventDefault();
237
281
  const { focusSelector, message } = maybeResult.value;
@@ -243,23 +287,23 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
243
287
  }
244
288
  },
245
289
  }),
246
- OnKeyUp: ({ f }) => (ctx) => updateDataOn(ctx, {
247
- keyup: (event) => ctx.dispatch(f(event.key, keyboardModifiers(event))),
290
+ OnKeyUp: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
291
+ keyup: (event) => ctx.dispatch(toMessage(event.key, keyboardModifiers(event))),
248
292
  }),
249
- OnKeyUpPreventDefault: ({ f }) => (ctx) => updateDataOn(ctx, {
293
+ OnKeyUpPreventDefault: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
250
294
  keyup: (event) => {
251
- const maybeMessage = f(event.key, keyboardModifiers(event));
295
+ const maybeMessage = toMaybeMessage(event.key, keyboardModifiers(event));
252
296
  if (Option.isSome(maybeMessage)) {
253
297
  event.preventDefault();
254
298
  ctx.dispatch(maybeMessage.value);
255
299
  }
256
300
  },
257
301
  }),
258
- OnKeyPress: ({ f }) => (ctx) => updateDataOn(ctx, {
259
- keypress: (event) => ctx.dispatch(f(event.key, keyboardModifiers(event))),
302
+ OnKeyPress: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
303
+ keypress: (event) => ctx.dispatch(toMessage(event.key, keyboardModifiers(event))),
260
304
  }),
261
- OnFocus: ({ message }) => (ctx) => updateDataOn(ctx, { focus: () => ctx.dispatch(message) }),
262
- OnBlur: ({ message }) => (ctx) => updateDataOn(ctx, {
305
+ OnFocus: ({ message }, ctx) => addDataOn(ctx, 'focus', () => ctx.dispatch(message)),
306
+ OnBlur: ({ message }, ctx) => updateDataOn(ctx, {
263
307
  blur: (event) => {
264
308
  if (event.relatedTarget instanceof Element &&
265
309
  event.relatedTarget.id === DEVTOOLS_HOST_ID) {
@@ -268,17 +312,17 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
268
312
  ctx.dispatch(message);
269
313
  },
270
314
  }),
271
- OnInput: ({ f }) => (ctx) => updateDataOn(ctx, {
315
+ OnInput: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
272
316
  input: (event) =>
273
317
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
274
- ctx.dispatch(f(event.target.value)),
318
+ ctx.dispatch(toMessage(event.target.value)),
275
319
  }),
276
- OnChange: ({ f }) => (ctx) => updateDataOn(ctx, {
320
+ OnChange: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
277
321
  change: (event) =>
278
322
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
279
- ctx.dispatch(f(event.target.value)),
323
+ ctx.dispatch(toMessage(event.target.value)),
280
324
  }),
281
- OnFileChange: ({ f }) => (ctx) => updateDataOn(ctx, {
325
+ OnFileChange: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
282
326
  change: tagAsFileHandler((event) => {
283
327
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
284
328
  const target = event.target;
@@ -286,36 +330,36 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
286
330
  ? Array.fromIterable(target.files)
287
331
  : Array.empty();
288
332
  target.value = '';
289
- ctx.dispatch(f(files));
333
+ ctx.dispatch(toMessage(files));
290
334
  }, 'OnFileChange'),
291
335
  }),
292
- OnSubmit: ({ message }) => (ctx) => updateDataOn(ctx, {
336
+ OnSubmit: ({ message }, ctx) => updateDataOn(ctx, {
293
337
  submit: (event) => {
294
338
  event.preventDefault();
295
339
  ctx.dispatch(message);
296
340
  },
297
341
  }),
298
- OnReset: ({ message }) => (ctx) => updateDataOn(ctx, { reset: () => ctx.dispatch(message) }),
299
- OnScroll: ({ f }) => (ctx) => updateDataOn(ctx, {
342
+ OnReset: ({ message }, ctx) => addDataOn(ctx, 'reset', () => ctx.dispatch(message)),
343
+ OnScroll: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
300
344
  scroll: (event) =>
301
345
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
302
- ctx.dispatch(f(event.target.scrollTop)),
346
+ ctx.dispatch(toMessage(event.target.scrollTop)),
303
347
  }),
304
- OnWheel: ({ message }) => (ctx) => updateDataOn(ctx, { wheel: () => ctx.dispatch(message) }),
305
- OnCopy: ({ message }) => (ctx) => updateDataOn(ctx, { copy: () => ctx.dispatch(message) }),
306
- OnCut: ({ message }) => (ctx) => updateDataOn(ctx, { cut: () => ctx.dispatch(message) }),
307
- OnPaste: ({ message }) => (ctx) => updateDataOn(ctx, { paste: () => ctx.dispatch(message) }),
308
- OnPastePreventDefault: ({ f }) => (ctx) => updateDataOn(ctx, {
348
+ OnWheel: ({ message }, ctx) => addDataOn(ctx, 'wheel', () => ctx.dispatch(message)),
349
+ OnCopy: ({ message }, ctx) => addDataOn(ctx, 'copy', () => ctx.dispatch(message)),
350
+ OnCut: ({ message }, ctx) => addDataOn(ctx, 'cut', () => ctx.dispatch(message)),
351
+ OnPaste: ({ message }, ctx) => addDataOn(ctx, 'paste', () => ctx.dispatch(message)),
352
+ OnPastePreventDefault: ({ f: toMaybeMessage }, ctx) => updateDataOn(ctx, {
309
353
  paste: (event) => {
310
354
  const text = event.clipboardData?.getData('text/plain') ?? '';
311
- const maybeMessage = f(text);
355
+ const maybeMessage = toMaybeMessage(text);
312
356
  if (Option.isSome(maybeMessage)) {
313
357
  event.preventDefault();
314
358
  ctx.dispatch(maybeMessage.value);
315
359
  }
316
360
  },
317
361
  }),
318
- OnCopyText: ({ text }) => (ctx) => updateDataOn(ctx, {
362
+ OnCopyText: ({ text }, ctx) => updateDataOn(ctx, {
319
363
  copy: (event) => {
320
364
  if (event.clipboardData) {
321
365
  event.clipboardData.setData('text/plain', text);
@@ -323,7 +367,7 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
323
367
  }
324
368
  },
325
369
  }),
326
- OnCutText: ({ text, message }) => (ctx) => updateDataOn(ctx, {
370
+ OnCutText: ({ text, message }, ctx) => updateDataOn(ctx, {
327
371
  cut: (event) => {
328
372
  if (event.clipboardData) {
329
373
  event.clipboardData.setData('text/plain', text);
@@ -332,27 +376,27 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
332
376
  }
333
377
  },
334
378
  }),
335
- OnCancel: ({ message }) => (ctx) => updateDataOn(ctx, {
379
+ OnCancel: ({ message }, ctx) => updateDataOn(ctx, {
336
380
  cancel: (event) => {
337
381
  event.preventDefault();
338
382
  ctx.dispatch(message);
339
383
  },
340
384
  }),
341
- OnToggle: ({ f }) => (ctx) => updateDataOn(ctx, {
385
+ OnToggle: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
342
386
  toggle: event =>
343
387
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
344
- ctx.dispatch(f(event.target.open)),
388
+ ctx.dispatch(toMessage(event.target.open)),
345
389
  }),
346
- OnContextMenu: ({ message }) => (ctx) => updateDataOn(ctx, {
390
+ OnContextMenu: ({ message }, ctx) => updateDataOn(ctx, {
347
391
  contextmenu: (event) => {
348
392
  event.preventDefault();
349
393
  ctx.dispatch(message);
350
394
  },
351
395
  }),
352
- OnDragStart: ({ message }) => (ctx) => updateDataOn(ctx, { dragstart: () => ctx.dispatch(message) }),
353
- OnDrag: ({ message }) => (ctx) => updateDataOn(ctx, { drag: () => ctx.dispatch(message) }),
354
- OnDragEnd: ({ message }) => (ctx) => updateDataOn(ctx, { dragend: () => ctx.dispatch(message) }),
355
- OnDragEnter: ({ message }) => (ctx) => updateDataOn(ctx, {
396
+ OnDragStart: ({ message }, ctx) => addDataOn(ctx, 'dragstart', () => ctx.dispatch(message)),
397
+ OnDrag: ({ message }, ctx) => addDataOn(ctx, 'drag', () => ctx.dispatch(message)),
398
+ OnDragEnd: ({ message }, ctx) => addDataOn(ctx, 'dragend', () => ctx.dispatch(message)),
399
+ OnDragEnter: ({ message }, ctx) => updateDataOn(ctx, {
356
400
  dragenter: (event) => {
357
401
  event.preventDefault();
358
402
  const zone = event.currentTarget;
@@ -366,7 +410,7 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
366
410
  }
367
411
  },
368
412
  }),
369
- OnDragLeave: ({ message }) => (ctx) => updateDataOn(ctx, {
413
+ OnDragLeave: ({ message }, ctx) => updateDataOn(ctx, {
370
414
  dragleave: (event) => {
371
415
  const zone = event.currentTarget;
372
416
  if (!(zone instanceof Element)) {
@@ -383,18 +427,18 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
383
427
  }
384
428
  },
385
429
  }),
386
- OnDragOver: ({ message }) => (ctx) => updateDataOn(ctx, {
430
+ OnDragOver: ({ message }, ctx) => updateDataOn(ctx, {
387
431
  dragover: (event) => {
388
432
  event.preventDefault();
389
433
  ctx.dispatch(message);
390
434
  },
391
435
  }),
392
- AllowDrop: () => (ctx) => updateDataOn(ctx, {
436
+ AllowDrop: (_attribute, ctx) => updateDataOn(ctx, {
393
437
  dragover: (event) => {
394
438
  event.preventDefault();
395
439
  },
396
440
  }),
397
- OnDrop: ({ message }) => (ctx) => updateDataOn(ctx, {
441
+ OnDrop: ({ message }, ctx) => updateDataOn(ctx, {
398
442
  drop: (event) => {
399
443
  event.preventDefault();
400
444
  const zone = event.currentTarget;
@@ -404,7 +448,7 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
404
448
  ctx.dispatch(message);
405
449
  },
406
450
  }),
407
- OnDropFiles: ({ f }) => (ctx) => updateDataOn(ctx, {
451
+ OnDropFiles: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
408
452
  drop: tagAsFileHandler((event) => {
409
453
  event.preventDefault();
410
454
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
@@ -416,260 +460,260 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
416
460
  const files = dragEvent.dataTransfer?.files
417
461
  ? Array.fromIterable(dragEvent.dataTransfer.files)
418
462
  : Array.empty();
419
- ctx.dispatch(f(files));
463
+ ctx.dispatch(toMessage(files));
420
464
  }, 'OnDropFiles'),
421
465
  }),
422
- OnTouchStart: ({ message }) => (ctx) => updateDataOn(ctx, { touchstart: () => ctx.dispatch(message) }),
423
- OnTouchEnd: ({ message }) => (ctx) => updateDataOn(ctx, { touchend: () => ctx.dispatch(message) }),
424
- OnTouchMove: ({ message }) => (ctx) => updateDataOn(ctx, { touchmove: () => ctx.dispatch(message) }),
425
- OnTouchCancel: ({ message }) => (ctx) => updateDataOn(ctx, { touchcancel: () => ctx.dispatch(message) }),
426
- OnAnimationStart: ({ message }) => (ctx) => updateDataOn(ctx, { animationstart: () => ctx.dispatch(message) }),
427
- OnAnimationEnd: ({ message }) => (ctx) => updateDataOn(ctx, { animationend: () => ctx.dispatch(message) }),
428
- OnAnimationIteration: ({ message }) => (ctx) => updateDataOn(ctx, { animationiteration: () => ctx.dispatch(message) }),
429
- OnTransitionEnd: ({ message }) => (ctx) => updateDataOn(ctx, { transitionend: () => ctx.dispatch(message) }),
430
- OnLoad: ({ message }) => (ctx) => updateDataOn(ctx, { load: () => ctx.dispatch(message) }),
431
- OnError: ({ message }) => (ctx) => updateDataOn(ctx, { error: () => ctx.dispatch(message) }),
432
- OnPlay: ({ message }) => (ctx) => updateDataOn(ctx, { play: () => ctx.dispatch(message) }),
433
- OnPause: ({ message }) => (ctx) => updateDataOn(ctx, { pause: () => ctx.dispatch(message) }),
434
- OnEnded: ({ message }) => (ctx) => updateDataOn(ctx, { ended: () => ctx.dispatch(message) }),
435
- OnTimeUpdate: ({ message }) => (ctx) => updateDataOn(ctx, { timeupdate: () => ctx.dispatch(message) }),
436
- OnVolumeChange: ({ message }) => (ctx) => updateDataOn(ctx, { volumechange: () => ctx.dispatch(message) }),
437
- OnSelect: ({ message }) => (ctx) => updateDataOn(ctx, { select: () => ctx.dispatch(message) }),
438
- Value: ({ value }) => (ctx) => updatePropsWithPostpatch(ctx, 'value', value),
439
- Checked: ({ value }) => (ctx) => updatePropsWithPostpatch(ctx, 'checked', value),
440
- Selected: ({ value }) => (ctx) => updatePropsWithPostpatch(ctx, 'selected', value),
441
- Open: ({ value }) => (ctx) => updatePropsWithPostpatch(ctx, 'open', value),
442
- Placeholder: ({ value }) => (ctx) => updateDataProps(ctx, { placeholder: value }),
443
- Name: ({ value }) => (ctx) => updateDataProps(ctx, { name: value }),
444
- Disabled: ({ value }) => (ctx) => updateDataProps(ctx, { disabled: value }),
445
- Readonly: ({ value }) => (ctx) => updateDataProps(ctx, { readOnly: value }),
446
- Required: ({ value }) => (ctx) => updateDataProps(ctx, { required: value }),
447
- Autofocus: ({ value }) => (ctx) => updateDataProps(ctx, { autofocus: value }),
448
- Spellcheck: ({ value }) => (ctx) => updateDataAttrs(ctx, { spellcheck: value.toString() }),
449
- Autocorrect: ({ value }) => (ctx) => updateDataAttrs(ctx, { autocorrect: value }),
450
- Autocapitalize: ({ value }) => (ctx) => updateDataAttrs(ctx, { autocapitalize: value }),
451
- InputMode: ({ value }) => (ctx) => updateDataAttrs(ctx, { inputmode: value }),
452
- EnterKeyHint: ({ value }) => (ctx) => updateDataAttrs(ctx, { enterkeyhint: value }),
453
- Multiple: ({ value }) => (ctx) => updateDataProps(ctx, { multiple: value }),
454
- Type: ({ value }) => (ctx) => updateDataProps(ctx, { type: value }),
455
- Accept: ({ value }) => (ctx) => updateDataProps(ctx, { accept: value }),
456
- Autocomplete: ({ value }) => (ctx) => updateDataProps(ctx, { autocomplete: value }),
457
- Pattern: ({ value }) => (ctx) => updateDataProps(ctx, { pattern: value }),
458
- Maxlength: ({ value }) => (ctx) => updateDataProps(ctx, { maxLength: value }),
459
- Minlength: ({ value }) => (ctx) => updateDataProps(ctx, { minLength: value }),
460
- Size: ({ value }) => (ctx) => updateDataProps(ctx, { size: value }),
461
- Cols: ({ value }) => (ctx) => updateDataProps(ctx, { cols: value }),
462
- Rows: ({ value }) => (ctx) => updateDataProps(ctx, { rows: value }),
463
- Max: ({ value }) => (ctx) => updateDataProps(ctx, { max: value }),
464
- Min: ({ value }) => (ctx) => updateDataProps(ctx, { min: value }),
465
- Step: ({ value }) => (ctx) => updateDataProps(ctx, { step: value }),
466
- For: ({ value }) => (ctx) => updateDataProps(ctx, { htmlFor: value }),
467
- Href: ({ value }) => (ctx) => updateDataProps(ctx, { href: value }),
468
- Src: ({ value }) => (ctx) => updateDataProps(ctx, { src: value }),
469
- Alt: ({ value }) => (ctx) => updateDataProps(ctx, { alt: value }),
470
- Target: ({ value }) => (ctx) => updateDataProps(ctx, { target: value }),
471
- Rel: ({ value }) => (ctx) => updateDataProps(ctx, { rel: value }),
472
- Download: ({ value }) => (ctx) => updateDataProps(ctx, { download: value }),
473
- Action: ({ value }) => (ctx) => updateDataProps(ctx, { action: value }),
474
- Method: ({ value }) => (ctx) => updateDataProps(ctx, { method: value }),
475
- Enctype: ({ value }) => (ctx) => updateDataProps(ctx, { enctype: value }),
476
- Novalidate: ({ value }) => (ctx) => updateDataProps(ctx, { noValidate: value }),
477
- Formaction: ({ value }) => (ctx) => updateDataProps(ctx, { formAction: value }),
478
- Formmethod: ({ value }) => (ctx) => updateDataProps(ctx, { formMethod: value }),
479
- Formnovalidate: ({ value }) => (ctx) => updateDataProps(ctx, { formNoValidate: value }),
480
- Formtarget: ({ value }) => (ctx) => updateDataProps(ctx, { formTarget: value }),
481
- Formenctype: ({ value }) => (ctx) => updateDataProps(ctx, { formEnctype: value }),
482
- Colspan: ({ value }) => (ctx) => updateDataProps(ctx, { colSpan: value }),
483
- Rowspan: ({ value }) => (ctx) => updateDataProps(ctx, { rowSpan: value }),
484
- Scope: ({ value }) => (ctx) => updateDataAttrs(ctx, { scope: value }),
485
- Headers: ({ value }) => (ctx) => updateDataAttrs(ctx, { headers: value }),
486
- Span: ({ value }) => (ctx) => updateDataProps(ctx, { span: value }),
487
- Start: ({ value }) => (ctx) => updateDataProps(ctx, { start: value }),
488
- Reversed: ({ value }) => (ctx) => updateDataProps(ctx, { reversed: value }),
489
- CiteAttr: ({ value }) => (ctx) => updateDataProps(ctx, { cite: value }),
490
- Datetime: ({ value }) => (ctx) => updateDataProps(ctx, { dateTime: value }),
491
- Wrap: ({ value }) => (ctx) => updateDataProps(ctx, { wrap: value }),
492
- List: ({ value }) => (ctx) => updateDataAttrs(ctx, { list: value }),
493
- FormAttr: ({ value }) => (ctx) => updateDataAttrs(ctx, { form: value }),
494
- LabelAttr: ({ value }) => (ctx) => updateDataProps(ctx, { label: value }),
495
- ContentAttr: ({ value }) => (ctx) => updateDataAttrs(ctx, { content: value }),
496
- Charset: ({ value }) => (ctx) => updateDataAttrs(ctx, { charset: value }),
497
- HttpEquiv: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'http-equiv': value }),
498
- Srcset: ({ value }) => (ctx) => updateDataAttrs(ctx, { srcset: value }),
499
- Sizes: ({ value }) => (ctx) => updateDataAttrs(ctx, { sizes: value }),
500
- Loading: ({ value }) => (ctx) => updateDataAttrs(ctx, { loading: value }),
501
- Decoding: ({ value }) => (ctx) => updateDataAttrs(ctx, { decoding: value }),
502
- Fetchpriority: ({ value }) => (ctx) => updateDataAttrs(ctx, { fetchpriority: value }),
503
- Crossorigin: ({ value }) => (ctx) => updateDataAttrs(ctx, { crossorigin: value }),
504
- Referrerpolicy: ({ value }) => (ctx) => updateDataAttrs(ctx, { referrerpolicy: value }),
505
- Integrity: ({ value }) => (ctx) => updateDataAttrs(ctx, { integrity: value }),
506
- Hreflang: ({ value }) => (ctx) => updateDataAttrs(ctx, { hreflang: value }),
507
- Ping: ({ value }) => (ctx) => updateDataAttrs(ctx, { ping: value }),
508
- Sandbox: ({ value }) => (ctx) => updateDataAttrs(ctx, { sandbox: value }),
509
- Allow: ({ value }) => (ctx) => updateDataAttrs(ctx, { allow: value }),
510
- Srcdoc: ({ value }) => (ctx) => updateDataAttrs(ctx, { srcdoc: value }),
511
- Autoplay: ({ value }) => (ctx) => updateDataProps(ctx, { autoplay: value }),
512
- Controls: ({ value }) => (ctx) => updateDataProps(ctx, { controls: value }),
513
- Loop: ({ value }) => (ctx) => updateDataProps(ctx, { loop: value }),
514
- Muted: ({ value }) => (ctx) => updatePropsWithPostpatch(ctx, 'muted', value),
515
- Poster: ({ value }) => (ctx) => updateDataProps(ctx, { poster: value }),
516
- Preload: ({ value }) => (ctx) => updateDataProps(ctx, { preload: value }),
517
- Playsinline: ({ value }) => (ctx) => updateDataProps(ctx, { playsInline: value }),
518
- High: ({ value }) => (ctx) => updateDataProps(ctx, { high: value }),
519
- Low: ({ value }) => (ctx) => updateDataProps(ctx, { low: value }),
520
- Optimum: ({ value }) => (ctx) => updateDataProps(ctx, { optimum: value }),
521
- Usemap: ({ value }) => (ctx) => updateDataAttrs(ctx, { usemap: value }),
522
- Ismap: ({ value }) => (ctx) => updateDataProps(ctx, { isMap: value }),
523
- Role: ({ value }) => (ctx) => updateDataAttrs(ctx, { role: value }),
524
- AriaLabel: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-label': value }),
525
- AriaLabelledBy: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-labelledby': value }),
526
- AriaDescribedBy: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-describedby': value }),
527
- AriaHidden: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-hidden': value.toString() }),
528
- AriaExpanded: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-expanded': value.toString() }),
529
- AriaSelected: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-selected': value.toString() }),
530
- AriaChecked: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-checked': value.toString() }),
531
- AriaDisabled: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-disabled': value.toString() }),
532
- AriaRequired: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-required': value.toString() }),
533
- AriaInvalid: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-invalid': value.toString() }),
534
- AriaLive: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-live': value }),
535
- AriaControls: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-controls': value }),
536
- AriaCurrent: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-current': value }),
537
- AriaOrientation: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-orientation': value }),
538
- AriaPressed: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-pressed': value }),
539
- AriaHasPopup: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-haspopup': value }),
540
- AriaActiveDescendant: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-activedescendant': value }),
541
- AriaSort: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-sort': value }),
542
- AriaMultiSelectable: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-multiselectable': value.toString() }),
543
- AriaModal: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-modal': value.toString() }),
544
- AriaBusy: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-busy': value.toString() }),
545
- AriaErrorMessage: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-errormessage': value }),
546
- AriaRoleDescription: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-roledescription': value }),
547
- AriaAtomic: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-atomic': value.toString() }),
548
- AriaAutocomplete: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-autocomplete': value }),
549
- AriaColcount: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-colcount': value.toString() }),
550
- AriaColindex: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-colindex': value.toString() }),
551
- AriaColspan: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-colspan': value.toString() }),
552
- AriaDescription: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-description': value }),
553
- AriaDetails: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-details': value }),
554
- AriaFlowto: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-flowto': value }),
555
- AriaKeyshortcuts: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-keyshortcuts': value }),
556
- AriaLevel: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-level': value.toString() }),
557
- AriaOwns: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-owns': value }),
558
- AriaPlaceholder: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-placeholder': value }),
559
- AriaPosinset: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-posinset': value.toString() }),
560
- AriaReadonly: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-readonly': value.toString() }),
561
- AriaRelevant: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-relevant': value }),
562
- AriaRowcount: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-rowcount': value.toString() }),
563
- AriaRowindex: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-rowindex': value.toString() }),
564
- AriaRowspan: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-rowspan': value.toString() }),
565
- AriaSetsize: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-setsize': value.toString() }),
566
- AriaValuemax: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-valuemax': value.toString() }),
567
- AriaValuemin: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-valuemin': value.toString() }),
568
- AriaValuenow: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-valuenow': value.toString() }),
569
- AriaValuetext: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'aria-valuetext': value }),
570
- Attribute: ({ key, value }) => (ctx) => updateDataAttrs(ctx, { [key]: value }),
571
- DataAttribute: ({ key, value }) => (ctx) => updateDataAttrs(ctx, { [`data-${key}`]: value }),
572
- Style: ({ value }) => (ctx) => setData(ctx, 'style', value),
573
- InnerHTML: ({ value }) => (ctx) => updateDataProps(ctx, { innerHTML: value }),
574
- ViewBox: ({ value }) => (ctx) => updateDataAttrs(ctx, { viewBox: value }),
575
- Xmlns: ({ value }) => (ctx) => updateDataAttrs(ctx, { xmlns: value }),
576
- Fill: ({ value }) => (ctx) => updateDataAttrs(ctx, { fill: value }),
577
- FillRule: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'fill-rule': value }),
578
- ClipRule: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'clip-rule': value }),
579
- Stroke: ({ value }) => (ctx) => updateDataAttrs(ctx, { stroke: value }),
580
- StrokeWidth: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-width': value }),
581
- StrokeLinecap: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-linecap': value }),
582
- StrokeLinejoin: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-linejoin': value }),
583
- D: ({ value }) => (ctx) => updateDataAttrs(ctx, { d: value }),
584
- Cx: ({ value }) => (ctx) => updateDataAttrs(ctx, { cx: value }),
585
- Cy: ({ value }) => (ctx) => updateDataAttrs(ctx, { cy: value }),
586
- R: ({ value }) => (ctx) => updateDataAttrs(ctx, { r: value }),
587
- X: ({ value }) => (ctx) => updateDataAttrs(ctx, { x: value }),
588
- Y: ({ value }) => (ctx) => updateDataAttrs(ctx, { y: value }),
589
- Width: ({ value }) => (ctx) => updateDataAttrs(ctx, { width: value }),
590
- Height: ({ value }) => (ctx) => updateDataAttrs(ctx, { height: value }),
591
- X1: ({ value }) => (ctx) => updateDataAttrs(ctx, { x1: value }),
592
- Y1: ({ value }) => (ctx) => updateDataAttrs(ctx, { y1: value }),
593
- X2: ({ value }) => (ctx) => updateDataAttrs(ctx, { x2: value }),
594
- Y2: ({ value }) => (ctx) => updateDataAttrs(ctx, { y2: value }),
595
- Points: ({ value }) => (ctx) => updateDataAttrs(ctx, { points: value }),
596
- Transform: ({ value }) => (ctx) => updateDataAttrs(ctx, { transform: value }),
597
- Opacity: ({ value }) => (ctx) => updateDataAttrs(ctx, { opacity: value }),
598
- StrokeDasharray: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-dasharray': value }),
599
- StrokeDashoffset: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-dashoffset': value }),
600
- Dx: ({ value }) => (ctx) => updateDataAttrs(ctx, { dx: value }),
601
- Dy: ({ value }) => (ctx) => updateDataAttrs(ctx, { dy: value }),
602
- Rotate: ({ value }) => (ctx) => updateDataAttrs(ctx, { rotate: value }),
603
- TextAnchor: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'text-anchor': value }),
604
- DominantBaseline: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'dominant-baseline': value }),
605
- AlignmentBaseline: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'alignment-baseline': value }),
606
- BaselineShift: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'baseline-shift': value }),
607
- TextLength: ({ value }) => (ctx) => updateDataAttrs(ctx, { textLength: value }),
608
- LengthAdjust: ({ value }) => (ctx) => updateDataAttrs(ctx, { lengthAdjust: value }),
609
- FontFamily: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'font-family': value }),
610
- FontSize: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'font-size': value }),
611
- FontWeight: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'font-weight': value }),
612
- FontStyle: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'font-style': value }),
613
- LetterSpacing: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'letter-spacing': value }),
614
- WordSpacing: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'word-spacing': value }),
615
- TextDecoration: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'text-decoration': value }),
616
- WritingMode: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'writing-mode': value }),
617
- Rx: ({ value }) => (ctx) => updateDataAttrs(ctx, { rx: value }),
618
- Ry: ({ value }) => (ctx) => updateDataAttrs(ctx, { ry: value }),
619
- PathLength: ({ value }) => (ctx) => updateDataAttrs(ctx, { pathLength: value }),
620
- FillOpacity: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'fill-opacity': value }),
621
- StrokeOpacity: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-opacity': value }),
622
- StrokeMiterlimit: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stroke-miterlimit': value }),
623
- PaintOrder: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'paint-order': value }),
624
- VectorEffect: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'vector-effect': value }),
625
- Color: ({ value }) => (ctx) => updateDataAttrs(ctx, { color: value }),
626
- Visibility: ({ value }) => (ctx) => updateDataAttrs(ctx, { visibility: value }),
627
- Display: ({ value }) => (ctx) => updateDataAttrs(ctx, { display: value }),
628
- Overflow: ({ value }) => (ctx) => updateDataAttrs(ctx, { overflow: value }),
629
- PointerEvents: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'pointer-events': value }),
630
- Cursor: ({ value }) => (ctx) => updateDataAttrs(ctx, { cursor: value }),
631
- ShapeRendering: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'shape-rendering': value }),
632
- TextRendering: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'text-rendering': value }),
633
- ImageRendering: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'image-rendering': value }),
634
- ClipPath: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'clip-path': value }),
635
- Mask: ({ value }) => (ctx) => updateDataAttrs(ctx, { mask: value }),
636
- Filter: ({ value }) => (ctx) => updateDataAttrs(ctx, { filter: value }),
637
- ClipPathUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { clipPathUnits: value }),
638
- MaskUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { maskUnits: value }),
639
- MaskContentUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { maskContentUnits: value }),
640
- FilterUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { filterUnits: value }),
641
- PrimitiveUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { primitiveUnits: value }),
642
- Offset: ({ value }) => (ctx) => updateDataAttrs(ctx, { offset: value }),
643
- StopColor: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stop-color': value }),
644
- StopOpacity: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'stop-opacity': value }),
645
- GradientUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { gradientUnits: value }),
646
- GradientTransform: ({ value }) => (ctx) => updateDataAttrs(ctx, { gradientTransform: value }),
647
- SpreadMethod: ({ value }) => (ctx) => updateDataAttrs(ctx, { spreadMethod: value }),
648
- Fx: ({ value }) => (ctx) => updateDataAttrs(ctx, { fx: value }),
649
- Fy: ({ value }) => (ctx) => updateDataAttrs(ctx, { fy: value }),
650
- Fr: ({ value }) => (ctx) => updateDataAttrs(ctx, { fr: value }),
651
- PatternUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { patternUnits: value }),
652
- PatternContentUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { patternContentUnits: value }),
653
- PatternTransform: ({ value }) => (ctx) => updateDataAttrs(ctx, { patternTransform: value }),
654
- MarkerStart: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'marker-start': value }),
655
- MarkerMid: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'marker-mid': value }),
656
- MarkerEnd: ({ value }) => (ctx) => updateDataAttrs(ctx, { 'marker-end': value }),
657
- MarkerWidth: ({ value }) => (ctx) => updateDataAttrs(ctx, { markerWidth: value }),
658
- MarkerHeight: ({ value }) => (ctx) => updateDataAttrs(ctx, { markerHeight: value }),
659
- MarkerUnits: ({ value }) => (ctx) => updateDataAttrs(ctx, { markerUnits: value }),
660
- RefX: ({ value }) => (ctx) => updateDataAttrs(ctx, { refX: value }),
661
- RefY: ({ value }) => (ctx) => updateDataAttrs(ctx, { refY: value }),
662
- Orient: ({ value }) => (ctx) => updateDataAttrs(ctx, { orient: value }),
663
- PreserveAspectRatio: ({ value }) => (ctx) => updateDataAttrs(ctx, { preserveAspectRatio: value }),
664
- Prop: ({ key, value }) => (ctx) => updateDataProps(ctx, { [key]: value }),
665
- OnCustomEvent: ({ name, f }) => (ctx) => updateDataOn(ctx, {
466
+ OnTouchStart: ({ message }, ctx) => addDataOn(ctx, 'touchstart', () => ctx.dispatch(message)),
467
+ OnTouchEnd: ({ message }, ctx) => addDataOn(ctx, 'touchend', () => ctx.dispatch(message)),
468
+ OnTouchMove: ({ message }, ctx) => addDataOn(ctx, 'touchmove', () => ctx.dispatch(message)),
469
+ OnTouchCancel: ({ message }, ctx) => addDataOn(ctx, 'touchcancel', () => ctx.dispatch(message)),
470
+ OnAnimationStart: ({ message }, ctx) => addDataOn(ctx, 'animationstart', () => ctx.dispatch(message)),
471
+ OnAnimationEnd: ({ message }, ctx) => addDataOn(ctx, 'animationend', () => ctx.dispatch(message)),
472
+ OnAnimationIteration: ({ message }, ctx) => addDataOn(ctx, 'animationiteration', () => ctx.dispatch(message)),
473
+ OnTransitionEnd: ({ message }, ctx) => addDataOn(ctx, 'transitionend', () => ctx.dispatch(message)),
474
+ OnLoad: ({ message }, ctx) => addDataOn(ctx, 'load', () => ctx.dispatch(message)),
475
+ OnError: ({ message }, ctx) => addDataOn(ctx, 'error', () => ctx.dispatch(message)),
476
+ OnPlay: ({ message }, ctx) => addDataOn(ctx, 'play', () => ctx.dispatch(message)),
477
+ OnPause: ({ message }, ctx) => addDataOn(ctx, 'pause', () => ctx.dispatch(message)),
478
+ OnEnded: ({ message }, ctx) => addDataOn(ctx, 'ended', () => ctx.dispatch(message)),
479
+ OnTimeUpdate: ({ message }, ctx) => addDataOn(ctx, 'timeupdate', () => ctx.dispatch(message)),
480
+ OnVolumeChange: ({ message }, ctx) => addDataOn(ctx, 'volumechange', () => ctx.dispatch(message)),
481
+ OnSelect: ({ message }, ctx) => addDataOn(ctx, 'select', () => ctx.dispatch(message)),
482
+ Value: ({ value }, ctx) => updatePropsWithPostpatch(ctx, 'value', value),
483
+ Checked: ({ value }, ctx) => updatePropsWithPostpatch(ctx, 'checked', value),
484
+ Selected: ({ value }, ctx) => updatePropsWithPostpatch(ctx, 'selected', value),
485
+ Open: ({ value }, ctx) => updatePropsWithPostpatch(ctx, 'open', value),
486
+ Placeholder: ({ value }, ctx) => setDataProp(ctx, 'placeholder', value),
487
+ Name: ({ value }, ctx) => setDataProp(ctx, 'name', value),
488
+ Disabled: ({ value }, ctx) => setDataProp(ctx, 'disabled', value),
489
+ Readonly: ({ value }, ctx) => setDataProp(ctx, 'readOnly', value),
490
+ Required: ({ value }, ctx) => setDataProp(ctx, 'required', value),
491
+ Autofocus: ({ value }, ctx) => setDataProp(ctx, 'autofocus', value),
492
+ Spellcheck: ({ value }, ctx) => setDataAttr(ctx, 'spellcheck', value.toString()),
493
+ Autocorrect: ({ value }, ctx) => setDataAttr(ctx, 'autocorrect', value),
494
+ Autocapitalize: ({ value }, ctx) => setDataAttr(ctx, 'autocapitalize', value),
495
+ InputMode: ({ value }, ctx) => setDataAttr(ctx, 'inputmode', value),
496
+ EnterKeyHint: ({ value }, ctx) => setDataAttr(ctx, 'enterkeyhint', value),
497
+ Multiple: ({ value }, ctx) => setDataProp(ctx, 'multiple', value),
498
+ Type: ({ value }, ctx) => setDataProp(ctx, 'type', value),
499
+ Accept: ({ value }, ctx) => setDataProp(ctx, 'accept', value),
500
+ Autocomplete: ({ value }, ctx) => setDataProp(ctx, 'autocomplete', value),
501
+ Pattern: ({ value }, ctx) => setDataProp(ctx, 'pattern', value),
502
+ Maxlength: ({ value }, ctx) => setDataProp(ctx, 'maxLength', value),
503
+ Minlength: ({ value }, ctx) => setDataProp(ctx, 'minLength', value),
504
+ Size: ({ value }, ctx) => setDataProp(ctx, 'size', value),
505
+ Cols: ({ value }, ctx) => setDataProp(ctx, 'cols', value),
506
+ Rows: ({ value }, ctx) => setDataProp(ctx, 'rows', value),
507
+ Max: ({ value }, ctx) => setDataProp(ctx, 'max', value),
508
+ Min: ({ value }, ctx) => setDataProp(ctx, 'min', value),
509
+ Step: ({ value }, ctx) => setDataProp(ctx, 'step', value),
510
+ For: ({ value }, ctx) => setDataProp(ctx, 'htmlFor', value),
511
+ Href: ({ value }, ctx) => setDataProp(ctx, 'href', value),
512
+ Src: ({ value }, ctx) => setDataProp(ctx, 'src', value),
513
+ Alt: ({ value }, ctx) => setDataProp(ctx, 'alt', value),
514
+ Target: ({ value }, ctx) => setDataProp(ctx, 'target', value),
515
+ Rel: ({ value }, ctx) => setDataProp(ctx, 'rel', value),
516
+ Download: ({ value }, ctx) => setDataProp(ctx, 'download', value),
517
+ Action: ({ value }, ctx) => setDataProp(ctx, 'action', value),
518
+ Method: ({ value }, ctx) => setDataProp(ctx, 'method', value),
519
+ Enctype: ({ value }, ctx) => setDataProp(ctx, 'enctype', value),
520
+ Novalidate: ({ value }, ctx) => setDataProp(ctx, 'noValidate', value),
521
+ Formaction: ({ value }, ctx) => setDataProp(ctx, 'formAction', value),
522
+ Formmethod: ({ value }, ctx) => setDataProp(ctx, 'formMethod', value),
523
+ Formnovalidate: ({ value }, ctx) => setDataProp(ctx, 'formNoValidate', value),
524
+ Formtarget: ({ value }, ctx) => setDataProp(ctx, 'formTarget', value),
525
+ Formenctype: ({ value }, ctx) => setDataProp(ctx, 'formEnctype', value),
526
+ Colspan: ({ value }, ctx) => setDataProp(ctx, 'colSpan', value),
527
+ Rowspan: ({ value }, ctx) => setDataProp(ctx, 'rowSpan', value),
528
+ Scope: ({ value }, ctx) => setDataAttr(ctx, 'scope', value),
529
+ Headers: ({ value }, ctx) => setDataAttr(ctx, 'headers', value),
530
+ Span: ({ value }, ctx) => setDataProp(ctx, 'span', value),
531
+ Start: ({ value }, ctx) => setDataProp(ctx, 'start', value),
532
+ Reversed: ({ value }, ctx) => setDataProp(ctx, 'reversed', value),
533
+ CiteAttr: ({ value }, ctx) => setDataProp(ctx, 'cite', value),
534
+ Datetime: ({ value }, ctx) => setDataProp(ctx, 'dateTime', value),
535
+ Wrap: ({ value }, ctx) => setDataProp(ctx, 'wrap', value),
536
+ List: ({ value }, ctx) => setDataAttr(ctx, 'list', value),
537
+ FormAttr: ({ value }, ctx) => setDataAttr(ctx, 'form', value),
538
+ LabelAttr: ({ value }, ctx) => setDataProp(ctx, 'label', value),
539
+ ContentAttr: ({ value }, ctx) => setDataAttr(ctx, 'content', value),
540
+ Charset: ({ value }, ctx) => setDataAttr(ctx, 'charset', value),
541
+ HttpEquiv: ({ value }, ctx) => setDataAttr(ctx, 'http-equiv', value),
542
+ Srcset: ({ value }, ctx) => setDataAttr(ctx, 'srcset', value),
543
+ Sizes: ({ value }, ctx) => setDataAttr(ctx, 'sizes', value),
544
+ Loading: ({ value }, ctx) => setDataAttr(ctx, 'loading', value),
545
+ Decoding: ({ value }, ctx) => setDataAttr(ctx, 'decoding', value),
546
+ Fetchpriority: ({ value }, ctx) => setDataAttr(ctx, 'fetchpriority', value),
547
+ Crossorigin: ({ value }, ctx) => setDataAttr(ctx, 'crossorigin', value),
548
+ Referrerpolicy: ({ value }, ctx) => setDataAttr(ctx, 'referrerpolicy', value),
549
+ Integrity: ({ value }, ctx) => setDataAttr(ctx, 'integrity', value),
550
+ Hreflang: ({ value }, ctx) => setDataAttr(ctx, 'hreflang', value),
551
+ Ping: ({ value }, ctx) => setDataAttr(ctx, 'ping', value),
552
+ Sandbox: ({ value }, ctx) => setDataAttr(ctx, 'sandbox', value),
553
+ Allow: ({ value }, ctx) => setDataAttr(ctx, 'allow', value),
554
+ Srcdoc: ({ value }, ctx) => setDataAttr(ctx, 'srcdoc', value),
555
+ Autoplay: ({ value }, ctx) => setDataProp(ctx, 'autoplay', value),
556
+ Controls: ({ value }, ctx) => setDataProp(ctx, 'controls', value),
557
+ Loop: ({ value }, ctx) => setDataProp(ctx, 'loop', value),
558
+ Muted: ({ value }, ctx) => updatePropsWithPostpatch(ctx, 'muted', value),
559
+ Poster: ({ value }, ctx) => setDataProp(ctx, 'poster', value),
560
+ Preload: ({ value }, ctx) => setDataProp(ctx, 'preload', value),
561
+ Playsinline: ({ value }, ctx) => setDataProp(ctx, 'playsInline', value),
562
+ High: ({ value }, ctx) => setDataProp(ctx, 'high', value),
563
+ Low: ({ value }, ctx) => setDataProp(ctx, 'low', value),
564
+ Optimum: ({ value }, ctx) => setDataProp(ctx, 'optimum', value),
565
+ Usemap: ({ value }, ctx) => setDataAttr(ctx, 'usemap', value),
566
+ Ismap: ({ value }, ctx) => setDataProp(ctx, 'isMap', value),
567
+ Role: ({ value }, ctx) => setDataAttr(ctx, 'role', value),
568
+ AriaLabel: ({ value }, ctx) => setDataAttr(ctx, 'aria-label', value),
569
+ AriaLabelledBy: ({ value }, ctx) => setDataAttr(ctx, 'aria-labelledby', value),
570
+ AriaDescribedBy: ({ value }, ctx) => setDataAttr(ctx, 'aria-describedby', value),
571
+ AriaHidden: ({ value }, ctx) => setDataAttr(ctx, 'aria-hidden', value.toString()),
572
+ AriaExpanded: ({ value }, ctx) => setDataAttr(ctx, 'aria-expanded', value.toString()),
573
+ AriaSelected: ({ value }, ctx) => setDataAttr(ctx, 'aria-selected', value.toString()),
574
+ AriaChecked: ({ value }, ctx) => setDataAttr(ctx, 'aria-checked', value.toString()),
575
+ AriaDisabled: ({ value }, ctx) => setDataAttr(ctx, 'aria-disabled', value.toString()),
576
+ AriaRequired: ({ value }, ctx) => setDataAttr(ctx, 'aria-required', value.toString()),
577
+ AriaInvalid: ({ value }, ctx) => setDataAttr(ctx, 'aria-invalid', value.toString()),
578
+ AriaLive: ({ value }, ctx) => setDataAttr(ctx, 'aria-live', value),
579
+ AriaControls: ({ value }, ctx) => setDataAttr(ctx, 'aria-controls', value),
580
+ AriaCurrent: ({ value }, ctx) => setDataAttr(ctx, 'aria-current', value),
581
+ AriaOrientation: ({ value }, ctx) => setDataAttr(ctx, 'aria-orientation', value),
582
+ AriaPressed: ({ value }, ctx) => setDataAttr(ctx, 'aria-pressed', value),
583
+ AriaHasPopup: ({ value }, ctx) => setDataAttr(ctx, 'aria-haspopup', value),
584
+ AriaActiveDescendant: ({ value }, ctx) => setDataAttr(ctx, 'aria-activedescendant', value),
585
+ AriaSort: ({ value }, ctx) => setDataAttr(ctx, 'aria-sort', value),
586
+ AriaMultiSelectable: ({ value }, ctx) => setDataAttr(ctx, 'aria-multiselectable', value.toString()),
587
+ AriaModal: ({ value }, ctx) => setDataAttr(ctx, 'aria-modal', value.toString()),
588
+ AriaBusy: ({ value }, ctx) => setDataAttr(ctx, 'aria-busy', value.toString()),
589
+ AriaErrorMessage: ({ value }, ctx) => setDataAttr(ctx, 'aria-errormessage', value),
590
+ AriaRoleDescription: ({ value }, ctx) => setDataAttr(ctx, 'aria-roledescription', value),
591
+ AriaAtomic: ({ value }, ctx) => setDataAttr(ctx, 'aria-atomic', value.toString()),
592
+ AriaAutocomplete: ({ value }, ctx) => setDataAttr(ctx, 'aria-autocomplete', value),
593
+ AriaColcount: ({ value }, ctx) => setDataAttr(ctx, 'aria-colcount', value.toString()),
594
+ AriaColindex: ({ value }, ctx) => setDataAttr(ctx, 'aria-colindex', value.toString()),
595
+ AriaColspan: ({ value }, ctx) => setDataAttr(ctx, 'aria-colspan', value.toString()),
596
+ AriaDescription: ({ value }, ctx) => setDataAttr(ctx, 'aria-description', value),
597
+ AriaDetails: ({ value }, ctx) => setDataAttr(ctx, 'aria-details', value),
598
+ AriaFlowto: ({ value }, ctx) => setDataAttr(ctx, 'aria-flowto', value),
599
+ AriaKeyshortcuts: ({ value }, ctx) => setDataAttr(ctx, 'aria-keyshortcuts', value),
600
+ AriaLevel: ({ value }, ctx) => setDataAttr(ctx, 'aria-level', value.toString()),
601
+ AriaOwns: ({ value }, ctx) => setDataAttr(ctx, 'aria-owns', value),
602
+ AriaPlaceholder: ({ value }, ctx) => setDataAttr(ctx, 'aria-placeholder', value),
603
+ AriaPosinset: ({ value }, ctx) => setDataAttr(ctx, 'aria-posinset', value.toString()),
604
+ AriaReadonly: ({ value }, ctx) => setDataAttr(ctx, 'aria-readonly', value.toString()),
605
+ AriaRelevant: ({ value }, ctx) => setDataAttr(ctx, 'aria-relevant', value),
606
+ AriaRowcount: ({ value }, ctx) => setDataAttr(ctx, 'aria-rowcount', value.toString()),
607
+ AriaRowindex: ({ value }, ctx) => setDataAttr(ctx, 'aria-rowindex', value.toString()),
608
+ AriaRowspan: ({ value }, ctx) => setDataAttr(ctx, 'aria-rowspan', value.toString()),
609
+ AriaSetsize: ({ value }, ctx) => setDataAttr(ctx, 'aria-setsize', value.toString()),
610
+ AriaValuemax: ({ value }, ctx) => setDataAttr(ctx, 'aria-valuemax', value.toString()),
611
+ AriaValuemin: ({ value }, ctx) => setDataAttr(ctx, 'aria-valuemin', value.toString()),
612
+ AriaValuenow: ({ value }, ctx) => setDataAttr(ctx, 'aria-valuenow', value.toString()),
613
+ AriaValuetext: ({ value }, ctx) => setDataAttr(ctx, 'aria-valuetext', value),
614
+ Attribute: ({ key, value }, ctx) => setDataAttr(ctx, key, value),
615
+ DataAttribute: ({ key, value }, ctx) => setDataAttr(ctx, `data-${key}`, value),
616
+ Style: ({ value }, ctx) => setModuleData(ctx, 'style', value, VNodeDataMask.Style),
617
+ InnerHTML: ({ value }, ctx) => setDataProp(ctx, 'innerHTML', value),
618
+ ViewBox: ({ value }, ctx) => setDataAttr(ctx, 'viewBox', value),
619
+ Xmlns: ({ value }, ctx) => setDataAttr(ctx, 'xmlns', value),
620
+ Fill: ({ value }, ctx) => setDataAttr(ctx, 'fill', value),
621
+ FillRule: ({ value }, ctx) => setDataAttr(ctx, 'fill-rule', value),
622
+ ClipRule: ({ value }, ctx) => setDataAttr(ctx, 'clip-rule', value),
623
+ Stroke: ({ value }, ctx) => setDataAttr(ctx, 'stroke', value),
624
+ StrokeWidth: ({ value }, ctx) => setDataAttr(ctx, 'stroke-width', value),
625
+ StrokeLinecap: ({ value }, ctx) => setDataAttr(ctx, 'stroke-linecap', value),
626
+ StrokeLinejoin: ({ value }, ctx) => setDataAttr(ctx, 'stroke-linejoin', value),
627
+ D: ({ value }, ctx) => setDataAttr(ctx, 'd', value),
628
+ Cx: ({ value }, ctx) => setDataAttr(ctx, 'cx', value),
629
+ Cy: ({ value }, ctx) => setDataAttr(ctx, 'cy', value),
630
+ R: ({ value }, ctx) => setDataAttr(ctx, 'r', value),
631
+ X: ({ value }, ctx) => setDataAttr(ctx, 'x', value),
632
+ Y: ({ value }, ctx) => setDataAttr(ctx, 'y', value),
633
+ Width: ({ value }, ctx) => setDataAttr(ctx, 'width', value),
634
+ Height: ({ value }, ctx) => setDataAttr(ctx, 'height', value),
635
+ X1: ({ value }, ctx) => setDataAttr(ctx, 'x1', value),
636
+ Y1: ({ value }, ctx) => setDataAttr(ctx, 'y1', value),
637
+ X2: ({ value }, ctx) => setDataAttr(ctx, 'x2', value),
638
+ Y2: ({ value }, ctx) => setDataAttr(ctx, 'y2', value),
639
+ Points: ({ value }, ctx) => setDataAttr(ctx, 'points', value),
640
+ Transform: ({ value }, ctx) => setDataAttr(ctx, 'transform', value),
641
+ Opacity: ({ value }, ctx) => setDataAttr(ctx, 'opacity', value),
642
+ StrokeDasharray: ({ value }, ctx) => setDataAttr(ctx, 'stroke-dasharray', value),
643
+ StrokeDashoffset: ({ value }, ctx) => setDataAttr(ctx, 'stroke-dashoffset', value),
644
+ Dx: ({ value }, ctx) => setDataAttr(ctx, 'dx', value),
645
+ Dy: ({ value }, ctx) => setDataAttr(ctx, 'dy', value),
646
+ Rotate: ({ value }, ctx) => setDataAttr(ctx, 'rotate', value),
647
+ TextAnchor: ({ value }, ctx) => setDataAttr(ctx, 'text-anchor', value),
648
+ DominantBaseline: ({ value }, ctx) => setDataAttr(ctx, 'dominant-baseline', value),
649
+ AlignmentBaseline: ({ value }, ctx) => setDataAttr(ctx, 'alignment-baseline', value),
650
+ BaselineShift: ({ value }, ctx) => setDataAttr(ctx, 'baseline-shift', value),
651
+ TextLength: ({ value }, ctx) => setDataAttr(ctx, 'textLength', value),
652
+ LengthAdjust: ({ value }, ctx) => setDataAttr(ctx, 'lengthAdjust', value),
653
+ FontFamily: ({ value }, ctx) => setDataAttr(ctx, 'font-family', value),
654
+ FontSize: ({ value }, ctx) => setDataAttr(ctx, 'font-size', value),
655
+ FontWeight: ({ value }, ctx) => setDataAttr(ctx, 'font-weight', value),
656
+ FontStyle: ({ value }, ctx) => setDataAttr(ctx, 'font-style', value),
657
+ LetterSpacing: ({ value }, ctx) => setDataAttr(ctx, 'letter-spacing', value),
658
+ WordSpacing: ({ value }, ctx) => setDataAttr(ctx, 'word-spacing', value),
659
+ TextDecoration: ({ value }, ctx) => setDataAttr(ctx, 'text-decoration', value),
660
+ WritingMode: ({ value }, ctx) => setDataAttr(ctx, 'writing-mode', value),
661
+ Rx: ({ value }, ctx) => setDataAttr(ctx, 'rx', value),
662
+ Ry: ({ value }, ctx) => setDataAttr(ctx, 'ry', value),
663
+ PathLength: ({ value }, ctx) => setDataAttr(ctx, 'pathLength', value),
664
+ FillOpacity: ({ value }, ctx) => setDataAttr(ctx, 'fill-opacity', value),
665
+ StrokeOpacity: ({ value }, ctx) => setDataAttr(ctx, 'stroke-opacity', value),
666
+ StrokeMiterlimit: ({ value }, ctx) => setDataAttr(ctx, 'stroke-miterlimit', value),
667
+ PaintOrder: ({ value }, ctx) => setDataAttr(ctx, 'paint-order', value),
668
+ VectorEffect: ({ value }, ctx) => setDataAttr(ctx, 'vector-effect', value),
669
+ Color: ({ value }, ctx) => setDataAttr(ctx, 'color', value),
670
+ Visibility: ({ value }, ctx) => setDataAttr(ctx, 'visibility', value),
671
+ Display: ({ value }, ctx) => setDataAttr(ctx, 'display', value),
672
+ Overflow: ({ value }, ctx) => setDataAttr(ctx, 'overflow', value),
673
+ PointerEvents: ({ value }, ctx) => setDataAttr(ctx, 'pointer-events', value),
674
+ Cursor: ({ value }, ctx) => setDataAttr(ctx, 'cursor', value),
675
+ ShapeRendering: ({ value }, ctx) => setDataAttr(ctx, 'shape-rendering', value),
676
+ TextRendering: ({ value }, ctx) => setDataAttr(ctx, 'text-rendering', value),
677
+ ImageRendering: ({ value }, ctx) => setDataAttr(ctx, 'image-rendering', value),
678
+ ClipPath: ({ value }, ctx) => setDataAttr(ctx, 'clip-path', value),
679
+ Mask: ({ value }, ctx) => setDataAttr(ctx, 'mask', value),
680
+ Filter: ({ value }, ctx) => setDataAttr(ctx, 'filter', value),
681
+ ClipPathUnits: ({ value }, ctx) => setDataAttr(ctx, 'clipPathUnits', value),
682
+ MaskUnits: ({ value }, ctx) => setDataAttr(ctx, 'maskUnits', value),
683
+ MaskContentUnits: ({ value }, ctx) => setDataAttr(ctx, 'maskContentUnits', value),
684
+ FilterUnits: ({ value }, ctx) => setDataAttr(ctx, 'filterUnits', value),
685
+ PrimitiveUnits: ({ value }, ctx) => setDataAttr(ctx, 'primitiveUnits', value),
686
+ Offset: ({ value }, ctx) => setDataAttr(ctx, 'offset', value),
687
+ StopColor: ({ value }, ctx) => setDataAttr(ctx, 'stop-color', value),
688
+ StopOpacity: ({ value }, ctx) => setDataAttr(ctx, 'stop-opacity', value),
689
+ GradientUnits: ({ value }, ctx) => setDataAttr(ctx, 'gradientUnits', value),
690
+ GradientTransform: ({ value }, ctx) => setDataAttr(ctx, 'gradientTransform', value),
691
+ SpreadMethod: ({ value }, ctx) => setDataAttr(ctx, 'spreadMethod', value),
692
+ Fx: ({ value }, ctx) => setDataAttr(ctx, 'fx', value),
693
+ Fy: ({ value }, ctx) => setDataAttr(ctx, 'fy', value),
694
+ Fr: ({ value }, ctx) => setDataAttr(ctx, 'fr', value),
695
+ PatternUnits: ({ value }, ctx) => setDataAttr(ctx, 'patternUnits', value),
696
+ PatternContentUnits: ({ value }, ctx) => setDataAttr(ctx, 'patternContentUnits', value),
697
+ PatternTransform: ({ value }, ctx) => setDataAttr(ctx, 'patternTransform', value),
698
+ MarkerStart: ({ value }, ctx) => setDataAttr(ctx, 'marker-start', value),
699
+ MarkerMid: ({ value }, ctx) => setDataAttr(ctx, 'marker-mid', value),
700
+ MarkerEnd: ({ value }, ctx) => setDataAttr(ctx, 'marker-end', value),
701
+ MarkerWidth: ({ value }, ctx) => setDataAttr(ctx, 'markerWidth', value),
702
+ MarkerHeight: ({ value }, ctx) => setDataAttr(ctx, 'markerHeight', value),
703
+ MarkerUnits: ({ value }, ctx) => setDataAttr(ctx, 'markerUnits', value),
704
+ RefX: ({ value }, ctx) => setDataAttr(ctx, 'refX', value),
705
+ RefY: ({ value }, ctx) => setDataAttr(ctx, 'refY', value),
706
+ Orient: ({ value }, ctx) => setDataAttr(ctx, 'orient', value),
707
+ PreserveAspectRatio: ({ value }, ctx) => setDataAttr(ctx, 'preserveAspectRatio', value),
708
+ Prop: ({ key, value }, ctx) => setDataProp(ctx, key, value),
709
+ OnCustomEvent: ({ name, f: toMessage }, ctx) => updateDataOn(ctx, {
666
710
  [name]: (event) => {
667
711
  if (event instanceof CustomEvent) {
668
- ctx.dispatch(f(event));
712
+ ctx.dispatch(toMessage(event));
669
713
  }
670
714
  },
671
715
  }),
672
- OnMount: ({ action }) => (ctx) => {
716
+ OnMount: ({ action }, ctx) => {
673
717
  const capturedContext = ctx.getCapturedContext();
674
718
  const maybeTracker = Context.getOption(capturedContext, MountTracker);
675
719
  const notifyStarted = Option.isSome(maybeTracker)
@@ -714,7 +758,7 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
714
758
  },
715
759
  };
716
760
  },
717
- OnUnmount: ({ message }) => (ctx) => {
761
+ OnUnmount: ({ message }, ctx) => {
718
762
  // NOTE: resolve the boundary wrapping chain eagerly, while the boundary
719
763
  // is still live this render. The destroy hook fires during the patch
720
764
  // that removes the element, after the Submodel's own destroy hook has
@@ -734,130 +778,156 @@ const attributeMatcher = Match.type().pipe(Match.tagsExhaustive({
734
778
  },
735
779
  };
736
780
  },
737
- }));
738
- const buildVNodeData = (attributes) => {
739
- // Capture lazily, and tolerate the absence of a runtime frame. Static
740
- // elements (`h.code([h.Class('x')], ['text'])`) and prose fragments built
741
- // at module top level (`const fragment = inlineCode('foo')` at import
742
- // time) must construct without an active render frame. They never invoke
743
- // the fallback dispatcher because they have no event handlers; event-
744
- // bearing Html constructed outside a render reaches the fallback only at
745
- // event-fire time, which surfaces a clear error rather than failing at
746
- // import time.
747
- let cachedCurrentDispatch;
748
- const getCurrentDispatch = () => {
749
- if (cachedCurrentDispatch === undefined) {
750
- try {
751
- cachedCurrentDispatch = requireDispatch();
752
- }
753
- catch {
754
- cachedCurrentDispatch = () => {
755
- throw new Error('Foldkit: an event-bearing Html attribute fired without an ' +
756
- 'active runtime frame. This typically means an Html element ' +
757
- 'with event handlers (OnClick, OnInput, etc.) was constructed ' +
758
- 'at module top level outside of a view function.');
759
- };
760
- }
761
- }
762
- return cachedCurrentDispatch;
763
- };
764
- let cachedUnmountResolver;
765
- const getCurrentUnmountResolver = () => {
766
- if (cachedUnmountResolver === undefined) {
767
- try {
768
- cachedUnmountResolver = requireUnmountResolver();
769
- }
770
- catch {
771
- cachedUnmountResolver = () => () => {
772
- throw new Error('Foldkit: an OnUnmount attribute fired without an active runtime ' +
773
- 'frame. This typically means an Html element with OnUnmount was ' +
774
- 'constructed at module top level outside of a view function.');
775
- };
776
- }
777
- }
778
- return cachedUnmountResolver;
779
- };
780
- let cachedCapturedContext;
781
- const getCapturedContext = () => {
782
- if (cachedCapturedContext === undefined) {
783
- try {
784
- cachedCapturedContext = requireRuntimeContext();
785
- }
786
- catch {
787
- cachedCapturedContext = Context.empty();
781
+ };
782
+ const applyAttribute = (attribute, ctx) => {
783
+ // NOTE: the mapped record type correlates each handler's attribute
784
+ // parameter with its tag, which TypeScript cannot re-derive at this
785
+ // widened call site.
786
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
787
+ const handler = attributeHandlers[attribute._tag];
788
+ handler(attribute, ctx);
789
+ };
790
+ // NOTE: tolerate the absence of a runtime frame. Static elements
791
+ // (`h.code([h.Class('x')], ['text'])`) and prose fragments built at module
792
+ // top level (`const fragment = inlineCode('foo')` at import time) must
793
+ // construct without an active render frame. They never invoke the fallback
794
+ // dispatcher because they have no event handlers; event-bearing Html
795
+ // constructed outside a render reaches the fallback only at event-fire time,
796
+ // which surfaces a clear error rather than failing at import time. The
797
+ // fallbacks are module-level constants so element construction allocates no
798
+ // per-element closures for them.
799
+ const fallbackDispatch = () => {
800
+ throw new Error('Foldkit: an event-bearing Html attribute fired without an ' +
801
+ 'active runtime frame. This typically means an Html element ' +
802
+ 'with event handlers (OnClick, OnInput, etc.) was constructed ' +
803
+ 'at module top level outside of a view function.');
804
+ };
805
+ const fallbackUnmountResolver = () => () => {
806
+ throw new Error('Foldkit: an OnUnmount attribute fired without an active runtime ' +
807
+ 'frame. This typically means an Html element with OnUnmount was ' +
808
+ 'constructed at module top level outside of a view function.');
809
+ };
810
+ const currentDispatchOrFallback = () => {
811
+ try {
812
+ return requireDispatch();
813
+ }
814
+ catch {
815
+ return fallbackDispatch;
816
+ }
817
+ };
818
+ const currentUnmountResolverOrFallback = () => {
819
+ try {
820
+ return requireUnmountResolver();
821
+ }
822
+ catch {
823
+ return fallbackUnmountResolver;
824
+ }
825
+ };
826
+ const capturedContextOrEmpty = () => {
827
+ try {
828
+ return requireRuntimeContext();
829
+ }
830
+ catch {
831
+ return Context.empty();
832
+ }
833
+ };
834
+ const attachPostpatchHook = (data, postpatchProps) => {
835
+ data.hook = {
836
+ ...data.hook,
837
+ postpatch: (_oldVnode, vnode) => {
838
+ if (vnode.elm) {
839
+ Array.forEach(postpatchProps, ({ propName, value }) => {
840
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
841
+ if (vnode.elm[propName] !== value) {
842
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
843
+ ;
844
+ vnode.elm[propName] = value;
845
+ }
846
+ });
788
847
  }
789
- }
790
- return cachedCapturedContext;
848
+ },
791
849
  };
792
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
793
- const data = {};
794
- const postpatchProps = [];
795
- // Most attributes route through the current frame's dispatch. ChildAttribute
796
- // items carry a different dispatcher (captured by `childAttributes`
797
- // in a Submodel's own boundary), so they need their own BuildContext closed
798
- // over that dispatch. The matcher itself is module-level and shared.
799
- // The main ctx is built lazily. Static-only attribute arrays (Class, Id,
800
- // etc. with no event handlers) skip `requireDispatch` entirely so Html can
801
- // be constructed at module top level.
850
+ };
851
+ const buildVNodeData = (attributes) => {
852
+ const data = { [vnodeDataMaskKey]: 0 };
853
+ if (attributes.length === 0) {
854
+ return data;
855
+ }
856
+ // NOTE: most attributes route through the current frame's dispatch.
857
+ // ChildAttribute items carry a different dispatcher (captured by
858
+ // `childAttributes` in a Submodel's own boundary), so they need their own
859
+ // BuildContext closed over that dispatch. The handler record itself is
860
+ // module-level and shared. The main ctx is built lazily. Static-only
861
+ // attribute arrays (Class, Id, etc. with no event handlers) skip
862
+ // `requireDispatch` entirely so Html can be constructed at module top
863
+ // level. The boundary ctx map is only allocated when a ChildAttribute is
864
+ // actually present.
802
865
  let mainCtx;
803
- const boundaryCtxByDispatch = new Map();
866
+ let boundaryCtxByDispatch;
867
+ let sharedPostpatchProps;
868
+ const getSharedPostpatchProps = () => (sharedPostpatchProps ??= []);
804
869
  for (const item of attributes) {
805
870
  if (isChildAttribute(item)) {
871
+ boundaryCtxByDispatch ??= new Map();
806
872
  let ctx = boundaryCtxByDispatch.get(item.dispatch);
807
873
  if (ctx === undefined) {
808
874
  ctx = {
809
875
  data,
810
- postpatchProps,
876
+ getPostpatchProps: getSharedPostpatchProps,
811
877
  dispatch: item.dispatch,
812
878
  resolveUnmount: item.resolveUnmount,
813
879
  boundaryMappers: item.boundaryMappers,
814
- getCapturedContext,
880
+ getCapturedContext: capturedContextOrEmpty,
815
881
  };
816
882
  boundaryCtxByDispatch.set(item.dispatch, ctx);
817
883
  }
818
884
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
819
- attributeMatcher(item.attribute)(ctx);
885
+ applyAttribute(item.attribute, ctx);
820
886
  }
821
887
  else {
822
888
  if (mainCtx === undefined) {
823
889
  mainCtx = {
824
890
  data,
825
- postpatchProps,
826
- dispatch: getCurrentDispatch(),
827
- resolveUnmount: getCurrentUnmountResolver(),
891
+ getPostpatchProps: getSharedPostpatchProps,
892
+ dispatch: currentDispatchOrFallback(),
893
+ resolveUnmount: currentUnmountResolverOrFallback(),
828
894
  boundaryMappers: requireBoundaryMappers(),
829
- getCapturedContext,
895
+ getCapturedContext: capturedContextOrEmpty,
830
896
  };
831
897
  }
832
898
  /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
833
- attributeMatcher(item)(mainCtx);
899
+ applyAttribute(item, mainCtx);
834
900
  }
835
901
  }
836
- if (Array.isReadonlyArrayNonEmpty(postpatchProps)) {
837
- data.hook = {
838
- ...data.hook,
839
- postpatch: (_oldVnode, vnode) => {
840
- if (vnode.elm) {
841
- Array.forEach(postpatchProps, ({ propName, value }) => {
842
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
843
- if (vnode.elm[propName] !== value) {
844
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
845
- ;
846
- vnode.elm[propName] = value;
847
- }
848
- });
849
- }
850
- },
851
- };
902
+ if (sharedPostpatchProps !== undefined &&
903
+ Array.isReadonlyArrayNonEmpty(sharedPostpatchProps)) {
904
+ attachPostpatchHook(data, sharedPostpatchProps);
852
905
  }
853
906
  return data;
854
907
  };
855
- const processVNodeChildren = (children) => Array.filter(children, Predicate.isNotNull);
856
- const createElement = (tagName, attributes = [], children = []) => h(tagName, buildVNodeData(attributes), Array.fromIterable(processVNodeChildren(children)));
908
+ // NOTE: one fresh mutable array per element in a single pass: `h.empty`
909
+ // children (null) are dropped, and snabbdom's `h` converts primitive
910
+ // children to text vnodes in place, so the caller's array must never be
911
+ // handed over directly.
912
+ const copyChildrenDroppingEmpty = (children) => {
913
+ const next = [];
914
+ for (let index = 0; index < children.length; index++) {
915
+ const child = children[index];
916
+ if (child !== null && child !== undefined) {
917
+ next.push(child);
918
+ }
919
+ }
920
+ return next;
921
+ };
922
+ const createElement = (tagName, attributes = [], children = []) => h(tagName, buildVNodeData(attributes), copyChildrenDroppingEmpty(children));
857
923
  const element = () => (tagName) => (attributes = [], children = []) => createElement(tagName, attributes, children);
858
924
  export const customElement = () => (tagName) => (attributes = [], children = []) => createElement(tagName, attributes, children);
859
925
  const voidElement = () => (tagName) => (attributes = []) => createElement(tagName, attributes, []);
860
- const keyed = () => (tagName) => (key, attributes = [], children = []) => element()(tagName)([...attributes, Key({ value: key })], children);
926
+ const keyed = () => (tagName) => (key, attributes = [], children = []) => {
927
+ const data = buildVNodeData(attributes);
928
+ data.key = key;
929
+ return h(tagName, data, copyChildrenDroppingEmpty(children));
930
+ };
861
931
  const htmlElements = () => {
862
932
  const el = element();
863
933
  const voidEl = voidElement();
@@ -1137,12 +1207,12 @@ const htmlAttributes = () => ({
1137
1207
  OnMouseOver: (message) => OnMouseOver({ message }),
1138
1208
  OnMouseOut: (message) => OnMouseOut({ message }),
1139
1209
  OnMouseMove: (message) => OnMouseMove({ message }),
1140
- OnPointerMove: (f) => OnPointerMove({ f }),
1141
- OnPointerLeave: (f) => OnPointerLeave({ f }),
1142
- OnPointerDown: (f) => OnPointerDown({ f }),
1143
- OnPointerUp: (f) => OnPointerUp({ f }),
1144
- OnKeyDown: (f) => OnKeyDown({ f }),
1145
- OnKeyDownPreventDefault: (f) => OnKeyDownPreventDefault({ f }),
1210
+ OnPointerMove: (toMaybeMessage) => OnPointerMove({ f: toMaybeMessage }),
1211
+ OnPointerLeave: (toMaybeMessage) => OnPointerLeave({ f: toMaybeMessage }),
1212
+ OnPointerDown: (toMaybeMessage) => OnPointerDown({ f: toMaybeMessage }),
1213
+ OnPointerUp: (toMaybeMessage) => OnPointerUp({ f: toMaybeMessage }),
1214
+ OnKeyDown: (toMessage) => OnKeyDown({ f: toMessage }),
1215
+ OnKeyDownPreventDefault: (toMaybeMessage) => OnKeyDownPreventDefault({ f: toMaybeMessage }),
1146
1216
  /**
1147
1217
  * Keydown handler that, for a handled key, synchronously focuses the element
1148
1218
  * matching `focusSelector` and dispatches `message`, both inside the
@@ -1165,18 +1235,18 @@ const htmlAttributes = () => ({
1165
1235
  * )
1166
1236
  * ```
1167
1237
  */
1168
- OnKeyDownFocus: (f) => OnKeyDownFocus({ f }),
1169
- OnKeyUp: (f) => OnKeyUp({ f }),
1170
- OnKeyUpPreventDefault: (f) => OnKeyUpPreventDefault({ f }),
1171
- OnKeyPress: (f) => OnKeyPress({ f }),
1238
+ OnKeyDownFocus: (toMaybeFocusAndMessage) => OnKeyDownFocus({ f: toMaybeFocusAndMessage }),
1239
+ OnKeyUp: (toMessage) => OnKeyUp({ f: toMessage }),
1240
+ OnKeyUpPreventDefault: (toMaybeMessage) => OnKeyUpPreventDefault({ f: toMaybeMessage }),
1241
+ OnKeyPress: (toMessage) => OnKeyPress({ f: toMessage }),
1172
1242
  OnFocus: (message) => OnFocus({ message }),
1173
1243
  OnBlur: (message) => OnBlur({ message }),
1174
- OnInput: (f) => OnInput({ f }),
1175
- OnChange: (f) => OnChange({ f }),
1176
- OnFileChange: (f) => OnFileChange({ f }),
1244
+ OnInput: (toMessage) => OnInput({ f: toMessage }),
1245
+ OnChange: (toMessage) => OnChange({ f: toMessage }),
1246
+ OnFileChange: (toMessage) => OnFileChange({ f: toMessage }),
1177
1247
  OnSubmit: (message) => OnSubmit({ message }),
1178
1248
  OnReset: (message) => OnReset({ message }),
1179
- OnScroll: (f) => OnScroll({ f }),
1249
+ OnScroll: (toMessage) => OnScroll({ f: toMessage }),
1180
1250
  OnWheel: (message) => OnWheel({ message }),
1181
1251
  OnCopy: (message) => OnCopy({ message }),
1182
1252
  OnCut: (message) => OnCut({ message }),
@@ -1198,7 +1268,7 @@ const htmlAttributes = () => ({
1198
1268
  * h.OnPastePreventDefault(text => Option.some(PastedText({ text })))
1199
1269
  * ```
1200
1270
  */
1201
- OnPastePreventDefault: (f) => OnPastePreventDefault({ f }),
1271
+ OnPastePreventDefault: (toMaybeMessage) => OnPastePreventDefault({ f: toMaybeMessage }),
1202
1272
  /**
1203
1273
  * Copy handler that synchronously writes `text` to the clipboard as
1204
1274
  * `text/plain` and calls `preventDefault`, replacing the browser's default
@@ -1227,7 +1297,7 @@ const htmlAttributes = () => ({
1227
1297
  */
1228
1298
  OnCutText: (text, message) => OnCutText({ text, message }),
1229
1299
  OnCancel: (message) => OnCancel({ message }),
1230
- OnToggle: (f) => OnToggle({ f }),
1300
+ OnToggle: (toMessage) => OnToggle({ f: toMessage }),
1231
1301
  OnContextMenu: (message) => OnContextMenu({ message }),
1232
1302
  OnDragStart: (message) => OnDragStart({ message }),
1233
1303
  OnDrag: (message) => OnDrag({ message }),
@@ -1237,7 +1307,7 @@ const htmlAttributes = () => ({
1237
1307
  OnDragOver: (message) => OnDragOver({ message }),
1238
1308
  AllowDrop: () => AllowDrop(),
1239
1309
  OnDrop: (message) => OnDrop({ message }),
1240
- OnDropFiles: (f) => OnDropFiles({ f }),
1310
+ OnDropFiles: (toMessage) => OnDropFiles({ f: toMessage }),
1241
1311
  OnTouchStart: (message) => OnTouchStart({ message }),
1242
1312
  OnTouchEnd: (message) => OnTouchEnd({ message }),
1243
1313
  OnTouchMove: (message) => OnTouchMove({ message }),