@coherent.js/core 1.0.0-beta.3 → 1.0.0-beta.6
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.
- package/dist/index.cjs +2531 -1308
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +2523 -1307
- package/dist/index.js.map +4 -4
- package/package.json +4 -2
- package/types/elements.d.ts +1080 -0
- package/types/index.d.ts +199 -65
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coherent.js Strict Element Types
|
|
3
|
+
* Per-element attribute validation for HTML elements
|
|
4
|
+
*
|
|
5
|
+
* This module provides strict TypeScript types for HTML elements with:
|
|
6
|
+
* - Per-element attribute validation (e.g., 'checked' only on input)
|
|
7
|
+
* - Strict children types (no boolean children)
|
|
8
|
+
* - Void element handling (no children on img, input, br, etc.)
|
|
9
|
+
* - Data attribute support via template literal types
|
|
10
|
+
*
|
|
11
|
+
* @version 1.0.0-beta.1
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Strict Children Type
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Valid child types for Coherent elements.
|
|
20
|
+
* Note: boolean is NOT allowed - use null/undefined for conditional rendering.
|
|
21
|
+
*/
|
|
22
|
+
export type CoherentChild =
|
|
23
|
+
| string
|
|
24
|
+
| number
|
|
25
|
+
| StrictCoherentElement
|
|
26
|
+
| StrictCoherentElement[]
|
|
27
|
+
| null
|
|
28
|
+
| undefined;
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Global HTML Attributes
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* ARIA role values for accessibility
|
|
36
|
+
*/
|
|
37
|
+
export type AriaRole =
|
|
38
|
+
| 'alert'
|
|
39
|
+
| 'alertdialog'
|
|
40
|
+
| 'application'
|
|
41
|
+
| 'article'
|
|
42
|
+
| 'banner'
|
|
43
|
+
| 'button'
|
|
44
|
+
| 'cell'
|
|
45
|
+
| 'checkbox'
|
|
46
|
+
| 'columnheader'
|
|
47
|
+
| 'combobox'
|
|
48
|
+
| 'complementary'
|
|
49
|
+
| 'contentinfo'
|
|
50
|
+
| 'definition'
|
|
51
|
+
| 'dialog'
|
|
52
|
+
| 'directory'
|
|
53
|
+
| 'document'
|
|
54
|
+
| 'feed'
|
|
55
|
+
| 'figure'
|
|
56
|
+
| 'form'
|
|
57
|
+
| 'grid'
|
|
58
|
+
| 'gridcell'
|
|
59
|
+
| 'group'
|
|
60
|
+
| 'heading'
|
|
61
|
+
| 'img'
|
|
62
|
+
| 'link'
|
|
63
|
+
| 'list'
|
|
64
|
+
| 'listbox'
|
|
65
|
+
| 'listitem'
|
|
66
|
+
| 'log'
|
|
67
|
+
| 'main'
|
|
68
|
+
| 'marquee'
|
|
69
|
+
| 'math'
|
|
70
|
+
| 'menu'
|
|
71
|
+
| 'menubar'
|
|
72
|
+
| 'menuitem'
|
|
73
|
+
| 'menuitemcheckbox'
|
|
74
|
+
| 'menuitemradio'
|
|
75
|
+
| 'navigation'
|
|
76
|
+
| 'none'
|
|
77
|
+
| 'note'
|
|
78
|
+
| 'option'
|
|
79
|
+
| 'presentation'
|
|
80
|
+
| 'progressbar'
|
|
81
|
+
| 'radio'
|
|
82
|
+
| 'radiogroup'
|
|
83
|
+
| 'region'
|
|
84
|
+
| 'row'
|
|
85
|
+
| 'rowgroup'
|
|
86
|
+
| 'rowheader'
|
|
87
|
+
| 'scrollbar'
|
|
88
|
+
| 'search'
|
|
89
|
+
| 'searchbox'
|
|
90
|
+
| 'separator'
|
|
91
|
+
| 'slider'
|
|
92
|
+
| 'spinbutton'
|
|
93
|
+
| 'status'
|
|
94
|
+
| 'switch'
|
|
95
|
+
| 'tab'
|
|
96
|
+
| 'table'
|
|
97
|
+
| 'tablist'
|
|
98
|
+
| 'tabpanel'
|
|
99
|
+
| 'term'
|
|
100
|
+
| 'textbox'
|
|
101
|
+
| 'timer'
|
|
102
|
+
| 'toolbar'
|
|
103
|
+
| 'tooltip'
|
|
104
|
+
| 'tree'
|
|
105
|
+
| 'treegrid'
|
|
106
|
+
| 'treeitem'
|
|
107
|
+
| string; // Allow custom roles
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Global HTML attributes shared by all elements.
|
|
111
|
+
* Based on lib.dom.d.ts patterns.
|
|
112
|
+
*/
|
|
113
|
+
export interface GlobalHTMLAttributes {
|
|
114
|
+
// Core attributes
|
|
115
|
+
id?: string;
|
|
116
|
+
className?: string;
|
|
117
|
+
class?: string; // alias for className
|
|
118
|
+
style?: string | Record<string, string | number>;
|
|
119
|
+
title?: string;
|
|
120
|
+
lang?: string;
|
|
121
|
+
dir?: 'ltr' | 'rtl' | 'auto';
|
|
122
|
+
tabIndex?: number;
|
|
123
|
+
hidden?: boolean;
|
|
124
|
+
draggable?: boolean | 'true' | 'false';
|
|
125
|
+
contentEditable?: boolean | 'true' | 'false' | 'inherit';
|
|
126
|
+
spellCheck?: boolean | 'true' | 'false';
|
|
127
|
+
translate?: 'yes' | 'no';
|
|
128
|
+
accessKey?: string;
|
|
129
|
+
autoCapitalize?: 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
|
|
130
|
+
enterKeyHint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
|
|
131
|
+
inputMode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
|
|
132
|
+
slot?: string;
|
|
133
|
+
is?: string;
|
|
134
|
+
|
|
135
|
+
// Key prop for reconciliation (extracted, not rendered)
|
|
136
|
+
key?: string | number;
|
|
137
|
+
|
|
138
|
+
// Data attributes (template literal type)
|
|
139
|
+
[key: `data-${string}`]: string | number | boolean | undefined;
|
|
140
|
+
|
|
141
|
+
// ARIA attributes
|
|
142
|
+
role?: AriaRole;
|
|
143
|
+
'aria-label'?: string;
|
|
144
|
+
'aria-labelledby'?: string;
|
|
145
|
+
'aria-describedby'?: string;
|
|
146
|
+
'aria-hidden'?: boolean | 'true' | 'false';
|
|
147
|
+
'aria-disabled'?: boolean | 'true' | 'false';
|
|
148
|
+
'aria-expanded'?: boolean | 'true' | 'false';
|
|
149
|
+
'aria-selected'?: boolean | 'true' | 'false';
|
|
150
|
+
'aria-checked'?: boolean | 'true' | 'false' | 'mixed';
|
|
151
|
+
'aria-pressed'?: boolean | 'true' | 'false' | 'mixed';
|
|
152
|
+
'aria-current'?: boolean | 'true' | 'false' | 'page' | 'step' | 'location' | 'date' | 'time';
|
|
153
|
+
'aria-live'?: 'off' | 'assertive' | 'polite';
|
|
154
|
+
'aria-atomic'?: boolean | 'true' | 'false';
|
|
155
|
+
'aria-busy'?: boolean | 'true' | 'false';
|
|
156
|
+
'aria-controls'?: string;
|
|
157
|
+
'aria-haspopup'?: boolean | 'true' | 'false' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';
|
|
158
|
+
'aria-invalid'?: boolean | 'true' | 'false' | 'grammar' | 'spelling';
|
|
159
|
+
'aria-modal'?: boolean | 'true' | 'false';
|
|
160
|
+
'aria-multiline'?: boolean | 'true' | 'false';
|
|
161
|
+
'aria-multiselectable'?: boolean | 'true' | 'false';
|
|
162
|
+
'aria-orientation'?: 'horizontal' | 'vertical';
|
|
163
|
+
'aria-owns'?: string;
|
|
164
|
+
'aria-placeholder'?: string;
|
|
165
|
+
'aria-readonly'?: boolean | 'true' | 'false';
|
|
166
|
+
'aria-required'?: boolean | 'true' | 'false';
|
|
167
|
+
'aria-roledescription'?: string;
|
|
168
|
+
'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other';
|
|
169
|
+
'aria-valuemax'?: number;
|
|
170
|
+
'aria-valuemin'?: number;
|
|
171
|
+
'aria-valuenow'?: number;
|
|
172
|
+
'aria-valuetext'?: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Global Event Handlers
|
|
177
|
+
// ============================================================================
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Event handler types matching runtime behavior.
|
|
181
|
+
* Handlers can be either inline strings (for SSR) or functions (for hydration).
|
|
182
|
+
*/
|
|
183
|
+
export interface GlobalEventHandlers {
|
|
184
|
+
// Mouse events
|
|
185
|
+
onClick?: string | ((event: MouseEvent) => void);
|
|
186
|
+
onDblClick?: string | ((event: MouseEvent) => void);
|
|
187
|
+
onMouseDown?: string | ((event: MouseEvent) => void);
|
|
188
|
+
onMouseUp?: string | ((event: MouseEvent) => void);
|
|
189
|
+
onMouseEnter?: string | ((event: MouseEvent) => void);
|
|
190
|
+
onMouseLeave?: string | ((event: MouseEvent) => void);
|
|
191
|
+
onMouseMove?: string | ((event: MouseEvent) => void);
|
|
192
|
+
onMouseOver?: string | ((event: MouseEvent) => void);
|
|
193
|
+
onMouseOut?: string | ((event: MouseEvent) => void);
|
|
194
|
+
onContextMenu?: string | ((event: MouseEvent) => void);
|
|
195
|
+
|
|
196
|
+
// Keyboard events
|
|
197
|
+
onKeyDown?: string | ((event: KeyboardEvent) => void);
|
|
198
|
+
onKeyUp?: string | ((event: KeyboardEvent) => void);
|
|
199
|
+
onKeyPress?: string | ((event: KeyboardEvent) => void);
|
|
200
|
+
|
|
201
|
+
// Focus events
|
|
202
|
+
onFocus?: string | ((event: FocusEvent) => void);
|
|
203
|
+
onBlur?: string | ((event: FocusEvent) => void);
|
|
204
|
+
onFocusIn?: string | ((event: FocusEvent) => void);
|
|
205
|
+
onFocusOut?: string | ((event: FocusEvent) => void);
|
|
206
|
+
|
|
207
|
+
// Form events
|
|
208
|
+
onChange?: string | ((event: Event) => void);
|
|
209
|
+
onInput?: string | ((event: Event) => void);
|
|
210
|
+
onSubmit?: string | ((event: SubmitEvent) => void);
|
|
211
|
+
onReset?: string | ((event: Event) => void);
|
|
212
|
+
onInvalid?: string | ((event: Event) => void);
|
|
213
|
+
|
|
214
|
+
// Drag events
|
|
215
|
+
onDrag?: string | ((event: DragEvent) => void);
|
|
216
|
+
onDragEnd?: string | ((event: DragEvent) => void);
|
|
217
|
+
onDragEnter?: string | ((event: DragEvent) => void);
|
|
218
|
+
onDragLeave?: string | ((event: DragEvent) => void);
|
|
219
|
+
onDragOver?: string | ((event: DragEvent) => void);
|
|
220
|
+
onDragStart?: string | ((event: DragEvent) => void);
|
|
221
|
+
onDrop?: string | ((event: DragEvent) => void);
|
|
222
|
+
|
|
223
|
+
// Clipboard events
|
|
224
|
+
onCopy?: string | ((event: ClipboardEvent) => void);
|
|
225
|
+
onCut?: string | ((event: ClipboardEvent) => void);
|
|
226
|
+
onPaste?: string | ((event: ClipboardEvent) => void);
|
|
227
|
+
|
|
228
|
+
// Touch events
|
|
229
|
+
onTouchStart?: string | ((event: TouchEvent) => void);
|
|
230
|
+
onTouchMove?: string | ((event: TouchEvent) => void);
|
|
231
|
+
onTouchEnd?: string | ((event: TouchEvent) => void);
|
|
232
|
+
onTouchCancel?: string | ((event: TouchEvent) => void);
|
|
233
|
+
|
|
234
|
+
// Wheel events
|
|
235
|
+
onWheel?: string | ((event: WheelEvent) => void);
|
|
236
|
+
onScroll?: string | ((event: Event) => void);
|
|
237
|
+
|
|
238
|
+
// Animation events
|
|
239
|
+
onAnimationStart?: string | ((event: AnimationEvent) => void);
|
|
240
|
+
onAnimationEnd?: string | ((event: AnimationEvent) => void);
|
|
241
|
+
onAnimationIteration?: string | ((event: AnimationEvent) => void);
|
|
242
|
+
|
|
243
|
+
// Transition events
|
|
244
|
+
onTransitionStart?: string | ((event: TransitionEvent) => void);
|
|
245
|
+
onTransitionEnd?: string | ((event: TransitionEvent) => void);
|
|
246
|
+
onTransitionCancel?: string | ((event: TransitionEvent) => void);
|
|
247
|
+
onTransitionRun?: string | ((event: TransitionEvent) => void);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// Coherent-specific Properties
|
|
252
|
+
// ============================================================================
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Coherent.js-specific element properties.
|
|
256
|
+
*/
|
|
257
|
+
export interface CoherentElementBase {
|
|
258
|
+
/** Text content (escaped during render) */
|
|
259
|
+
text?: string | number;
|
|
260
|
+
/** Raw HTML content (dangerous - not escaped) */
|
|
261
|
+
html?: string;
|
|
262
|
+
/** Child elements */
|
|
263
|
+
children?: CoherentChild | CoherentChild[];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Base attributes combining global HTML attributes, event handlers, and Coherent properties.
|
|
268
|
+
*/
|
|
269
|
+
export type BaseElementAttributes = GlobalHTMLAttributes & GlobalEventHandlers & CoherentElementBase;
|
|
270
|
+
|
|
271
|
+
// ============================================================================
|
|
272
|
+
// Element-specific Attribute Interfaces
|
|
273
|
+
// ============================================================================
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Input element types
|
|
277
|
+
*/
|
|
278
|
+
export type InputType =
|
|
279
|
+
| 'text'
|
|
280
|
+
| 'email'
|
|
281
|
+
| 'password'
|
|
282
|
+
| 'number'
|
|
283
|
+
| 'tel'
|
|
284
|
+
| 'url'
|
|
285
|
+
| 'search'
|
|
286
|
+
| 'date'
|
|
287
|
+
| 'time'
|
|
288
|
+
| 'datetime-local'
|
|
289
|
+
| 'month'
|
|
290
|
+
| 'week'
|
|
291
|
+
| 'color'
|
|
292
|
+
| 'file'
|
|
293
|
+
| 'hidden'
|
|
294
|
+
| 'checkbox'
|
|
295
|
+
| 'radio'
|
|
296
|
+
| 'range'
|
|
297
|
+
| 'submit'
|
|
298
|
+
| 'reset'
|
|
299
|
+
| 'button'
|
|
300
|
+
| 'image';
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Input element attributes
|
|
304
|
+
*/
|
|
305
|
+
export interface InputAttributes extends GlobalHTMLAttributes, GlobalEventHandlers {
|
|
306
|
+
// Coherent-specific (no children for void element, only text for label)
|
|
307
|
+
text?: string | number;
|
|
308
|
+
html?: string;
|
|
309
|
+
// Note: children intentionally omitted for void element
|
|
310
|
+
|
|
311
|
+
// Input-specific attributes
|
|
312
|
+
type?: InputType;
|
|
313
|
+
value?: string | number | readonly string[];
|
|
314
|
+
checked?: boolean;
|
|
315
|
+
disabled?: boolean;
|
|
316
|
+
required?: boolean;
|
|
317
|
+
placeholder?: string;
|
|
318
|
+
name?: string;
|
|
319
|
+
min?: string | number;
|
|
320
|
+
max?: string | number;
|
|
321
|
+
step?: string | number;
|
|
322
|
+
pattern?: string;
|
|
323
|
+
readOnly?: boolean;
|
|
324
|
+
readonly?: boolean; // alias
|
|
325
|
+
autoComplete?: string;
|
|
326
|
+
autocomplete?: string; // alias
|
|
327
|
+
autoFocus?: boolean;
|
|
328
|
+
autofocus?: boolean; // alias
|
|
329
|
+
multiple?: boolean;
|
|
330
|
+
accept?: string;
|
|
331
|
+
maxLength?: number;
|
|
332
|
+
minLength?: number;
|
|
333
|
+
size?: number;
|
|
334
|
+
list?: string;
|
|
335
|
+
form?: string;
|
|
336
|
+
formAction?: string;
|
|
337
|
+
formEncType?: string;
|
|
338
|
+
formMethod?: string;
|
|
339
|
+
formNoValidate?: boolean;
|
|
340
|
+
formTarget?: string;
|
|
341
|
+
capture?: boolean | 'user' | 'environment';
|
|
342
|
+
width?: number | string;
|
|
343
|
+
height?: number | string;
|
|
344
|
+
src?: string;
|
|
345
|
+
alt?: string;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Button element attributes
|
|
350
|
+
*/
|
|
351
|
+
export interface ButtonAttributes extends BaseElementAttributes {
|
|
352
|
+
type?: 'button' | 'submit' | 'reset';
|
|
353
|
+
disabled?: boolean;
|
|
354
|
+
form?: string;
|
|
355
|
+
formAction?: string;
|
|
356
|
+
formEncType?: string;
|
|
357
|
+
formMethod?: string;
|
|
358
|
+
formTarget?: string;
|
|
359
|
+
formNoValidate?: boolean;
|
|
360
|
+
name?: string;
|
|
361
|
+
value?: string;
|
|
362
|
+
popoverTarget?: string;
|
|
363
|
+
popoverTargetAction?: 'hide' | 'show' | 'toggle';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Anchor element attributes
|
|
368
|
+
*/
|
|
369
|
+
export interface AnchorAttributes extends BaseElementAttributes {
|
|
370
|
+
href?: string;
|
|
371
|
+
target?: '_self' | '_blank' | '_parent' | '_top' | string;
|
|
372
|
+
rel?: string;
|
|
373
|
+
download?: string | boolean;
|
|
374
|
+
hrefLang?: string;
|
|
375
|
+
hreflang?: string; // alias
|
|
376
|
+
type?: string;
|
|
377
|
+
referrerPolicy?: ReferrerPolicy;
|
|
378
|
+
ping?: string;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Image element attributes (void element - no children)
|
|
383
|
+
*/
|
|
384
|
+
export interface ImgAttributes extends GlobalHTMLAttributes, GlobalEventHandlers {
|
|
385
|
+
// Coherent-specific (no children for void element)
|
|
386
|
+
text?: string | number;
|
|
387
|
+
html?: string;
|
|
388
|
+
// Note: children intentionally omitted for void element
|
|
389
|
+
|
|
390
|
+
src?: string;
|
|
391
|
+
alt?: string;
|
|
392
|
+
width?: number | string;
|
|
393
|
+
height?: number | string;
|
|
394
|
+
loading?: 'lazy' | 'eager';
|
|
395
|
+
decoding?: 'sync' | 'async' | 'auto';
|
|
396
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
397
|
+
referrerPolicy?: ReferrerPolicy;
|
|
398
|
+
srcSet?: string;
|
|
399
|
+
srcset?: string; // alias
|
|
400
|
+
sizes?: string;
|
|
401
|
+
useMap?: string;
|
|
402
|
+
isMap?: boolean;
|
|
403
|
+
fetchPriority?: 'high' | 'low' | 'auto';
|
|
404
|
+
|
|
405
|
+
// Event handlers
|
|
406
|
+
onLoad?: string | ((event: Event) => void);
|
|
407
|
+
onError?: string | ((event: Event) => void);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Form element attributes
|
|
412
|
+
*/
|
|
413
|
+
export interface FormAttributes extends BaseElementAttributes {
|
|
414
|
+
action?: string;
|
|
415
|
+
method?: 'get' | 'post' | 'dialog';
|
|
416
|
+
encType?: string;
|
|
417
|
+
enctype?: string; // alias
|
|
418
|
+
target?: '_self' | '_blank' | '_parent' | '_top' | string;
|
|
419
|
+
noValidate?: boolean;
|
|
420
|
+
novalidate?: boolean; // alias
|
|
421
|
+
autoComplete?: 'on' | 'off';
|
|
422
|
+
autocomplete?: 'on' | 'off'; // alias
|
|
423
|
+
acceptCharset?: string;
|
|
424
|
+
name?: string;
|
|
425
|
+
rel?: string;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Select element attributes
|
|
430
|
+
*/
|
|
431
|
+
export interface SelectAttributes extends BaseElementAttributes {
|
|
432
|
+
name?: string;
|
|
433
|
+
multiple?: boolean;
|
|
434
|
+
disabled?: boolean;
|
|
435
|
+
required?: boolean;
|
|
436
|
+
size?: number;
|
|
437
|
+
autoFocus?: boolean;
|
|
438
|
+
autofocus?: boolean; // alias
|
|
439
|
+
form?: string;
|
|
440
|
+
value?: string | number | readonly string[];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Textarea element attributes
|
|
445
|
+
*/
|
|
446
|
+
export interface TextareaAttributes extends BaseElementAttributes {
|
|
447
|
+
name?: string;
|
|
448
|
+
rows?: number;
|
|
449
|
+
cols?: number;
|
|
450
|
+
disabled?: boolean;
|
|
451
|
+
readOnly?: boolean;
|
|
452
|
+
readonly?: boolean; // alias
|
|
453
|
+
required?: boolean;
|
|
454
|
+
placeholder?: string;
|
|
455
|
+
maxLength?: number;
|
|
456
|
+
minLength?: number;
|
|
457
|
+
wrap?: 'soft' | 'hard' | 'off';
|
|
458
|
+
autoFocus?: boolean;
|
|
459
|
+
autofocus?: boolean; // alias
|
|
460
|
+
autoComplete?: string;
|
|
461
|
+
autocomplete?: string; // alias
|
|
462
|
+
form?: string;
|
|
463
|
+
value?: string;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Label element attributes
|
|
468
|
+
*/
|
|
469
|
+
export interface LabelAttributes extends BaseElementAttributes {
|
|
470
|
+
htmlFor?: string;
|
|
471
|
+
for?: string; // alias
|
|
472
|
+
form?: string;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Option element attributes
|
|
477
|
+
*/
|
|
478
|
+
export interface OptionAttributes extends BaseElementAttributes {
|
|
479
|
+
value?: string | number;
|
|
480
|
+
disabled?: boolean;
|
|
481
|
+
selected?: boolean;
|
|
482
|
+
label?: string;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Optgroup element attributes
|
|
487
|
+
*/
|
|
488
|
+
export interface OptgroupAttributes extends BaseElementAttributes {
|
|
489
|
+
disabled?: boolean;
|
|
490
|
+
label?: string;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Table element attributes
|
|
495
|
+
*/
|
|
496
|
+
export interface TableAttributes extends BaseElementAttributes {
|
|
497
|
+
border?: number | string;
|
|
498
|
+
cellPadding?: number | string;
|
|
499
|
+
cellSpacing?: number | string;
|
|
500
|
+
width?: number | string;
|
|
501
|
+
summary?: string;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Table cell attributes (td, th)
|
|
506
|
+
*/
|
|
507
|
+
export interface TableCellAttributes extends BaseElementAttributes {
|
|
508
|
+
colSpan?: number;
|
|
509
|
+
colspan?: number; // alias
|
|
510
|
+
rowSpan?: number;
|
|
511
|
+
rowspan?: number; // alias
|
|
512
|
+
headers?: string;
|
|
513
|
+
scope?: 'row' | 'col' | 'rowgroup' | 'colgroup';
|
|
514
|
+
abbr?: string;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Iframe element attributes
|
|
519
|
+
*/
|
|
520
|
+
export interface IframeAttributes extends BaseElementAttributes {
|
|
521
|
+
src?: string;
|
|
522
|
+
srcDoc?: string;
|
|
523
|
+
srcdoc?: string; // alias
|
|
524
|
+
name?: string;
|
|
525
|
+
width?: number | string;
|
|
526
|
+
height?: number | string;
|
|
527
|
+
sandbox?: string;
|
|
528
|
+
allow?: string;
|
|
529
|
+
allowFullScreen?: boolean;
|
|
530
|
+
allowfullscreen?: boolean; // alias
|
|
531
|
+
loading?: 'lazy' | 'eager';
|
|
532
|
+
referrerPolicy?: ReferrerPolicy;
|
|
533
|
+
|
|
534
|
+
// Event handlers
|
|
535
|
+
onLoad?: string | ((event: Event) => void);
|
|
536
|
+
onError?: string | ((event: Event) => void);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Video element attributes
|
|
541
|
+
*/
|
|
542
|
+
export interface VideoAttributes extends BaseElementAttributes {
|
|
543
|
+
src?: string;
|
|
544
|
+
poster?: string;
|
|
545
|
+
width?: number | string;
|
|
546
|
+
height?: number | string;
|
|
547
|
+
autoPlay?: boolean;
|
|
548
|
+
autoplay?: boolean; // alias
|
|
549
|
+
controls?: boolean;
|
|
550
|
+
loop?: boolean;
|
|
551
|
+
muted?: boolean;
|
|
552
|
+
playsInline?: boolean;
|
|
553
|
+
playsinline?: boolean; // alias
|
|
554
|
+
preload?: 'none' | 'metadata' | 'auto' | '';
|
|
555
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
556
|
+
|
|
557
|
+
// Event handlers
|
|
558
|
+
onPlay?: string | ((event: Event) => void);
|
|
559
|
+
onPause?: string | ((event: Event) => void);
|
|
560
|
+
onEnded?: string | ((event: Event) => void);
|
|
561
|
+
onLoadedMetadata?: string | ((event: Event) => void);
|
|
562
|
+
onTimeUpdate?: string | ((event: Event) => void);
|
|
563
|
+
onVolumeChange?: string | ((event: Event) => void);
|
|
564
|
+
onError?: string | ((event: Event) => void);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Audio element attributes
|
|
569
|
+
*/
|
|
570
|
+
export interface AudioAttributes extends BaseElementAttributes {
|
|
571
|
+
src?: string;
|
|
572
|
+
autoPlay?: boolean;
|
|
573
|
+
autoplay?: boolean; // alias
|
|
574
|
+
controls?: boolean;
|
|
575
|
+
loop?: boolean;
|
|
576
|
+
muted?: boolean;
|
|
577
|
+
preload?: 'none' | 'metadata' | 'auto' | '';
|
|
578
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
579
|
+
|
|
580
|
+
// Event handlers
|
|
581
|
+
onPlay?: string | ((event: Event) => void);
|
|
582
|
+
onPause?: string | ((event: Event) => void);
|
|
583
|
+
onEnded?: string | ((event: Event) => void);
|
|
584
|
+
onLoadedMetadata?: string | ((event: Event) => void);
|
|
585
|
+
onTimeUpdate?: string | ((event: Event) => void);
|
|
586
|
+
onVolumeChange?: string | ((event: Event) => void);
|
|
587
|
+
onError?: string | ((event: Event) => void);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Source element attributes (void element)
|
|
592
|
+
*/
|
|
593
|
+
export interface SourceAttributes extends GlobalHTMLAttributes {
|
|
594
|
+
src?: string;
|
|
595
|
+
srcSet?: string;
|
|
596
|
+
srcset?: string; // alias
|
|
597
|
+
type?: string;
|
|
598
|
+
media?: string;
|
|
599
|
+
sizes?: string;
|
|
600
|
+
width?: number;
|
|
601
|
+
height?: number;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Track element attributes (void element)
|
|
606
|
+
*/
|
|
607
|
+
export interface TrackAttributes extends GlobalHTMLAttributes {
|
|
608
|
+
kind?: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';
|
|
609
|
+
src?: string;
|
|
610
|
+
srcLang?: string;
|
|
611
|
+
srclang?: string; // alias
|
|
612
|
+
label?: string;
|
|
613
|
+
default?: boolean;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Canvas element attributes
|
|
618
|
+
*/
|
|
619
|
+
export interface CanvasAttributes extends BaseElementAttributes {
|
|
620
|
+
width?: number | string;
|
|
621
|
+
height?: number | string;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Link element attributes (void element)
|
|
626
|
+
*/
|
|
627
|
+
export interface LinkAttributes extends GlobalHTMLAttributes {
|
|
628
|
+
href?: string;
|
|
629
|
+
rel?: string;
|
|
630
|
+
type?: string;
|
|
631
|
+
media?: string;
|
|
632
|
+
as?: string;
|
|
633
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
634
|
+
integrity?: string;
|
|
635
|
+
referrerPolicy?: ReferrerPolicy;
|
|
636
|
+
sizes?: string;
|
|
637
|
+
disabled?: boolean;
|
|
638
|
+
hrefLang?: string;
|
|
639
|
+
imageSrcSet?: string;
|
|
640
|
+
imageSizes?: string;
|
|
641
|
+
fetchPriority?: 'high' | 'low' | 'auto';
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Meta element attributes (void element)
|
|
646
|
+
*/
|
|
647
|
+
export interface MetaAttributes extends GlobalHTMLAttributes {
|
|
648
|
+
name?: string;
|
|
649
|
+
content?: string;
|
|
650
|
+
httpEquiv?: string;
|
|
651
|
+
'http-equiv'?: string; // alias
|
|
652
|
+
charset?: string;
|
|
653
|
+
property?: string;
|
|
654
|
+
media?: string;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Script element attributes
|
|
659
|
+
*/
|
|
660
|
+
export interface ScriptAttributes extends BaseElementAttributes {
|
|
661
|
+
src?: string;
|
|
662
|
+
type?: string;
|
|
663
|
+
async?: boolean;
|
|
664
|
+
defer?: boolean;
|
|
665
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
666
|
+
integrity?: string;
|
|
667
|
+
noModule?: boolean;
|
|
668
|
+
nomodule?: boolean; // alias
|
|
669
|
+
referrerPolicy?: ReferrerPolicy;
|
|
670
|
+
blocking?: string;
|
|
671
|
+
fetchPriority?: 'high' | 'low' | 'auto';
|
|
672
|
+
|
|
673
|
+
// Event handlers
|
|
674
|
+
onLoad?: string | ((event: Event) => void);
|
|
675
|
+
onError?: string | ((event: Event) => void);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Style element attributes
|
|
680
|
+
*/
|
|
681
|
+
export interface StyleAttributes extends BaseElementAttributes {
|
|
682
|
+
type?: string;
|
|
683
|
+
media?: string;
|
|
684
|
+
nonce?: string;
|
|
685
|
+
blocking?: string;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Progress element attributes
|
|
690
|
+
*/
|
|
691
|
+
export interface ProgressAttributes extends BaseElementAttributes {
|
|
692
|
+
value?: number;
|
|
693
|
+
max?: number;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Meter element attributes
|
|
698
|
+
*/
|
|
699
|
+
export interface MeterAttributes extends BaseElementAttributes {
|
|
700
|
+
value?: number;
|
|
701
|
+
min?: number;
|
|
702
|
+
max?: number;
|
|
703
|
+
low?: number;
|
|
704
|
+
high?: number;
|
|
705
|
+
optimum?: number;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Details element attributes
|
|
710
|
+
*/
|
|
711
|
+
export interface DetailsAttributes extends BaseElementAttributes {
|
|
712
|
+
open?: boolean;
|
|
713
|
+
onToggle?: string | ((event: Event) => void);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Dialog element attributes
|
|
718
|
+
*/
|
|
719
|
+
export interface DialogAttributes extends BaseElementAttributes {
|
|
720
|
+
open?: boolean;
|
|
721
|
+
onClose?: string | ((event: Event) => void);
|
|
722
|
+
onCancel?: string | ((event: Event) => void);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Time element attributes
|
|
727
|
+
*/
|
|
728
|
+
export interface TimeAttributes extends BaseElementAttributes {
|
|
729
|
+
dateTime?: string;
|
|
730
|
+
datetime?: string; // alias
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Output element attributes
|
|
735
|
+
*/
|
|
736
|
+
export interface OutputAttributes extends BaseElementAttributes {
|
|
737
|
+
htmlFor?: string;
|
|
738
|
+
for?: string; // alias
|
|
739
|
+
form?: string;
|
|
740
|
+
name?: string;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Fieldset element attributes
|
|
745
|
+
*/
|
|
746
|
+
export interface FieldsetAttributes extends BaseElementAttributes {
|
|
747
|
+
disabled?: boolean;
|
|
748
|
+
form?: string;
|
|
749
|
+
name?: string;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Legend element attributes
|
|
754
|
+
*/
|
|
755
|
+
export interface LegendAttributes extends BaseElementAttributes {}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Datalist element attributes
|
|
759
|
+
*/
|
|
760
|
+
export interface DatalistAttributes extends BaseElementAttributes {}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* Col element attributes (void element)
|
|
764
|
+
*/
|
|
765
|
+
export interface ColAttributes extends GlobalHTMLAttributes {
|
|
766
|
+
span?: number;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* Colgroup element attributes
|
|
771
|
+
*/
|
|
772
|
+
export interface ColgroupAttributes extends BaseElementAttributes {
|
|
773
|
+
span?: number;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Area element attributes (void element)
|
|
778
|
+
*/
|
|
779
|
+
export interface AreaAttributes extends GlobalHTMLAttributes, GlobalEventHandlers {
|
|
780
|
+
alt?: string;
|
|
781
|
+
coords?: string;
|
|
782
|
+
download?: string | boolean;
|
|
783
|
+
href?: string;
|
|
784
|
+
hrefLang?: string;
|
|
785
|
+
ping?: string;
|
|
786
|
+
referrerPolicy?: ReferrerPolicy;
|
|
787
|
+
rel?: string;
|
|
788
|
+
shape?: 'rect' | 'circle' | 'poly' | 'default';
|
|
789
|
+
target?: '_self' | '_blank' | '_parent' | '_top' | string;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Map element attributes
|
|
794
|
+
*/
|
|
795
|
+
export interface MapAttributes extends BaseElementAttributes {
|
|
796
|
+
name?: string;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Embed element attributes (void element)
|
|
801
|
+
*/
|
|
802
|
+
export interface EmbedAttributes extends GlobalHTMLAttributes, GlobalEventHandlers {
|
|
803
|
+
src?: string;
|
|
804
|
+
type?: string;
|
|
805
|
+
width?: number | string;
|
|
806
|
+
height?: number | string;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Object element attributes
|
|
811
|
+
*/
|
|
812
|
+
export interface ObjectAttributes extends BaseElementAttributes {
|
|
813
|
+
data?: string;
|
|
814
|
+
type?: string;
|
|
815
|
+
name?: string;
|
|
816
|
+
useMap?: string;
|
|
817
|
+
form?: string;
|
|
818
|
+
width?: number | string;
|
|
819
|
+
height?: number | string;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Param element attributes (void element - deprecated but still supported)
|
|
824
|
+
*/
|
|
825
|
+
export interface ParamAttributes extends GlobalHTMLAttributes {
|
|
826
|
+
name?: string;
|
|
827
|
+
value?: string;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Blockquote element attributes
|
|
832
|
+
*/
|
|
833
|
+
export interface BlockquoteAttributes extends BaseElementAttributes {
|
|
834
|
+
cite?: string;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Q element attributes
|
|
839
|
+
*/
|
|
840
|
+
export interface QAttributes extends BaseElementAttributes {
|
|
841
|
+
cite?: string;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Ins/Del element attributes
|
|
846
|
+
*/
|
|
847
|
+
export interface InsDelAttributes extends BaseElementAttributes {
|
|
848
|
+
cite?: string;
|
|
849
|
+
dateTime?: string;
|
|
850
|
+
datetime?: string; // alias
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Referrer policy type
|
|
855
|
+
*/
|
|
856
|
+
export type ReferrerPolicy =
|
|
857
|
+
| 'no-referrer'
|
|
858
|
+
| 'no-referrer-when-downgrade'
|
|
859
|
+
| 'origin'
|
|
860
|
+
| 'origin-when-cross-origin'
|
|
861
|
+
| 'same-origin'
|
|
862
|
+
| 'strict-origin'
|
|
863
|
+
| 'strict-origin-when-cross-origin'
|
|
864
|
+
| 'unsafe-url'
|
|
865
|
+
| '';
|
|
866
|
+
|
|
867
|
+
// ============================================================================
|
|
868
|
+
// Void Element Tag Names
|
|
869
|
+
// ============================================================================
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* HTML void elements that cannot have children.
|
|
873
|
+
*/
|
|
874
|
+
export type VoidElementTagNames =
|
|
875
|
+
| 'area'
|
|
876
|
+
| 'base'
|
|
877
|
+
| 'br'
|
|
878
|
+
| 'col'
|
|
879
|
+
| 'embed'
|
|
880
|
+
| 'hr'
|
|
881
|
+
| 'img'
|
|
882
|
+
| 'input'
|
|
883
|
+
| 'link'
|
|
884
|
+
| 'meta'
|
|
885
|
+
| 'param'
|
|
886
|
+
| 'source'
|
|
887
|
+
| 'track'
|
|
888
|
+
| 'wbr';
|
|
889
|
+
|
|
890
|
+
// ============================================================================
|
|
891
|
+
// HTML Element Attribute Map
|
|
892
|
+
// ============================================================================
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Maps HTML tag names to their specific attribute interfaces.
|
|
896
|
+
*/
|
|
897
|
+
export interface HTMLElementAttributeMap {
|
|
898
|
+
// Interactive elements
|
|
899
|
+
a: AnchorAttributes;
|
|
900
|
+
button: ButtonAttributes;
|
|
901
|
+
input: InputAttributes;
|
|
902
|
+
select: SelectAttributes;
|
|
903
|
+
textarea: TextareaAttributes;
|
|
904
|
+
label: LabelAttributes;
|
|
905
|
+
option: OptionAttributes;
|
|
906
|
+
optgroup: OptgroupAttributes;
|
|
907
|
+
output: OutputAttributes;
|
|
908
|
+
datalist: DatalistAttributes;
|
|
909
|
+
|
|
910
|
+
// Form elements
|
|
911
|
+
form: FormAttributes;
|
|
912
|
+
fieldset: FieldsetAttributes;
|
|
913
|
+
legend: LegendAttributes;
|
|
914
|
+
|
|
915
|
+
// Media elements
|
|
916
|
+
img: ImgAttributes;
|
|
917
|
+
video: VideoAttributes;
|
|
918
|
+
audio: AudioAttributes;
|
|
919
|
+
source: SourceAttributes;
|
|
920
|
+
track: TrackAttributes;
|
|
921
|
+
canvas: CanvasAttributes;
|
|
922
|
+
picture: BaseElementAttributes;
|
|
923
|
+
|
|
924
|
+
// Embedded content
|
|
925
|
+
iframe: IframeAttributes;
|
|
926
|
+
embed: EmbedAttributes;
|
|
927
|
+
object: ObjectAttributes;
|
|
928
|
+
param: ParamAttributes;
|
|
929
|
+
map: MapAttributes;
|
|
930
|
+
area: AreaAttributes;
|
|
931
|
+
|
|
932
|
+
// Document metadata
|
|
933
|
+
link: LinkAttributes;
|
|
934
|
+
meta: MetaAttributes;
|
|
935
|
+
base: GlobalHTMLAttributes;
|
|
936
|
+
style: StyleAttributes;
|
|
937
|
+
script: ScriptAttributes;
|
|
938
|
+
noscript: BaseElementAttributes;
|
|
939
|
+
|
|
940
|
+
// Table elements
|
|
941
|
+
table: TableAttributes;
|
|
942
|
+
caption: BaseElementAttributes;
|
|
943
|
+
thead: BaseElementAttributes;
|
|
944
|
+
tbody: BaseElementAttributes;
|
|
945
|
+
tfoot: BaseElementAttributes;
|
|
946
|
+
tr: BaseElementAttributes;
|
|
947
|
+
td: TableCellAttributes;
|
|
948
|
+
th: TableCellAttributes;
|
|
949
|
+
col: ColAttributes;
|
|
950
|
+
colgroup: ColgroupAttributes;
|
|
951
|
+
|
|
952
|
+
// Progress/Meter
|
|
953
|
+
progress: ProgressAttributes;
|
|
954
|
+
meter: MeterAttributes;
|
|
955
|
+
|
|
956
|
+
// Interactive elements
|
|
957
|
+
details: DetailsAttributes;
|
|
958
|
+
summary: BaseElementAttributes;
|
|
959
|
+
dialog: DialogAttributes;
|
|
960
|
+
|
|
961
|
+
// Text elements
|
|
962
|
+
time: TimeAttributes;
|
|
963
|
+
blockquote: BlockquoteAttributes;
|
|
964
|
+
q: QAttributes;
|
|
965
|
+
ins: InsDelAttributes;
|
|
966
|
+
del: InsDelAttributes;
|
|
967
|
+
|
|
968
|
+
// Void elements with only global attributes
|
|
969
|
+
br: GlobalHTMLAttributes;
|
|
970
|
+
hr: GlobalHTMLAttributes;
|
|
971
|
+
wbr: GlobalHTMLAttributes;
|
|
972
|
+
|
|
973
|
+
// Structural elements (all use base attributes)
|
|
974
|
+
div: BaseElementAttributes;
|
|
975
|
+
span: BaseElementAttributes;
|
|
976
|
+
p: BaseElementAttributes;
|
|
977
|
+
section: BaseElementAttributes;
|
|
978
|
+
article: BaseElementAttributes;
|
|
979
|
+
aside: BaseElementAttributes;
|
|
980
|
+
header: BaseElementAttributes;
|
|
981
|
+
footer: BaseElementAttributes;
|
|
982
|
+
main: BaseElementAttributes;
|
|
983
|
+
nav: BaseElementAttributes;
|
|
984
|
+
figure: BaseElementAttributes;
|
|
985
|
+
figcaption: BaseElementAttributes;
|
|
986
|
+
address: BaseElementAttributes;
|
|
987
|
+
hgroup: BaseElementAttributes;
|
|
988
|
+
search: BaseElementAttributes;
|
|
989
|
+
|
|
990
|
+
// Heading elements
|
|
991
|
+
h1: BaseElementAttributes;
|
|
992
|
+
h2: BaseElementAttributes;
|
|
993
|
+
h3: BaseElementAttributes;
|
|
994
|
+
h4: BaseElementAttributes;
|
|
995
|
+
h5: BaseElementAttributes;
|
|
996
|
+
h6: BaseElementAttributes;
|
|
997
|
+
|
|
998
|
+
// List elements
|
|
999
|
+
ul: BaseElementAttributes;
|
|
1000
|
+
ol: BaseElementAttributes;
|
|
1001
|
+
li: BaseElementAttributes;
|
|
1002
|
+
dl: BaseElementAttributes;
|
|
1003
|
+
dt: BaseElementAttributes;
|
|
1004
|
+
dd: BaseElementAttributes;
|
|
1005
|
+
menu: BaseElementAttributes;
|
|
1006
|
+
|
|
1007
|
+
// Text formatting elements
|
|
1008
|
+
em: BaseElementAttributes;
|
|
1009
|
+
strong: BaseElementAttributes;
|
|
1010
|
+
small: BaseElementAttributes;
|
|
1011
|
+
s: BaseElementAttributes;
|
|
1012
|
+
cite: BaseElementAttributes;
|
|
1013
|
+
dfn: BaseElementAttributes;
|
|
1014
|
+
abbr: BaseElementAttributes;
|
|
1015
|
+
ruby: BaseElementAttributes;
|
|
1016
|
+
rt: BaseElementAttributes;
|
|
1017
|
+
rp: BaseElementAttributes;
|
|
1018
|
+
data: BaseElementAttributes;
|
|
1019
|
+
code: BaseElementAttributes;
|
|
1020
|
+
var: BaseElementAttributes;
|
|
1021
|
+
samp: BaseElementAttributes;
|
|
1022
|
+
kbd: BaseElementAttributes;
|
|
1023
|
+
sub: BaseElementAttributes;
|
|
1024
|
+
sup: BaseElementAttributes;
|
|
1025
|
+
i: BaseElementAttributes;
|
|
1026
|
+
b: BaseElementAttributes;
|
|
1027
|
+
u: BaseElementAttributes;
|
|
1028
|
+
mark: BaseElementAttributes;
|
|
1029
|
+
bdi: BaseElementAttributes;
|
|
1030
|
+
bdo: BaseElementAttributes;
|
|
1031
|
+
pre: BaseElementAttributes;
|
|
1032
|
+
|
|
1033
|
+
// Document structure (typically not used in components)
|
|
1034
|
+
html: BaseElementAttributes;
|
|
1035
|
+
head: BaseElementAttributes;
|
|
1036
|
+
body: BaseElementAttributes;
|
|
1037
|
+
title: BaseElementAttributes;
|
|
1038
|
+
|
|
1039
|
+
// Other elements
|
|
1040
|
+
template: BaseElementAttributes;
|
|
1041
|
+
slot: BaseElementAttributes;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// ============================================================================
|
|
1045
|
+
// Strict Coherent Element Type
|
|
1046
|
+
// ============================================================================
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* Strict element type with per-element attribute validation.
|
|
1050
|
+
*
|
|
1051
|
+
* Use this type for strict type checking:
|
|
1052
|
+
* - Catches attribute typos (classname vs className)
|
|
1053
|
+
* - Catches element-specific attribute misuse (checked on div)
|
|
1054
|
+
* - Prevents children on void elements
|
|
1055
|
+
*
|
|
1056
|
+
* For permissive typing (backward compatibility), use CoherentElement from index.d.ts.
|
|
1057
|
+
*
|
|
1058
|
+
* @example
|
|
1059
|
+
* ```typescript
|
|
1060
|
+
* // Valid - input can have checked
|
|
1061
|
+
* const checkbox: StrictCoherentElement = {
|
|
1062
|
+
* input: { type: 'checkbox', checked: true }
|
|
1063
|
+
* };
|
|
1064
|
+
*
|
|
1065
|
+
* // Error - div cannot have checked
|
|
1066
|
+
* const invalid: StrictCoherentElement = {
|
|
1067
|
+
* div: { checked: true } // Type error!
|
|
1068
|
+
* };
|
|
1069
|
+
*
|
|
1070
|
+
* // Error - img cannot have children
|
|
1071
|
+
* const invalidImg: StrictCoherentElement = {
|
|
1072
|
+
* img: { src: 'foo.png', children: [{ span: {} }] } // Type error!
|
|
1073
|
+
* };
|
|
1074
|
+
* ```
|
|
1075
|
+
*/
|
|
1076
|
+
export type StrictCoherentElement = {
|
|
1077
|
+
[K in keyof HTMLElementAttributeMap]?: K extends VoidElementTagNames
|
|
1078
|
+
? Omit<HTMLElementAttributeMap[K], 'children'>
|
|
1079
|
+
: HTMLElementAttributeMap[K];
|
|
1080
|
+
};
|