@typesafe-html5/typescript 0.2.58

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 (117) hide show
  1. package/README.md +166 -0
  2. package/block/article/article.ts +506 -0
  3. package/block/aside/aside.ts +522 -0
  4. package/block/audio/audio.ts +506 -0
  5. package/block/blockquote/blockquote.ts +522 -0
  6. package/block/body/body.ts +458 -0
  7. package/block/canvas/canvas.ts +538 -0
  8. package/block/caption/caption.ts +506 -0
  9. package/block/colgroup/colgroup.ts +154 -0
  10. package/block/datalist/datalist.ts +506 -0
  11. package/block/dd/dd.ts +506 -0
  12. package/block/del/del.ts +538 -0
  13. package/block/details/details.ts +586 -0
  14. package/block/dialog/dialog.ts +586 -0
  15. package/block/div/div.ts +586 -0
  16. package/block/dl/dl.ts +506 -0
  17. package/block/dt/dt.ts +506 -0
  18. package/block/embed/embed.ts +317 -0
  19. package/block/fieldset/fieldset.ts +570 -0
  20. package/block/figcaption/figcaption.ts +506 -0
  21. package/block/figure/figure.ts +506 -0
  22. package/block/footer/footer.ts +522 -0
  23. package/block/form/form.ts +490 -0
  24. package/block/h1/h1.ts +490 -0
  25. package/block/h2/h2.ts +490 -0
  26. package/block/h3/h3.ts +490 -0
  27. package/block/h4/h4.ts +490 -0
  28. package/block/h5/h5.ts +490 -0
  29. package/block/h6/h6.ts +490 -0
  30. package/block/header/header.ts +298 -0
  31. package/block/hgroup/hgroup.ts +506 -0
  32. package/block/hr/hr.ts +189 -0
  33. package/block/html/html.ts +106 -0
  34. package/block/iframe/iframe.ts +538 -0
  35. package/block/ins/ins.ts +538 -0
  36. package/block/legend/legend.ts +506 -0
  37. package/block/li/li.ts +602 -0
  38. package/block/main/main.ts +538 -0
  39. package/block/map/map.ts +522 -0
  40. package/block/menu/menu.ts +554 -0
  41. package/block/nav/nav.ts +554 -0
  42. package/block/noscript/noscript.ts +282 -0
  43. package/block/object/object.ts +618 -0
  44. package/block/ol/ol.ts +618 -0
  45. package/block/optgroup/optgroup.ts +522 -0
  46. package/block/option/option.ts +618 -0
  47. package/block/p/p.ts +506 -0
  48. package/block/picture/picture.ts +506 -0
  49. package/block/pre/pre.ts +506 -0
  50. package/block/section/section.ts +538 -0
  51. package/block/summary/summary.ts +570 -0
  52. package/block/table/table.ts +570 -0
  53. package/block/tbody/tbody.ts +506 -0
  54. package/block/td/td.ts +666 -0
  55. package/block/template/template.ts +506 -0
  56. package/block/tfoot/tfoot.ts +506 -0
  57. package/block/th/th.ts +682 -0
  58. package/block/thead/thead.ts +506 -0
  59. package/block/tr/tr.ts +682 -0
  60. package/block/ul/ul.ts +570 -0
  61. package/block/video/video.ts +666 -0
  62. package/index.ts +126 -0
  63. package/inline/a/a.ts +682 -0
  64. package/inline/abbr/abbr.ts +490 -0
  65. package/inline/address/address.ts +474 -0
  66. package/inline/b/b.ts +506 -0
  67. package/inline/bdi/bdi.ts +490 -0
  68. package/inline/bdo/bdo.ts +506 -0
  69. package/inline/button/button.ts +826 -0
  70. package/inline/cite/cite.ts +506 -0
  71. package/inline/code/code.ts +506 -0
  72. package/inline/data/data.ts +522 -0
  73. package/inline/dfn/dfn.ts +506 -0
  74. package/inline/em/em.ts +506 -0
  75. package/inline/i/i.ts +506 -0
  76. package/inline/img/img.ts +445 -0
  77. package/inline/input/input.ts +1197 -0
  78. package/inline/kbd/kbd.ts +506 -0
  79. package/inline/label/label.ts +538 -0
  80. package/inline/mark/mark.ts +506 -0
  81. package/inline/meter/meter.ts +554 -0
  82. package/inline/output/output.ts +426 -0
  83. package/inline/progress/progress.ts +490 -0
  84. package/inline/q/q.ts +522 -0
  85. package/inline/rp/rp.ts +506 -0
  86. package/inline/rt/rt.ts +506 -0
  87. package/inline/ruby/ruby.ts +506 -0
  88. package/inline/s/s.ts +506 -0
  89. package/inline/samp/samp.ts +506 -0
  90. package/inline/select/select.ts +810 -0
  91. package/inline/slot/slot.ts +522 -0
  92. package/inline/small/small.ts +506 -0
  93. package/inline/span/span.ts +506 -0
  94. package/inline/strong/strong.ts +506 -0
  95. package/inline/sub/sub.ts +506 -0
  96. package/inline/sup/sup.ts +506 -0
  97. package/inline/svg/svg.ts +618 -0
  98. package/inline/textarea/textarea.ts +874 -0
  99. package/inline/time/time.ts +522 -0
  100. package/inline/u/u.ts +506 -0
  101. package/inline/var/var.ts +506 -0
  102. package/package.json +32 -0
  103. package/tsconfig.json +26 -0
  104. package/void/area/area.ts +397 -0
  105. package/void/base/base.ts +61 -0
  106. package/void/br/br.ts +77 -0
  107. package/void/col/col.ts +77 -0
  108. package/void/head/head.ts +58 -0
  109. package/void/link/link.ts +253 -0
  110. package/void/meta/meta.ts +157 -0
  111. package/void/param/param.ts +93 -0
  112. package/void/script/script.ts +250 -0
  113. package/void/source/source.ts +125 -0
  114. package/void/style/style.ts +154 -0
  115. package/void/title/title.ts +58 -0
  116. package/void/track/track.ts +157 -0
  117. package/void/wbr/wbr.ts +61 -0
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # TypeScript HTML Element Classes
2
+
3
+ This directory contains auto-generated TypeScript classes for creating HTML elements with a fluent, type-safe API. Each class provides:
4
+
5
+ - Constructor with optional props
6
+ - Chainable setter methods for all attributes
7
+ - Type-safe property interfaces
8
+ - Automatic attribute handling (including null/undefined removal)
9
+
10
+ ## Installation
11
+
12
+ This is a static NPM package, providing just the TypeScript classes.
13
+
14
+ ```bash
15
+ npm install @typesafe-html5/typescript
16
+ # or
17
+ yarn add @typesafe-html5/typescript
18
+ # or
19
+ pnpm add @typesafe-html5/typescript
20
+ ```
21
+
22
+ ## Importing Elements
23
+
24
+ You can import individual elements from their specific files:
25
+
26
+ ```typescript
27
+ import { Input } from './inline/input/input';
28
+ import { Button } from './inline/button/button';
29
+ ```
30
+
31
+ Or import all elements from the main index file for convenience:
32
+
33
+ ```typescript
34
+ import { Input, Button, Div, Form } from './index';
35
+ ```
36
+
37
+ ## Usage Examples
38
+
39
+ ### Creating a Simple Input Element
40
+
41
+ ```typescript
42
+ import { Input } from './inline/input/input';
43
+
44
+ const input = new Input();
45
+ document.body.appendChild(input.getElement());
46
+ ```
47
+
48
+ ### Setting Properties via Constructor
49
+
50
+ ```typescript
51
+ import { Input } from './inline/input/input';
52
+
53
+ const input = new Input({
54
+ type: 'email',
55
+ placeholder: 'Enter your email',
56
+ required: true,
57
+ 'aria-label': 'Email input'
58
+ });
59
+ document.body.appendChild(input.getElement());
60
+ ```
61
+
62
+ ### Using Chainable Setter Methods
63
+
64
+ ```typescript
65
+ import { Input } from './inline/input/input';
66
+
67
+ const input = new Input();
68
+ input.setType('password')
69
+ .setPlaceholder('Enter password')
70
+ .setRequired(true)
71
+ .setAriaLabel('Password input');
72
+ document.body.appendChild(input.getElement());
73
+ ```
74
+
75
+ ### Creating a Form with Multiple Elements
76
+
77
+ ```typescript
78
+ import { Form } from './block/form/form';
79
+ import { Input } from './inline/input/input';
80
+ import { Button } from './inline/button/button';
81
+
82
+ const form = new Form({
83
+ action: '/submit',
84
+ method: 'post'
85
+ });
86
+
87
+ const usernameInput = new Input({
88
+ name: 'username',
89
+ type: 'text',
90
+ placeholder: 'Username'
91
+ });
92
+
93
+ const submitButton = new Button({
94
+ type: 'submit'
95
+ }).setChildren('Submit');
96
+
97
+ form.setChildren([usernameInput.getElement(), submitButton.getElement()]);
98
+ document.body.appendChild(form.getElement());
99
+ ```
100
+
101
+ ### Handling Events and Dynamic Updates
102
+
103
+ ```typescript
104
+ import { Button } from './inline/button/button';
105
+ import { Div } from './block/div/div';
106
+
107
+ const button = new Button({ type: 'button' }).setChildren('Click me');
108
+ const counterDiv = new Div().setChildren('Clicks: 0');
109
+
110
+ let count = 0;
111
+ button.getElement().addEventListener('click', () => {
112
+ count++;
113
+ counterDiv.setChildren(`Clicks: ${count}`);
114
+ });
115
+
116
+ document.body.appendChild(button.getElement());
117
+ document.body.appendChild(counterDiv.getElement());
118
+ ```
119
+
120
+ ### Working with Attributes (Including Removal)
121
+
122
+ ```typescript
123
+ import { Input } from './inline/input/input';
124
+
125
+ const input = new Input({
126
+ disabled: true,
127
+ value: 'Initial value'
128
+ });
129
+
130
+ // Later, enable the input and clear value
131
+ input.setDisabled(false)
132
+ .setValue(null); // Removes the value attribute
133
+
134
+ document.body.appendChild(input.getElement());
135
+ ```
136
+
137
+ ### Creating Complex Nested Structures
138
+
139
+ ```typescript
140
+ import { Div } from './block/div/div';
141
+ import { H1 } from './block/h1/h1';
142
+ import { P } from './block/p/p';
143
+ import { A } from './inline/a/a';
144
+
145
+ const container = new Div({ className: 'container' });
146
+
147
+ const header = new H1().setChildren('Welcome');
148
+
149
+ const paragraph = new P().setChildren([
150
+ 'Visit our ',
151
+ new A({ href: 'https://example.com' }).setChildren('website'),
152
+ ' for more information.'
153
+ ]);
154
+
155
+ container.setChildren([header.getElement(), paragraph.getElement()]);
156
+ document.body.appendChild(container.getElement());
157
+ ```
158
+
159
+ ## API Reference
160
+
161
+ - **Constructor**: `new ElementClass(props?)` - Creates element with optional initial props
162
+ - **Setters**: `setPropertyName(value)` - Chainable methods for all properties
163
+ - **getElement()**: Returns the underlying HTMLElement for DOM manipulation
164
+ - **setChildren()**: For elements that can contain children (block elements)
165
+
166
+ All setter methods accept flexible types including `null`/`undefined` to remove attributes.
@@ -0,0 +1,506 @@
1
+ /**
2
+ * THIS FILE IS AUTOGENERATED. DO NOT EDIT IT.
3
+ *
4
+ * @generated December 28, 2025 12:26:31
5
+ * @component Article
6
+ * @description
7
+ */
8
+
9
+ export interface ArticleProps {
10
+ /**
11
+ * Child content or elements
12
+ */
13
+ children?: string | HTMLElement | (string | HTMLElement)[];
14
+ /**
15
+ * specifies a shortcut key (or keys) to activate or focus an element
16
+ */
17
+ accesskey?: string | null | undefined;
18
+ /**
19
+ * Indicates whether assistive technologies should present the entire region as a whole when changes occur.
20
+ */
21
+ 'aria-atomic'?: 'false' | 'true' | boolean | null | undefined;
22
+ /**
23
+ * The aria-busy attribute is used to indicate whether an element is currently busy or not.
24
+ */
25
+ 'aria-busy'?: 'true' | 'false' | boolean | null | undefined;
26
+ /**
27
+ * Identifies the element(s) whose contents or presence are controlled by this element. Value is a list of IDs separated by a space
28
+ */
29
+ 'aria-controls'?: string | null | undefined;
30
+ /**
31
+ * Identifies the element(s) that describes the object. Value is a list of IDs separated by a space
32
+ */
33
+ 'aria-describedby'?: string | null | undefined;
34
+ /**
35
+ * References an element that provides additional details about the current element.
36
+ */
37
+ 'aria-details'?: string | null | undefined;
38
+ /**
39
+ * Defines keyboard shortcuts available for the element.
40
+ */
41
+ 'aria-keyshortcuts'?: string | null | undefined;
42
+ /**
43
+ * Identifies the element(s) that labels the current element. Value is a list of IDs separated by a space
44
+ */
45
+ 'aria-labelledby'?: string | null | undefined;
46
+ /**
47
+ * Defines how updates to the element should be announced to screen readers.
48
+ */
49
+ 'aria-live'?: 'off' | 'polite' | 'assertive' | null | undefined;
50
+ /**
51
+ * Establishes ownership relationships between elements. Value is a space-separated list of IDs.
52
+ */
53
+ 'aria-owns'?: string | null | undefined;
54
+ /**
55
+ * Indicates what content changes should be announced in a live region.
56
+ */
57
+ 'aria-relevant'?: 'additions' | 'removals' | 'text' | 'all' | 'additions text' | null | undefined;
58
+ /**
59
+ * Provides a human-readable custom role description for assistive technologies.
60
+ */
61
+ 'aria-roledescription'?: string | null | undefined;
62
+ /**
63
+ * Represents the autocapitalize behavior of the element
64
+ */
65
+ autocapitalize?: 'none' | 'sentences' | 'words' | 'characters' | null | undefined;
66
+ /**
67
+ * Indicates whether the element is hidden
68
+ */
69
+ autofocus?: boolean | null | undefined;
70
+ /**
71
+ * Indicates whether the element can be edited in place
72
+ */
73
+ contenteditable?: 'true' | 'false' | 'inherit' | boolean | null | undefined;
74
+ /**
75
+ * Represents the text direction of the element
76
+ */
77
+ dir?: 'ltr' | 'rtl' | 'auto' | null | undefined;
78
+ /**
79
+ * Indicates whether the element is draggable
80
+ */
81
+ draggable?: boolean | null | undefined;
82
+ /**
83
+ * Indicates whether the element is hidden
84
+ */
85
+ hidden?: boolean | null | undefined;
86
+ /**
87
+ * used to specify the data entry mode for an input. It helps guide on-screen keyboards (especially on mobile devices) to show the appropriate layout for the expected input type
88
+ */
89
+ inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'email' | 'tel' | 'url' | 'search' | null | undefined;
90
+ /**
91
+ * Specifies the primary language for the element's content
92
+ */
93
+ lang?: string | null | undefined;
94
+ /**
95
+ *
96
+ */
97
+ popover?: 'auto' | 'hint' | 'manual' | null | undefined;
98
+ /**
99
+ * Defines the semantic purpose of an element for assistive technologies.
100
+ */
101
+ role?: 'alert' | 'application' | 'article' | 'banner' | 'button' | 'checkbox' | 'complementary' | 'contentinfo' | 'dialog' | 'form' | 'grid' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'main' | 'menu' | 'menubar' | 'menuitem' | 'navigation' | 'none' | 'presentation' | 'radio' | 'region' | 'search' | 'status' | 'tab' | 'tablist' | 'tabpanel' | 'textbox' | 'toolbar' | 'tooltip' | null | undefined;
102
+ /**
103
+ * Represents a slot in a shadow DOM
104
+ */
105
+ slot?: string | null | undefined;
106
+ /**
107
+ * Represents the spellchecking behavior of the element
108
+ */
109
+ spellcheck?: 'true' | 'false' | boolean | null | undefined;
110
+ /**
111
+ * Represents the CSS inline style of the element
112
+ */
113
+ style?: string | null | undefined;
114
+ /**
115
+ * Represents a tab order of the element
116
+ */
117
+ tabindex?: number | null | undefined;
118
+ /**
119
+ * Represents a title or tooltip for the element
120
+ */
121
+ title?: string | null | undefined;
122
+ /**
123
+ * used to tell user agents whether the content should be translated.
124
+ */
125
+ translate?: 'yes' | 'no' | null | undefined;
126
+ }
127
+
128
+ /**
129
+ * Article -
130
+ */
131
+ export class Article {
132
+ private element: HTMLElement;
133
+
134
+ constructor(props: ArticleProps = {}) {
135
+ this.element = document.createElement('article');
136
+ this.applyProps(props);
137
+ }
138
+
139
+ private applyProps(props: ArticleProps): void {
140
+ if (props.children !== undefined) {
141
+ this.setChildren(props.children);
142
+ }
143
+ if (props.accesskey !== undefined) {
144
+ this.element.setAttribute('accesskey', String(props.accesskey));
145
+ }
146
+ if (props['aria-atomic'] !== undefined) {
147
+ this.setAriaAtomic(props['aria-atomic']);
148
+ }
149
+ if (props['aria-busy'] !== undefined) {
150
+ this.setAriaBusy(props['aria-busy']);
151
+ }
152
+ if (props['aria-controls'] !== undefined) {
153
+ this.element.setAttribute('aria-controls', String(props['aria-controls']));
154
+ }
155
+ if (props['aria-describedby'] !== undefined) {
156
+ this.element.setAttribute('aria-describedby', String(props['aria-describedby']));
157
+ }
158
+ if (props['aria-details'] !== undefined) {
159
+ this.element.setAttribute('aria-details', String(props['aria-details']));
160
+ }
161
+ if (props['aria-keyshortcuts'] !== undefined) {
162
+ this.element.setAttribute('aria-keyshortcuts', String(props['aria-keyshortcuts']));
163
+ }
164
+ if (props['aria-labelledby'] !== undefined) {
165
+ this.element.setAttribute('aria-labelledby', String(props['aria-labelledby']));
166
+ }
167
+ if (props['aria-live'] !== undefined) {
168
+ this.setAriaLive(props['aria-live']);
169
+ }
170
+ if (props['aria-owns'] !== undefined) {
171
+ this.element.setAttribute('aria-owns', String(props['aria-owns']));
172
+ }
173
+ if (props['aria-relevant'] !== undefined) {
174
+ this.setAriaRelevant(props['aria-relevant']);
175
+ }
176
+ if (props['aria-roledescription'] !== undefined) {
177
+ this.element.setAttribute('aria-roledescription', String(props['aria-roledescription']));
178
+ }
179
+ if (props.autocapitalize !== undefined) {
180
+ this.setAutocapitalize(props.autocapitalize);
181
+ }
182
+ if (props.autofocus !== undefined) {
183
+ this.element.setAttribute('autofocus', String(props.autofocus));
184
+ }
185
+ if (props.contenteditable !== undefined) {
186
+ this.setContenteditable(props.contenteditable);
187
+ }
188
+ if (props.dir !== undefined) {
189
+ this.setDir(props.dir);
190
+ }
191
+ if (props.draggable !== undefined) {
192
+ this.element.setAttribute('draggable', String(props.draggable));
193
+ }
194
+ if (props.hidden !== undefined) {
195
+ this.element.setAttribute('hidden', String(props.hidden));
196
+ }
197
+ if (props.inputmode !== undefined) {
198
+ this.setInputmode(props.inputmode);
199
+ }
200
+ if (props.lang !== undefined) {
201
+ this.element.setAttribute('lang', String(props.lang));
202
+ }
203
+ if (props.popover !== undefined) {
204
+ this.setPopover(props.popover);
205
+ }
206
+ if (props.role !== undefined) {
207
+ this.setRole(props.role);
208
+ }
209
+ if (props.slot !== undefined) {
210
+ this.element.setAttribute('slot', String(props.slot));
211
+ }
212
+ if (props.spellcheck !== undefined) {
213
+ this.setSpellcheck(props.spellcheck);
214
+ }
215
+ if (props.style !== undefined) {
216
+ this.element.setAttribute('style', String(props.style));
217
+ }
218
+ if (props.tabindex !== undefined) {
219
+ this.element.setAttribute('tabindex', String(props.tabindex));
220
+ }
221
+ if (props.title !== undefined) {
222
+ this.element.setAttribute('title', String(props.title));
223
+ }
224
+ if (props.translate !== undefined) {
225
+ this.setTranslate(props.translate);
226
+ }
227
+ }
228
+
229
+ setAccesskey(value: string | null | undefined): this {
230
+ if (value === null || value === undefined) {
231
+ this.element.removeAttribute('accesskey');
232
+ } else {
233
+ this.element.setAttribute('accesskey', String(value));
234
+ }
235
+ return this;
236
+ }
237
+
238
+ setAriaAtomic(value: 'false' | 'true' | boolean | null | undefined): this {
239
+ if (value === null || value === undefined) {
240
+ this.element.removeAttribute('aria-atomic');
241
+ } else {
242
+ this.element.setAttribute('aria-atomic', String(value));
243
+ }
244
+ return this;
245
+ }
246
+
247
+ setAriaBusy(value: 'true' | 'false' | boolean | null | undefined): this {
248
+ if (value === null || value === undefined) {
249
+ this.element.removeAttribute('aria-busy');
250
+ } else {
251
+ this.element.setAttribute('aria-busy', String(value));
252
+ }
253
+ return this;
254
+ }
255
+
256
+ setAriaControls(value: string | null | undefined): this {
257
+ if (value === null || value === undefined) {
258
+ this.element.removeAttribute('aria-controls');
259
+ } else {
260
+ this.element.setAttribute('aria-controls', String(value));
261
+ }
262
+ return this;
263
+ }
264
+
265
+ setAriaDescribedby(value: string | null | undefined): this {
266
+ if (value === null || value === undefined) {
267
+ this.element.removeAttribute('aria-describedby');
268
+ } else {
269
+ this.element.setAttribute('aria-describedby', String(value));
270
+ }
271
+ return this;
272
+ }
273
+
274
+ setAriaDetails(value: string | null | undefined): this {
275
+ if (value === null || value === undefined) {
276
+ this.element.removeAttribute('aria-details');
277
+ } else {
278
+ this.element.setAttribute('aria-details', String(value));
279
+ }
280
+ return this;
281
+ }
282
+
283
+ setAriaKeyshortcuts(value: string | null | undefined): this {
284
+ if (value === null || value === undefined) {
285
+ this.element.removeAttribute('aria-keyshortcuts');
286
+ } else {
287
+ this.element.setAttribute('aria-keyshortcuts', String(value));
288
+ }
289
+ return this;
290
+ }
291
+
292
+ setAriaLabelledby(value: string | null | undefined): this {
293
+ if (value === null || value === undefined) {
294
+ this.element.removeAttribute('aria-labelledby');
295
+ } else {
296
+ this.element.setAttribute('aria-labelledby', String(value));
297
+ }
298
+ return this;
299
+ }
300
+
301
+ setAriaLive(value: 'off' | 'polite' | 'assertive' | null | undefined): this {
302
+ if (value === null || value === undefined) {
303
+ this.element.removeAttribute('aria-live');
304
+ } else {
305
+ this.element.setAttribute('aria-live', String(value));
306
+ }
307
+ return this;
308
+ }
309
+
310
+ setAriaOwns(value: string | null | undefined): this {
311
+ if (value === null || value === undefined) {
312
+ this.element.removeAttribute('aria-owns');
313
+ } else {
314
+ this.element.setAttribute('aria-owns', String(value));
315
+ }
316
+ return this;
317
+ }
318
+
319
+ setAriaRelevant(value: 'additions' | 'removals' | 'text' | 'all' | 'additions text' | null | undefined): this {
320
+ if (value === null || value === undefined) {
321
+ this.element.removeAttribute('aria-relevant');
322
+ } else {
323
+ this.element.setAttribute('aria-relevant', String(value));
324
+ }
325
+ return this;
326
+ }
327
+
328
+ setAriaRoledescription(value: string | null | undefined): this {
329
+ if (value === null || value === undefined) {
330
+ this.element.removeAttribute('aria-roledescription');
331
+ } else {
332
+ this.element.setAttribute('aria-roledescription', String(value));
333
+ }
334
+ return this;
335
+ }
336
+
337
+ setAutocapitalize(value: 'none' | 'sentences' | 'words' | 'characters' | null | undefined): this {
338
+ if (value === null || value === undefined) {
339
+ this.element.removeAttribute('autocapitalize');
340
+ } else {
341
+ this.element.setAttribute('autocapitalize', String(value));
342
+ }
343
+ return this;
344
+ }
345
+
346
+ setAutofocus(value: boolean | null | undefined): this {
347
+ if (value === true) {
348
+ this.element.setAttribute('autofocus', '');
349
+ } else {
350
+ this.element.removeAttribute('autofocus');
351
+ }
352
+ return this;
353
+ }
354
+
355
+ setContenteditable(value: 'true' | 'false' | 'inherit' | boolean | null | undefined): this {
356
+ if (value === null || value === undefined) {
357
+ this.element.removeAttribute('contenteditable');
358
+ } else {
359
+ this.element.setAttribute('contenteditable', String(value));
360
+ }
361
+ return this;
362
+ }
363
+
364
+ setDir(value: 'ltr' | 'rtl' | 'auto' | null | undefined): this {
365
+ if (value === null || value === undefined) {
366
+ this.element.removeAttribute('dir');
367
+ } else {
368
+ this.element.setAttribute('dir', String(value));
369
+ }
370
+ return this;
371
+ }
372
+
373
+ setDraggable(value: boolean | null | undefined): this {
374
+ if (value === true) {
375
+ this.element.setAttribute('draggable', '');
376
+ } else {
377
+ this.element.removeAttribute('draggable');
378
+ }
379
+ return this;
380
+ }
381
+
382
+ setHidden(value: boolean | null | undefined): this {
383
+ if (value === true) {
384
+ this.element.setAttribute('hidden', '');
385
+ } else {
386
+ this.element.removeAttribute('hidden');
387
+ }
388
+ return this;
389
+ }
390
+
391
+ setInputmode(value: 'none' | 'text' | 'decimal' | 'numeric' | 'email' | 'tel' | 'url' | 'search' | null | undefined): this {
392
+ if (value === null || value === undefined) {
393
+ this.element.removeAttribute('inputmode');
394
+ } else {
395
+ this.element.setAttribute('inputmode', String(value));
396
+ }
397
+ return this;
398
+ }
399
+
400
+ setLang(value: string | null | undefined): this {
401
+ if (value === null || value === undefined) {
402
+ this.element.removeAttribute('lang');
403
+ } else {
404
+ this.element.setAttribute('lang', String(value));
405
+ }
406
+ return this;
407
+ }
408
+
409
+ setPopover(value: 'auto' | 'hint' | 'manual' | null | undefined): this {
410
+ if (value === null || value === undefined) {
411
+ this.element.removeAttribute('popover');
412
+ } else {
413
+ this.element.setAttribute('popover', String(value));
414
+ }
415
+ return this;
416
+ }
417
+
418
+ setRole(value: 'alert' | 'application' | 'article' | 'banner' | 'button' | 'checkbox' | 'complementary' | 'contentinfo' | 'dialog' | 'form' | 'grid' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'main' | 'menu' | 'menubar' | 'menuitem' | 'navigation' | 'none' | 'presentation' | 'radio' | 'region' | 'search' | 'status' | 'tab' | 'tablist' | 'tabpanel' | 'textbox' | 'toolbar' | 'tooltip' | null | undefined): this {
419
+ if (value === null || value === undefined) {
420
+ this.element.removeAttribute('role');
421
+ } else {
422
+ this.element.setAttribute('role', String(value));
423
+ }
424
+ return this;
425
+ }
426
+
427
+ setSlot(value: string | null | undefined): this {
428
+ if (value === null || value === undefined) {
429
+ this.element.removeAttribute('slot');
430
+ } else {
431
+ this.element.setAttribute('slot', String(value));
432
+ }
433
+ return this;
434
+ }
435
+
436
+ setSpellcheck(value: 'true' | 'false' | boolean | null | undefined): this {
437
+ if (value === null || value === undefined) {
438
+ this.element.removeAttribute('spellcheck');
439
+ } else {
440
+ this.element.setAttribute('spellcheck', String(value));
441
+ }
442
+ return this;
443
+ }
444
+
445
+ setStyle(value: string | null | undefined): this {
446
+ if (value === null || value === undefined) {
447
+ this.element.removeAttribute('style');
448
+ } else {
449
+ this.element.setAttribute('style', String(value));
450
+ }
451
+ return this;
452
+ }
453
+
454
+ setTabindex(value: number | null | undefined): this {
455
+ if (value === null || value === undefined) {
456
+ this.element.removeAttribute('tabindex');
457
+ } else {
458
+ this.element.setAttribute('tabindex', String(value));
459
+ }
460
+ return this;
461
+ }
462
+
463
+ setTitle(value: string | null | undefined): this {
464
+ if (value === null || value === undefined) {
465
+ this.element.removeAttribute('title');
466
+ } else {
467
+ this.element.setAttribute('title', String(value));
468
+ }
469
+ return this;
470
+ }
471
+
472
+ setTranslate(value: 'yes' | 'no' | null | undefined): this {
473
+ if (value === null || value === undefined) {
474
+ this.element.removeAttribute('translate');
475
+ } else {
476
+ this.element.setAttribute('translate', String(value));
477
+ }
478
+ return this;
479
+ }
480
+
481
+ setChildren(children: string | HTMLElement | (string | HTMLElement)[]): this {
482
+ // Clear existing children
483
+ while (this.element.firstChild) {
484
+ this.element.removeChild(this.element.firstChild);
485
+ }
486
+
487
+ if (typeof children === 'string') {
488
+ this.element.textContent = children;
489
+ } else if (Array.isArray(children)) {
490
+ children.forEach(child => {
491
+ if (typeof child === 'string') {
492
+ this.element.appendChild(document.createTextNode(child));
493
+ } else {
494
+ this.element.appendChild(child);
495
+ }
496
+ });
497
+ } else {
498
+ this.element.appendChild(children);
499
+ }
500
+ return this;
501
+ }
502
+
503
+ getElement(): HTMLElement {
504
+ return this.element;
505
+ }
506
+ }