kerfjs 0.4.2 → 0.5.1

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.
@@ -1,3 +1,632 @@
1
+ /**
2
+ * JSX intrinsic-element types — kerf's per-tag attribute contracts.
3
+ *
4
+ * Replaces the previous `[elemName: string]: Record<string, unknown>`
5
+ * catch-all that allowed any tag and any prop. Now: known tags get focused
6
+ * attribute interfaces (typos fail to compile); unknown tags require
7
+ * declaration merging to opt in.
8
+ *
9
+ * Coverage is intentionally focused, not exhaustive. The most common ~30
10
+ * HTML elements + the SVG primitives that make up `toElement`'s fragment
11
+ * set are typed in detail. Rare attributes can be added in follow-ups, or
12
+ * extended on a per-project basis via declaration merging into the
13
+ * `kerfjs/jsx-runtime` JSX namespace (KF-100):
14
+ *
15
+ * import type { KerfBaseAttrs, KerfCustomElement } from 'kerfjs/jsx-runtime';
16
+ *
17
+ * declare module 'kerfjs/jsx-runtime' {
18
+ * namespace JSX {
19
+ * interface IntrinsicElements {
20
+ * 'my-element': KerfCustomElement & { foo?: string };
21
+ * }
22
+ * }
23
+ * }
24
+ *
25
+ * `IntrinsicElements` in `jsx-runtime` is an **interface** that extends the
26
+ * one defined here, which is what makes the merge above work — type aliases
27
+ * (the previous shape) couldn't be merged.
28
+ *
29
+ * Every attribute value is `AttrValue` — string / number / boolean / null /
30
+ * undefined / `SafeHtml`. Event-handler props (`onClick` etc.) are
31
+ * deliberately omitted: kerf renders to strings, so inline handlers do
32
+ * nothing. Use `delegate()` / `delegateCapture()` instead.
33
+ */
34
+
35
+ /** Every kerf attribute value resolves to one of these. */
36
+ type AttrValue = string | number | boolean | null | undefined | SafeHtml;
37
+ /** A typed-narrowing helper: `AttrLike<'a'|'b'>` accepts the literals plus the runtime fall-throughs. */
38
+ type AttrLike<T = string> = T | SafeHtml | null | undefined;
39
+ /**
40
+ * `data-*` and `aria-*` index signatures. Applied via `KerfBaseAttrs` so
41
+ * every typed element accepts them without per-element enumeration.
42
+ */
43
+ interface DataAriaAttrs {
44
+ [k: `data-${string}`]: AttrValue;
45
+ [k: `aria-${string}`]: AttrValue;
46
+ }
47
+ /** Attributes valid on essentially every HTML element. */
48
+ interface KerfBaseAttrs extends DataAriaAttrs {
49
+ id?: AttrLike;
50
+ className?: AttrLike;
51
+ style?: AttrLike;
52
+ title?: AttrLike;
53
+ lang?: AttrLike;
54
+ dir?: AttrLike<'ltr' | 'rtl' | 'auto'>;
55
+ hidden?: AttrLike<boolean>;
56
+ draggable?: AttrLike<boolean>;
57
+ contentEditable?: AttrLike<boolean | 'true' | 'false' | 'inherit'>;
58
+ inputMode?: AttrLike<'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search'>;
59
+ spellCheck?: AttrLike<boolean>;
60
+ tabIndex?: AttrLike<number>;
61
+ role?: AttrLike;
62
+ slot?: AttrLike;
63
+ is?: AttrLike;
64
+ autoCapitalize?: AttrLike<'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters'>;
65
+ autoFocus?: AttrLike<boolean>;
66
+ accessKey?: AttrLike;
67
+ /** `data-morph-skip` opts a subtree out of kerf's diff. Any value (incl. `true`) is treated as set. */
68
+ 'data-morph-skip'?: AttrValue;
69
+ children?: unknown;
70
+ }
71
+ /** Element-specific attribute interfaces. Each extends `KerfBaseAttrs`. */
72
+ interface HTMLAnchorAttrs extends KerfBaseAttrs {
73
+ href?: AttrLike;
74
+ target?: AttrLike<'_self' | '_blank' | '_parent' | '_top'>;
75
+ rel?: AttrLike;
76
+ download?: AttrLike;
77
+ hrefLang?: AttrLike;
78
+ ping?: AttrLike;
79
+ referrerPolicy?: AttrLike;
80
+ type?: AttrLike;
81
+ }
82
+ interface HTMLAreaAttrs extends KerfBaseAttrs {
83
+ alt?: AttrLike;
84
+ coords?: AttrLike;
85
+ shape?: AttrLike<'rect' | 'circle' | 'poly' | 'default'>;
86
+ href?: AttrLike;
87
+ target?: AttrLike;
88
+ rel?: AttrLike;
89
+ }
90
+ interface HTMLImgAttrs extends KerfBaseAttrs {
91
+ src?: AttrLike;
92
+ alt?: AttrLike;
93
+ width?: AttrLike<number | string>;
94
+ height?: AttrLike<number | string>;
95
+ srcSet?: AttrLike;
96
+ sizes?: AttrLike;
97
+ loading?: AttrLike<'eager' | 'lazy'>;
98
+ decoding?: AttrLike<'sync' | 'async' | 'auto'>;
99
+ crossOrigin?: AttrLike<'anonymous' | 'use-credentials' | ''>;
100
+ referrerPolicy?: AttrLike;
101
+ useMap?: AttrLike;
102
+ fetchPriority?: AttrLike<'high' | 'low' | 'auto'>;
103
+ }
104
+ interface HTMLInputAttrs extends KerfBaseAttrs {
105
+ type?: AttrLike<'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'datetime-local' | 'time' | 'month' | 'week' | 'color' | 'checkbox' | 'radio' | 'file' | 'hidden' | 'submit' | 'reset' | 'button' | 'image' | 'range'>;
106
+ name?: AttrLike;
107
+ value?: AttrLike;
108
+ defaultValue?: AttrLike;
109
+ placeholder?: AttrLike;
110
+ required?: AttrLike<boolean>;
111
+ disabled?: AttrLike<boolean>;
112
+ readOnly?: AttrLike<boolean>;
113
+ checked?: AttrLike<boolean>;
114
+ defaultChecked?: AttrLike<boolean>;
115
+ multiple?: AttrLike<boolean>;
116
+ pattern?: AttrLike;
117
+ min?: AttrLike<number | string>;
118
+ max?: AttrLike<number | string>;
119
+ step?: AttrLike<number | string>;
120
+ minLength?: AttrLike<number>;
121
+ maxLength?: AttrLike<number>;
122
+ size?: AttrLike<number>;
123
+ autoComplete?: AttrLike;
124
+ form?: AttrLike;
125
+ formAction?: AttrLike;
126
+ formMethod?: AttrLike<'get' | 'post' | 'dialog'>;
127
+ formTarget?: AttrLike;
128
+ formEncType?: AttrLike;
129
+ formNoValidate?: AttrLike<boolean>;
130
+ list?: AttrLike;
131
+ src?: AttrLike;
132
+ alt?: AttrLike;
133
+ width?: AttrLike<number | string>;
134
+ height?: AttrLike<number | string>;
135
+ accept?: AttrLike;
136
+ capture?: AttrLike<boolean | 'user' | 'environment'>;
137
+ }
138
+ interface HTMLButtonAttrs extends KerfBaseAttrs {
139
+ type?: AttrLike<'button' | 'submit' | 'reset'>;
140
+ name?: AttrLike;
141
+ value?: AttrLike;
142
+ disabled?: AttrLike<boolean>;
143
+ form?: AttrLike;
144
+ formAction?: AttrLike;
145
+ formMethod?: AttrLike;
146
+ formTarget?: AttrLike;
147
+ formEncType?: AttrLike;
148
+ formNoValidate?: AttrLike<boolean>;
149
+ }
150
+ interface HTMLFormAttrs extends KerfBaseAttrs {
151
+ action?: AttrLike;
152
+ method?: AttrLike<'get' | 'post' | 'dialog'>;
153
+ encType?: AttrLike;
154
+ target?: AttrLike;
155
+ name?: AttrLike;
156
+ noValidate?: AttrLike<boolean>;
157
+ acceptCharset?: AttrLike;
158
+ autoComplete?: AttrLike;
159
+ }
160
+ interface HTMLLabelAttrs extends KerfBaseAttrs {
161
+ htmlFor?: AttrLike;
162
+ form?: AttrLike;
163
+ }
164
+ interface HTMLOptionAttrs extends KerfBaseAttrs {
165
+ value?: AttrLike;
166
+ selected?: AttrLike<boolean>;
167
+ defaultSelected?: AttrLike<boolean>;
168
+ disabled?: AttrLike<boolean>;
169
+ label?: AttrLike;
170
+ }
171
+ interface HTMLOptgroupAttrs extends KerfBaseAttrs {
172
+ label?: AttrLike;
173
+ disabled?: AttrLike<boolean>;
174
+ }
175
+ interface HTMLSelectAttrs extends KerfBaseAttrs {
176
+ name?: AttrLike;
177
+ value?: AttrLike;
178
+ defaultValue?: AttrLike;
179
+ multiple?: AttrLike<boolean>;
180
+ required?: AttrLike<boolean>;
181
+ disabled?: AttrLike<boolean>;
182
+ size?: AttrLike<number>;
183
+ form?: AttrLike;
184
+ autoComplete?: AttrLike;
185
+ }
186
+ interface HTMLTextareaAttrs extends KerfBaseAttrs {
187
+ name?: AttrLike;
188
+ value?: AttrLike;
189
+ defaultValue?: AttrLike;
190
+ placeholder?: AttrLike;
191
+ rows?: AttrLike<number>;
192
+ cols?: AttrLike<number>;
193
+ required?: AttrLike<boolean>;
194
+ disabled?: AttrLike<boolean>;
195
+ readOnly?: AttrLike<boolean>;
196
+ maxLength?: AttrLike<number>;
197
+ minLength?: AttrLike<number>;
198
+ wrap?: AttrLike<'hard' | 'soft' | 'off'>;
199
+ autoComplete?: AttrLike;
200
+ form?: AttrLike;
201
+ }
202
+ interface HTMLTableAttrs extends KerfBaseAttrs {
203
+ cellPadding?: AttrLike<number | string>;
204
+ cellSpacing?: AttrLike<number | string>;
205
+ }
206
+ interface HTMLTableCellAttrs extends KerfBaseAttrs {
207
+ colSpan?: AttrLike<number>;
208
+ rowSpan?: AttrLike<number>;
209
+ headers?: AttrLike;
210
+ scope?: AttrLike<'row' | 'col' | 'rowgroup' | 'colgroup'>;
211
+ abbr?: AttrLike;
212
+ }
213
+ interface HTMLColAttrs extends KerfBaseAttrs {
214
+ span?: AttrLike<number>;
215
+ }
216
+ interface HTMLMetaAttrs extends KerfBaseAttrs {
217
+ name?: AttrLike;
218
+ content?: AttrLike;
219
+ charSet?: AttrLike;
220
+ httpEquiv?: AttrLike;
221
+ }
222
+ interface HTMLLinkAttrs extends KerfBaseAttrs {
223
+ href?: AttrLike;
224
+ rel?: AttrLike;
225
+ type?: AttrLike;
226
+ media?: AttrLike;
227
+ sizes?: AttrLike;
228
+ hrefLang?: AttrLike;
229
+ as?: AttrLike;
230
+ crossOrigin?: AttrLike;
231
+ integrity?: AttrLike;
232
+ referrerPolicy?: AttrLike;
233
+ fetchPriority?: AttrLike<'high' | 'low' | 'auto'>;
234
+ }
235
+ interface HTMLScriptAttrs extends KerfBaseAttrs {
236
+ src?: AttrLike;
237
+ type?: AttrLike;
238
+ async?: AttrLike<boolean>;
239
+ defer?: AttrLike<boolean>;
240
+ noModule?: AttrLike<boolean>;
241
+ integrity?: AttrLike;
242
+ crossOrigin?: AttrLike;
243
+ referrerPolicy?: AttrLike;
244
+ nonce?: AttrLike;
245
+ }
246
+ interface HTMLStyleAttrs extends KerfBaseAttrs {
247
+ type?: AttrLike;
248
+ media?: AttrLike;
249
+ scoped?: AttrLike<boolean>;
250
+ }
251
+ interface HTMLIframeAttrs extends KerfBaseAttrs {
252
+ src?: AttrLike;
253
+ srcDoc?: AttrLike;
254
+ name?: AttrLike;
255
+ sandbox?: AttrLike;
256
+ allow?: AttrLike;
257
+ allowFullScreen?: AttrLike<boolean>;
258
+ width?: AttrLike<number | string>;
259
+ height?: AttrLike<number | string>;
260
+ loading?: AttrLike<'eager' | 'lazy'>;
261
+ referrerPolicy?: AttrLike;
262
+ }
263
+ interface HTMLMediaAttrs extends KerfBaseAttrs {
264
+ src?: AttrLike;
265
+ controls?: AttrLike<boolean>;
266
+ autoPlay?: AttrLike<boolean>;
267
+ loop?: AttrLike<boolean>;
268
+ muted?: AttrLike<boolean>;
269
+ preload?: AttrLike<'auto' | 'metadata' | 'none' | ''>;
270
+ crossOrigin?: AttrLike;
271
+ }
272
+ interface HTMLVideoAttrs extends HTMLMediaAttrs {
273
+ poster?: AttrLike;
274
+ width?: AttrLike<number | string>;
275
+ height?: AttrLike<number | string>;
276
+ playsInline?: AttrLike<boolean>;
277
+ }
278
+ interface HTMLSourceAttrs extends KerfBaseAttrs {
279
+ src?: AttrLike;
280
+ type?: AttrLike;
281
+ srcSet?: AttrLike;
282
+ sizes?: AttrLike;
283
+ media?: AttrLike;
284
+ }
285
+ interface HTMLTrackAttrs extends KerfBaseAttrs {
286
+ src?: AttrLike;
287
+ kind?: AttrLike<'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata'>;
288
+ srcLang?: AttrLike;
289
+ label?: AttrLike;
290
+ default?: AttrLike<boolean>;
291
+ }
292
+ interface HTMLDetailsAttrs extends KerfBaseAttrs {
293
+ open?: AttrLike<boolean>;
294
+ }
295
+ interface HTMLDialogAttrs extends KerfBaseAttrs {
296
+ open?: AttrLike<boolean>;
297
+ }
298
+ interface HTMLOlAttrs extends KerfBaseAttrs {
299
+ reversed?: AttrLike<boolean>;
300
+ start?: AttrLike<number>;
301
+ type?: AttrLike<'1' | 'a' | 'A' | 'i' | 'I'>;
302
+ }
303
+ interface HTMLLiAttrs extends KerfBaseAttrs {
304
+ value?: AttrLike<number>;
305
+ }
306
+ interface HTMLProgressAttrs extends KerfBaseAttrs {
307
+ value?: AttrLike<number>;
308
+ max?: AttrLike<number>;
309
+ }
310
+ interface HTMLMeterAttrs extends KerfBaseAttrs {
311
+ value?: AttrLike<number>;
312
+ min?: AttrLike<number>;
313
+ max?: AttrLike<number>;
314
+ low?: AttrLike<number>;
315
+ high?: AttrLike<number>;
316
+ optimum?: AttrLike<number>;
317
+ }
318
+ interface HTMLCanvasAttrs extends KerfBaseAttrs {
319
+ width?: AttrLike<number | string>;
320
+ height?: AttrLike<number | string>;
321
+ }
322
+ interface HTMLBaseAttrs extends KerfBaseAttrs {
323
+ href?: AttrLike;
324
+ target?: AttrLike;
325
+ }
326
+ interface HTMLBlockquoteAttrs extends KerfBaseAttrs {
327
+ cite?: AttrLike;
328
+ }
329
+ interface HTMLQAttrs extends KerfBaseAttrs {
330
+ cite?: AttrLike;
331
+ }
332
+ /**
333
+ * SVG attribute set — focused on the elements `toElement`'s SVG path supports
334
+ * (the `SVG_FRAGMENT_TAGS` set in `src/toElement.ts`). Presentation attrs are
335
+ * shared via `SVGPresentationAttrs`.
336
+ */
337
+ interface SVGPresentationAttrs {
338
+ fill?: AttrLike;
339
+ fillOpacity?: AttrLike<number | string>;
340
+ fillRule?: AttrLike<'nonzero' | 'evenodd' | 'inherit'>;
341
+ stroke?: AttrLike;
342
+ strokeWidth?: AttrLike<number | string>;
343
+ strokeOpacity?: AttrLike<number | string>;
344
+ strokeLinecap?: AttrLike<'butt' | 'round' | 'square' | 'inherit'>;
345
+ strokeLinejoin?: AttrLike<'miter' | 'round' | 'bevel' | 'inherit'>;
346
+ strokeDasharray?: AttrLike;
347
+ strokeDashoffset?: AttrLike<number | string>;
348
+ strokeMiterlimit?: AttrLike<number | string>;
349
+ opacity?: AttrLike<number | string>;
350
+ vectorEffect?: AttrLike;
351
+ clipPath?: AttrLike;
352
+ clipRule?: AttrLike;
353
+ mask?: AttrLike;
354
+ filter?: AttrLike;
355
+ pointerEvents?: AttrLike;
356
+ shapeRendering?: AttrLike;
357
+ paintOrder?: AttrLike;
358
+ color?: AttrLike;
359
+ display?: AttrLike;
360
+ visibility?: AttrLike;
361
+ }
362
+ interface SVGCommonAttrs extends DataAriaAttrs, SVGPresentationAttrs {
363
+ id?: AttrLike;
364
+ className?: AttrLike;
365
+ style?: AttrLike;
366
+ transform?: AttrLike;
367
+ tabIndex?: AttrLike<number>;
368
+ role?: AttrLike;
369
+ xmlns?: AttrLike;
370
+ xmlnsXlink?: AttrLike;
371
+ children?: unknown;
372
+ }
373
+ interface SVGSvgAttrs extends SVGCommonAttrs {
374
+ width?: AttrLike<number | string>;
375
+ height?: AttrLike<number | string>;
376
+ viewBox?: AttrLike;
377
+ preserveAspectRatio?: AttrLike;
378
+ x?: AttrLike<number | string>;
379
+ y?: AttrLike<number | string>;
380
+ }
381
+ interface SVGPathAttrs extends SVGCommonAttrs {
382
+ d?: AttrLike;
383
+ pathLength?: AttrLike<number>;
384
+ }
385
+ interface SVGCircleAttrs extends SVGCommonAttrs {
386
+ cx?: AttrLike<number | string>;
387
+ cy?: AttrLike<number | string>;
388
+ r?: AttrLike<number | string>;
389
+ }
390
+ interface SVGRectAttrs extends SVGCommonAttrs {
391
+ x?: AttrLike<number | string>;
392
+ y?: AttrLike<number | string>;
393
+ width?: AttrLike<number | string>;
394
+ height?: AttrLike<number | string>;
395
+ rx?: AttrLike<number | string>;
396
+ ry?: AttrLike<number | string>;
397
+ }
398
+ interface SVGLineAttrs extends SVGCommonAttrs {
399
+ x1?: AttrLike<number | string>;
400
+ y1?: AttrLike<number | string>;
401
+ x2?: AttrLike<number | string>;
402
+ y2?: AttrLike<number | string>;
403
+ }
404
+ interface SVGEllipseAttrs extends SVGCommonAttrs {
405
+ cx?: AttrLike<number | string>;
406
+ cy?: AttrLike<number | string>;
407
+ rx?: AttrLike<number | string>;
408
+ ry?: AttrLike<number | string>;
409
+ }
410
+ interface SVGPolyAttrs extends SVGCommonAttrs {
411
+ points?: AttrLike;
412
+ }
413
+ interface SVGTextAttrs extends SVGCommonAttrs {
414
+ x?: AttrLike<number | string>;
415
+ y?: AttrLike<number | string>;
416
+ dx?: AttrLike<number | string>;
417
+ dy?: AttrLike<number | string>;
418
+ textAnchor?: AttrLike<'start' | 'middle' | 'end' | 'inherit'>;
419
+ dominantBaseline?: AttrLike;
420
+ fontFamily?: AttrLike;
421
+ fontSize?: AttrLike<number | string>;
422
+ fontStyle?: AttrLike;
423
+ fontWeight?: AttrLike<number | string>;
424
+ letterSpacing?: AttrLike<number | string>;
425
+ }
426
+ interface SVGUseAttrs extends SVGCommonAttrs {
427
+ xlinkHref?: AttrLike;
428
+ href?: AttrLike;
429
+ x?: AttrLike<number | string>;
430
+ y?: AttrLike<number | string>;
431
+ width?: AttrLike<number | string>;
432
+ height?: AttrLike<number | string>;
433
+ }
434
+ interface SVGImageAttrs extends SVGCommonAttrs {
435
+ href?: AttrLike;
436
+ xlinkHref?: AttrLike;
437
+ x?: AttrLike<number | string>;
438
+ y?: AttrLike<number | string>;
439
+ width?: AttrLike<number | string>;
440
+ height?: AttrLike<number | string>;
441
+ preserveAspectRatio?: AttrLike;
442
+ }
443
+ interface SVGForeignObjectAttrs extends SVGCommonAttrs {
444
+ x?: AttrLike<number | string>;
445
+ y?: AttrLike<number | string>;
446
+ width?: AttrLike<number | string>;
447
+ height?: AttrLike<number | string>;
448
+ }
449
+ /**
450
+ * Loose attribute set for custom elements / web components. Use via
451
+ * declaration merging into the `kerfjs/jsx-runtime` JSX namespace if your
452
+ * project uses tags not enumerated below:
453
+ *
454
+ * import type { KerfCustomElement } from 'kerfjs/jsx-runtime';
455
+ *
456
+ * declare module 'kerfjs/jsx-runtime' {
457
+ * namespace JSX {
458
+ * interface IntrinsicElements {
459
+ * 'my-component': KerfCustomElement & { foo?: string };
460
+ * }
461
+ * }
462
+ * }
463
+ *
464
+ * `KerfCustomElement` is re-exported from `kerfjs/jsx-runtime` (KF-100) so
465
+ * apps don't need to reach into the internal `kerfjs/jsx-types` path.
466
+ */
467
+ interface KerfCustomElement extends KerfBaseAttrs {
468
+ [k: string]: AttrValue | unknown;
469
+ }
470
+ /**
471
+ * Built-in tag table. Renamed from `IntrinsicElements` (KF-123) so the type
472
+ * name in `dist/jsx-runtime.d.ts` cannot shadow the namespace's own
473
+ * `IntrinsicElements` after tsup/tsc strips import aliases — the previous
474
+ * name produced `interface IntrinsicElements extends IntrinsicElements {}`
475
+ * in the emitted .d.ts, which self-resolves to an empty interface and
476
+ * breaks every `<tag>` in consumer .tsx with TS2339.
477
+ */
478
+ interface KerfBuiltinIntrinsicElements {
479
+ html: KerfBaseAttrs;
480
+ head: KerfBaseAttrs;
481
+ body: KerfBaseAttrs;
482
+ div: KerfBaseAttrs;
483
+ span: KerfBaseAttrs;
484
+ section: KerfBaseAttrs;
485
+ article: KerfBaseAttrs;
486
+ header: KerfBaseAttrs;
487
+ footer: KerfBaseAttrs;
488
+ main: KerfBaseAttrs;
489
+ nav: KerfBaseAttrs;
490
+ aside: KerfBaseAttrs;
491
+ h1: KerfBaseAttrs;
492
+ h2: KerfBaseAttrs;
493
+ h3: KerfBaseAttrs;
494
+ h4: KerfBaseAttrs;
495
+ h5: KerfBaseAttrs;
496
+ h6: KerfBaseAttrs;
497
+ p: KerfBaseAttrs;
498
+ hr: KerfBaseAttrs;
499
+ br: KerfBaseAttrs;
500
+ pre: KerfBaseAttrs;
501
+ blockquote: HTMLBlockquoteAttrs;
502
+ q: HTMLQAttrs;
503
+ ol: HTMLOlAttrs;
504
+ ul: KerfBaseAttrs;
505
+ li: HTMLLiAttrs;
506
+ dl: KerfBaseAttrs;
507
+ dt: KerfBaseAttrs;
508
+ dd: KerfBaseAttrs;
509
+ figure: KerfBaseAttrs;
510
+ figcaption: KerfBaseAttrs;
511
+ a: HTMLAnchorAttrs;
512
+ em: KerfBaseAttrs;
513
+ strong: KerfBaseAttrs;
514
+ small: KerfBaseAttrs;
515
+ s: KerfBaseAttrs;
516
+ cite: KerfBaseAttrs;
517
+ code: KerfBaseAttrs;
518
+ kbd: KerfBaseAttrs;
519
+ samp: KerfBaseAttrs;
520
+ var: KerfBaseAttrs;
521
+ sub: KerfBaseAttrs;
522
+ sup: KerfBaseAttrs;
523
+ i: KerfBaseAttrs;
524
+ b: KerfBaseAttrs;
525
+ u: KerfBaseAttrs;
526
+ mark: KerfBaseAttrs;
527
+ abbr: KerfBaseAttrs;
528
+ time: KerfBaseAttrs & {
529
+ dateTime?: AttrLike;
530
+ };
531
+ img: HTMLImgAttrs;
532
+ picture: KerfBaseAttrs;
533
+ source: HTMLSourceAttrs;
534
+ track: HTMLTrackAttrs;
535
+ iframe: HTMLIframeAttrs;
536
+ embed: KerfBaseAttrs & {
537
+ src?: AttrLike;
538
+ type?: AttrLike;
539
+ width?: AttrLike<number | string>;
540
+ height?: AttrLike<number | string>;
541
+ };
542
+ object: KerfBaseAttrs & {
543
+ data?: AttrLike;
544
+ type?: AttrLike;
545
+ name?: AttrLike;
546
+ width?: AttrLike<number | string>;
547
+ height?: AttrLike<number | string>;
548
+ };
549
+ audio: HTMLMediaAttrs;
550
+ video: HTMLVideoAttrs;
551
+ canvas: HTMLCanvasAttrs;
552
+ area: HTMLAreaAttrs;
553
+ map: KerfBaseAttrs & {
554
+ name?: AttrLike;
555
+ };
556
+ form: HTMLFormAttrs;
557
+ input: HTMLInputAttrs;
558
+ button: HTMLButtonAttrs;
559
+ select: HTMLSelectAttrs;
560
+ optgroup: HTMLOptgroupAttrs;
561
+ option: HTMLOptionAttrs;
562
+ textarea: HTMLTextareaAttrs;
563
+ label: HTMLLabelAttrs;
564
+ fieldset: KerfBaseAttrs & {
565
+ name?: AttrLike;
566
+ form?: AttrLike;
567
+ disabled?: AttrLike<boolean>;
568
+ };
569
+ legend: KerfBaseAttrs;
570
+ datalist: KerfBaseAttrs;
571
+ output: KerfBaseAttrs & {
572
+ name?: AttrLike;
573
+ form?: AttrLike;
574
+ htmlFor?: AttrLike;
575
+ };
576
+ progress: HTMLProgressAttrs;
577
+ meter: HTMLMeterAttrs;
578
+ table: HTMLTableAttrs;
579
+ caption: KerfBaseAttrs;
580
+ colgroup: HTMLColAttrs;
581
+ col: HTMLColAttrs;
582
+ thead: KerfBaseAttrs;
583
+ tbody: KerfBaseAttrs;
584
+ tfoot: KerfBaseAttrs;
585
+ tr: KerfBaseAttrs;
586
+ td: HTMLTableCellAttrs;
587
+ th: HTMLTableCellAttrs;
588
+ meta: HTMLMetaAttrs;
589
+ link: HTMLLinkAttrs;
590
+ script: HTMLScriptAttrs;
591
+ style: HTMLStyleAttrs;
592
+ base: HTMLBaseAttrs;
593
+ title: KerfBaseAttrs;
594
+ details: HTMLDetailsAttrs;
595
+ summary: KerfBaseAttrs;
596
+ dialog: HTMLDialogAttrs;
597
+ template: KerfBaseAttrs;
598
+ slot: KerfBaseAttrs & {
599
+ name?: AttrLike;
600
+ };
601
+ svg: SVGSvgAttrs;
602
+ g: SVGCommonAttrs;
603
+ defs: SVGCommonAttrs;
604
+ symbol: SVGCommonAttrs;
605
+ use: SVGUseAttrs;
606
+ path: SVGPathAttrs;
607
+ circle: SVGCircleAttrs;
608
+ rect: SVGRectAttrs;
609
+ line: SVGLineAttrs;
610
+ ellipse: SVGEllipseAttrs;
611
+ polygon: SVGPolyAttrs;
612
+ polyline: SVGPolyAttrs;
613
+ text: SVGTextAttrs;
614
+ tspan: SVGTextAttrs;
615
+ image: SVGImageAttrs;
616
+ foreignObject: SVGForeignObjectAttrs;
617
+ clipPath: SVGCommonAttrs;
618
+ mask: SVGCommonAttrs;
619
+ pattern: SVGCommonAttrs;
620
+ marker: SVGCommonAttrs;
621
+ linearGradient: SVGCommonAttrs;
622
+ radialGradient: SVGCommonAttrs;
623
+ stop: SVGCommonAttrs & {
624
+ offset?: AttrLike<number | string>;
625
+ stopColor?: AttrLike;
626
+ stopOpacity?: AttrLike<number | string>;
627
+ };
628
+ }
629
+
1
630
  /**
2
631
  * `Segment` — kerf's structured render output.
3
632
  *
@@ -41,7 +670,45 @@ interface ListSegment {
41
670
  kind: 'list';
42
671
  id: string;
43
672
  items: ListItem[];
673
+ /**
674
+ * Optional granular patches (KF-92). When present, the list reconciler
675
+ * applies these directly to the existing binding instead of doing a
676
+ * full classify+reconcile pass. Emitted by `each()` when bound to an
677
+ * `arraySignal`. Mutually exclusive with the `items` snapshot in the
678
+ * sense that the snapshot is treated as informational/fall-back when
679
+ * patches are present.
680
+ */
681
+ patches?: ArrayPatchInternal[];
44
682
  }
683
+ /**
684
+ * Internal patch shape used inside list segments. Mirrors `ArrayPatch<T>`
685
+ * from `array-signal.ts` but typed against `object` so the segment layer
686
+ * doesn't need to be generic. `update` / `insert` patches carry the row's
687
+ * pre-rendered HTML — `each()` renders them at JSX-evaluation time inside a
688
+ * try/catch so a throwing render falls back to the snapshot path (KF-99)
689
+ * instead of leaving the signal and DOM divergent.
690
+ */
691
+ type ArrayPatchInternal = {
692
+ type: 'update';
693
+ index: number;
694
+ item: object;
695
+ html: string;
696
+ } | {
697
+ type: 'insert';
698
+ index: number;
699
+ item: object;
700
+ html: string;
701
+ } | {
702
+ type: 'remove';
703
+ index: number;
704
+ } | {
705
+ type: 'move';
706
+ from: number;
707
+ to: number;
708
+ } | {
709
+ type: 'replace';
710
+ items: readonly object[];
711
+ };
45
712
  interface MixedSegment {
46
713
  kind: 'mixed';
47
714
  parts: Segment[];
@@ -93,6 +760,19 @@ declare function raw(html: string): SafeHtml;
93
760
  * `each()` so the JSX runtime is the sole owner of `SafeHtml` construction.
94
761
  */
95
762
  declare function listSafeHtml(id: string, items: ListSegment['items']): SafeHtml;
763
+ /**
764
+ * Internal: build a `SafeHtml` representing a granular list segment with
765
+ * patches (KF-92). The reconciler applies the patches to the existing
766
+ * binding directly, skipping the per-item iteration that the snapshot
767
+ * `listSafeHtml` requires. `items` is included for fall-through paths
768
+ * (toString during SSR, fall-back when the binding doesn't exist yet).
769
+ *
770
+ * Patch HTML is rendered upstream (in `each()`) inside a try/catch — see
771
+ * KF-99 — so by the time we get here every `update` / `insert` patch
772
+ * already carries a `html` string, and the reconciler does no further
773
+ * row rendering.
774
+ */
775
+ declare function granularListSafeHtml(id: string, items: ListSegment['items'], patches: NonNullable<ListSegment['patches']>): SafeHtml;
96
776
  type Child = SafeHtml | string | number | boolean | null | undefined;
97
777
  type Children = Child | Children[];
98
778
  interface Props {
@@ -109,9 +789,8 @@ declare namespace JSX {
109
789
  interface ElementChildrenAttribute {
110
790
  children: unknown;
111
791
  }
112
- interface IntrinsicElements {
113
- [elemName: string]: Record<string, unknown>;
792
+ interface IntrinsicElements extends KerfBuiltinIntrinsicElements {
114
793
  }
115
794
  }
116
795
 
117
- export { Fragment, JSX, SafeHtml, isSafeHtml, jsx, jsx as jsxDEV, jsx as jsxs, listSafeHtml, raw };
796
+ export { type AttrLike, type AttrValue, type DataAriaAttrs, Fragment, JSX, type KerfBaseAttrs, type KerfCustomElement, SafeHtml, granularListSafeHtml, isSafeHtml, jsx, jsx as jsxDEV, jsx as jsxs, listSafeHtml, raw };
@@ -1,3 +1,3 @@
1
- export { Fragment, SafeHtml, isSafeHtml, jsx, jsx as jsxDEV, jsx as jsxs, listSafeHtml, raw } from './chunk-WK5D3OO7.js';
1
+ export { Fragment, SafeHtml, granularListSafeHtml, isSafeHtml, jsx, jsx as jsxDEV, jsx as jsxs, listSafeHtml, raw } from './chunk-KFOSUCCC.js';
2
2
  //# sourceMappingURL=jsx-runtime.js.map
3
3
  //# sourceMappingURL=jsx-runtime.js.map