domelemjs 2.0.0 → 2.0.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.
- package/README-hu.md +284 -0
- package/README.md +39 -2
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +22 -7
package/README-hu.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# DOMelemJS
|
|
2
|
+
|
|
3
|
+
Könnyű, függőségmentes TypeScript könyvtár HTML elemek dinamikus létrehozásához JavaScript-ből.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/domelemjs)
|
|
6
|
+
[](https://github.com/exphoenee/DOMelemJS/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## Telepítés
|
|
9
|
+
|
|
10
|
+
### npm
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install domelemjs
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### CDN (unpkg)
|
|
17
|
+
|
|
18
|
+
Build eszközök nélkül — közvetlenül az HTML-be ágyazható:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<script src="https://unpkg.com/domelemjs/dist/index.browser.js"></script>
|
|
22
|
+
<script>
|
|
23
|
+
const { createDOMElem, DOMElem } = DOMElemJS;
|
|
24
|
+
|
|
25
|
+
const app = createDOMElem({
|
|
26
|
+
tag: "div",
|
|
27
|
+
attrs: { id: "app" },
|
|
28
|
+
text: "Helló CDN-ről!",
|
|
29
|
+
});
|
|
30
|
+
</script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Adott verzió megadása:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<script src="https://unpkg.com/domelemjs@2.0.0/dist/index.browser.js"></script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Gyors Kezdés
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { createDOMElem } from "domelemjs";
|
|
43
|
+
|
|
44
|
+
const app = createDOMElem({
|
|
45
|
+
tag: "div",
|
|
46
|
+
attrs: { id: "app" },
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### `createDOMElem(options)`
|
|
53
|
+
|
|
54
|
+
A fő függvény. Létrehoz egy DOM elemet és visszaadja az `HTMLElement`-et.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const el = createDOMElem({
|
|
58
|
+
tag: "h1",
|
|
59
|
+
text: "Helló Világ",
|
|
60
|
+
attrs: { class: "title" },
|
|
61
|
+
style: { color: "blue" },
|
|
62
|
+
parent: "#app",
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `new DOMElem(options)`
|
|
67
|
+
|
|
68
|
+
Osztályalapú burkoló. A létrehozott elem a `.elem` tulajdonságon érhető el.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { DOMElem } from "domelemjs";
|
|
72
|
+
|
|
73
|
+
const div = new DOMElem({
|
|
74
|
+
tag: "div",
|
|
75
|
+
text: "Helló",
|
|
76
|
+
attrs: { class: "container" },
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
document.body.appendChild(div.elem);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Opciók
|
|
83
|
+
|
|
84
|
+
| Opció | Típus | Leírás |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `tag` | `string` | **Kötelező.** HTML tag neve (pl. `"div"`, `"span"`, `"input"`). |
|
|
87
|
+
| `text` | `string` | Egyszerű szöveges tartalom (`textContent`). |
|
|
88
|
+
| `content` | `string` | Nyers HTML tartalom (`innerHTML`). |
|
|
89
|
+
| `attrs` | `object \| object[]` | Beállítandó HTML attribútumok. Támogatja a `class`, `id`, `data-*`, `checked` stb. |
|
|
90
|
+
| `style` | `string \| object \| array` | Inline CSS stílusok (lásd [Stílusok](#stílusok)). |
|
|
91
|
+
| `children` | `array` | Gyerekelemek — options objektumok vagy `HTMLElement`-ek. |
|
|
92
|
+
| `parent` | `HTMLElement \| string` | Szülő elem, amibe beillesztjük. Elfogad elemet vagy CSS szelektort (`"#app"`, `".container"`, `"app"`). Alapértelmezés: `document.body`. |
|
|
93
|
+
| `handleEvent` | `object \| object[]` | Eseménykezelők (lásd [Események](#események)). |
|
|
94
|
+
| `append` | `boolean` | Hozzá kell-e fűzni a szülőhöz. Alapértelmezés: `true`. |
|
|
95
|
+
| `stripDiacritics` | `boolean` | El kell-e távolítani a diakritikus jeleket a `class` és `id` attribútumokból. Alapértelmezés: `true`. Állítsd `false`-ra a Unicode karakterek megőrzéséhez. |
|
|
96
|
+
|
|
97
|
+
## Stílusok
|
|
98
|
+
|
|
99
|
+
A stílusok több formátumban megadhatók:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
// CSS string
|
|
103
|
+
createDOMElem({
|
|
104
|
+
tag: "div",
|
|
105
|
+
style: "color: red; background-color: blue",
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Objektum
|
|
109
|
+
createDOMElem({
|
|
110
|
+
tag: "div",
|
|
111
|
+
style: { color: "red", backgroundColor: "blue" },
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Tömb (vegyes)
|
|
115
|
+
createDOMElem({
|
|
116
|
+
tag: "div",
|
|
117
|
+
style: ["color: red", { backgroundColor: "blue" }],
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Események
|
|
122
|
+
|
|
123
|
+
Eseménykezelők csatolása a `handleEvent` segítségével:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
createDOMElem({
|
|
127
|
+
tag: "button",
|
|
128
|
+
text: "Kattints rám",
|
|
129
|
+
handleEvent: {
|
|
130
|
+
event: "click",
|
|
131
|
+
cb: (e) => console.log("kattintás!"),
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Több esemény tömbben átadva:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
createDOMElem({
|
|
140
|
+
tag: "input",
|
|
141
|
+
handleEvent: [
|
|
142
|
+
{ event: "focus", cb: () => console.log("fókusz") },
|
|
143
|
+
{ event: "blur", cb: () => console.log("elvesztett fókusz") },
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Attribútumok
|
|
149
|
+
|
|
150
|
+
Az attribútumok lehetnek egyetlen objektumok vagy tömbök:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
createDOMElem({
|
|
154
|
+
tag: "input",
|
|
155
|
+
attrs: [
|
|
156
|
+
{ id: "myInput", type: "text" },
|
|
157
|
+
{ class: "form-control" },
|
|
158
|
+
],
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Speciális attribútum kezelés:
|
|
163
|
+
- **`checked`** — beállítja a checked tulajdonságot inputokon
|
|
164
|
+
- **`dataset`** — egyesíti a `data-*` attribútumokat (pl. `{ dataset: { id: "foo" } }` → `data-id="foo"`)
|
|
165
|
+
- **`class` / `id`** — a diakritikus jelek alapértelmezésben automatikusan eltávolításra kerülnek. Állítsd `stripDiacritics: false`-ra a megőrzésükhöz.
|
|
166
|
+
|
|
167
|
+
> **Megjegyzés:** Ha mind a `text`, mind a `content` meg van adva, a `text` élvez előnyt és figyelmeztetés naplózódik.
|
|
168
|
+
|
|
169
|
+
## Eseménykezelők Kezelése
|
|
170
|
+
|
|
171
|
+
A `DOMElem` osztály nyomon követi az eseménykezelőket és támogatja az eltávolításukat:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { DOMElem } from "domelemjs";
|
|
175
|
+
|
|
176
|
+
const btn = new DOMElem({
|
|
177
|
+
tag: "button",
|
|
178
|
+
text: "Kattints rám",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const handler = () => console.log("kattintás!");
|
|
182
|
+
btn.addEventListener("click", handler);
|
|
183
|
+
btn.removeEventListener("click", handler);
|
|
184
|
+
|
|
185
|
+
// Összes nyomon követett kezelő eltávolítása egyszerre
|
|
186
|
+
btn.removeAllListeners();
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## HTML Tag-ek
|
|
190
|
+
|
|
191
|
+
A DOMelemJS exportálja az érvényes HTML tag nevek listáját:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { HTML_TAGS } from "domelemjs";
|
|
195
|
+
|
|
196
|
+
if (HTML_TAGS.includes(tag)) {
|
|
197
|
+
// érvényes HTML tag
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Gyerekelemek
|
|
202
|
+
|
|
203
|
+
A gyerekek lehetnek beágyazott options objektumok vagy meglévő `HTMLElement`-ek:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
createDOMElem({
|
|
207
|
+
tag: "select",
|
|
208
|
+
attrs: { id: "selector" },
|
|
209
|
+
children: [
|
|
210
|
+
{ tag: "option", text: "Foo", attrs: { value: "foo" } },
|
|
211
|
+
{ tag: "option", text: "Bar", attrs: { value: "bar" } },
|
|
212
|
+
],
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Összetett Példa
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { createDOMElem } from "domelemjs";
|
|
220
|
+
|
|
221
|
+
const container = createDOMElem({
|
|
222
|
+
tag: "div",
|
|
223
|
+
attrs: { class: "date-filter" },
|
|
224
|
+
children: [
|
|
225
|
+
{
|
|
226
|
+
tag: "div",
|
|
227
|
+
attrs: { class: "date-group" },
|
|
228
|
+
children: [
|
|
229
|
+
{
|
|
230
|
+
tag: "label",
|
|
231
|
+
text: "Kezdő dátum:",
|
|
232
|
+
attrs: { for: "startDate" },
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
tag: "input",
|
|
236
|
+
attrs: { type: "date", id: "startDate" },
|
|
237
|
+
handleEvent: {
|
|
238
|
+
event: "change",
|
|
239
|
+
cb: (e) => console.log("Kezdet:", (e.target as HTMLInputElement).value),
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
tag: "div",
|
|
246
|
+
attrs: { class: "date-group" },
|
|
247
|
+
children: [
|
|
248
|
+
{
|
|
249
|
+
tag: "label",
|
|
250
|
+
text: "Befejező dátum:",
|
|
251
|
+
attrs: { for: "endDate" },
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
tag: "input",
|
|
255
|
+
attrs: { type: "date", id: "endDate" },
|
|
256
|
+
handleEvent: {
|
|
257
|
+
event: "change",
|
|
258
|
+
cb: (e) => console.log("Vég:", (e.target as HTMLInputElement).value),
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## TypeScript
|
|
268
|
+
|
|
269
|
+
A DOMelemJS TypeScript-ben íródott és teljes típusdefíciókkal szállítódik.
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
import { createDOMElem, type CreateDOMElemOptions } from "domelemjs";
|
|
273
|
+
|
|
274
|
+
const options: CreateDOMElemOptions = {
|
|
275
|
+
tag: "div",
|
|
276
|
+
text: "Tipizált!",
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const el = createDOMElem(options);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Licenc
|
|
283
|
+
|
|
284
|
+
MIT
|
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@ A lightweight, zero-dependency TypeScript library for dynamically creating HTML
|
|
|
5
5
|
[](https://www.npmjs.com/package/domelemjs)
|
|
6
6
|
[](https://github.com/exphoenee/DOMelemJS/blob/main/LICENSE)
|
|
7
7
|
|
|
8
|
+
[Magyar README](README-hu.md) | [English README](README.md)
|
|
9
|
+
|
|
8
10
|
## Installation
|
|
9
11
|
|
|
10
12
|
### npm
|
|
@@ -33,7 +35,7 @@ No build tools needed — include directly in your HTML:
|
|
|
33
35
|
Pin a specific version:
|
|
34
36
|
|
|
35
37
|
```html
|
|
36
|
-
<script src="https://unpkg.com/domelemjs@2.0.
|
|
38
|
+
<script src="https://unpkg.com/domelemjs@2.0.0/dist/index.browser.js"></script>
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Quick Start
|
|
@@ -92,6 +94,7 @@ document.body.appendChild(div.elem);
|
|
|
92
94
|
| `parent` | `HTMLElement \| string` | Parent to append to. Accepts an element or a CSS selector (`"#app"`, `".container"`, `"app"`). Defaults to `document.body`. |
|
|
93
95
|
| `handleEvent` | `object \| object[]` | Event listeners to attach (see [Events](#events)). |
|
|
94
96
|
| `append` | `boolean` | Whether to append the element to its parent. Defaults to `true`. |
|
|
97
|
+
| `stripDiacritics` | `boolean` | Whether to strip diacritics from `class` and `id` attributes. Defaults to `true`. Set to `false` to preserve Unicode characters. |
|
|
95
98
|
|
|
96
99
|
## Styling
|
|
97
100
|
|
|
@@ -161,7 +164,41 @@ createDOMElem({
|
|
|
161
164
|
Special attribute handling:
|
|
162
165
|
- **`checked`** — sets the checked property on inputs
|
|
163
166
|
- **`dataset`** — merges `data-*` attributes (e.g. `{ dataset: { id: "foo" } }` becomes `data-id="foo"`)
|
|
164
|
-
- **`class` / `id`** — special characters are automatically stripped
|
|
167
|
+
- **`class` / `id`** — special characters (diacritics) are automatically stripped by default. Set `stripDiacritics: false` to preserve them.
|
|
168
|
+
|
|
169
|
+
> **Note:** If both `text` and `content` are provided, `text` takes precedence and a warning is logged.
|
|
170
|
+
|
|
171
|
+
## Managing Event Listeners
|
|
172
|
+
|
|
173
|
+
The `DOMElem` class tracks event listeners and supports removal:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import { DOMElem } from "domelemjs";
|
|
177
|
+
|
|
178
|
+
const btn = new DOMElem({
|
|
179
|
+
tag: "button",
|
|
180
|
+
text: "Click me",
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const handler = () => console.log("clicked!");
|
|
184
|
+
btn.addEventListener("click", handler);
|
|
185
|
+
btn.removeEventListener("click", handler);
|
|
186
|
+
|
|
187
|
+
// Remove all tracked listeners at once
|
|
188
|
+
btn.removeAllListeners();
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## HTML Tags
|
|
192
|
+
|
|
193
|
+
DOMelemJS exports a list of valid HTML tag names:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
import { HTML_TAGS } from "domelemjs";
|
|
197
|
+
|
|
198
|
+
if (HTML_TAGS.includes(tag)) {
|
|
199
|
+
// valid HTML tag
|
|
200
|
+
}
|
|
201
|
+
```
|
|
165
202
|
|
|
166
203
|
## Children
|
|
167
204
|
|
package/dist/index.browser.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var DOMElemJS=(()=>{var
|
|
1
|
+
"use strict";var DOMElemJS=(()=>{var u=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var O=(t,e)=>{for(var n in e)u(t,n,{get:e[n],enumerable:!0})},L=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of b(e))!M.call(t,o)&&o!==n&&u(t,o,{get:()=>e[o],enumerable:!(r=g(e,o))||r.enumerable});return t};var T=t=>L(u({},"__esModule",{value:!0}),t);var x={};O(x,{DOMElem:()=>p,HTML_TAGS:()=>E,createDOMElem:()=>l});function f(t){return t.split("-").map((e,n)=>n>0?e.charAt(0).toUpperCase()+e.slice(1):e).join("")}function m(t){return t==null?[]:Array.isArray(t)?t:[t]}function h(t,e=!1){let n={\u00E1:"a",\u00E9:"e",\u00ED:"i",\u00F3:"o",\u00F6:"o",\u0151:"o",\u00FA:"u",\u00FC:"u",\u0171:"u",\u00C1:"A",\u00C9:"E",\u00CD:"I",\u00D3:"O",\u00D6:"O",\u0150:"O",\u00DA:"U",\u00DC:"U",\u0170:"U",\u00E0:"a",\u00E8:"e",\u00EC:"i",\u00F2:"o",\u00F9:"u",\u00E2:"a",\u00EA:"e",\u00EE:"i",\u00F4:"o",\u00FB:"u",\u0103:"a",\u0115:"e",\u012D:"i",\u014F:"o",\u016D:"u",\u0101:"a",\u0113:"e",\u012B:"i",\u014D:"o",\u016B:"u",\u01CE:"a",\u011B:"e",\u01D0:"i",\u01D2:"o",\u01D4:"u",\u00E4:"a",\u00EB:"e",\u00EF:"i",\u00E5:"a",\u00F8:"o",\u00E3:"a",\u00F5:"o",\u00E6:"ae",\u00E7:"c",\u011F:"g",\u0142:"l",\u00F1:"n",\u0111:"d",\u00DF:"ss",\u010F:"d",\u0165:"t",\u0148:"n",\u0159:"r",\u0161:"s",\u017E:"z",\u0158:"R",\u0160:"S",\u017D:"Z",\u00C7:"C",\u015E:"S",\u011E:"G",\u0141:"L",\u00D1:"N",\u0110:"D",\u013E:"l",\u0155:"r",\u013A:"l"},r=t;for(let[o,i]of Object.entries(n))r=r.split(o).join(i);return e?r.toLowerCase():r}var A=["class","id"];function S(t){if(t instanceof HTMLElement)return t;let e=null;return t.charAt(0)==="#"||t.charAt(0)==="."?e=document.querySelector(t):e=document.querySelector(`#${t}`)||document.querySelector(`.${t}`)||document.querySelector(t),e||(console.warn(`[DOMElemJS] Parent element not found for selector: "${t}". Falling back to document.body.`),document.body)}function C(t,e,n){for(let r of m(e))for(let[o,i]of Object.entries(r))if(i!=null)if(o==="checked")t.checked=!!i;else if(o==="dataset"&&typeof i=="object"&&!Array.isArray(i))Object.assign(t.dataset,i);else{let a=(Array.isArray(i)?i:[i]).map(d=>n&&A.includes(o)?h(String(d)):String(d));t.setAttribute(o,a.join(" "))}}function H(t,e){m(e).map(r=>typeof r=="object"&&r!==null?Object.entries(r).map(([o,i])=>`${o}: ${i}`).join("; "):m(r).join("; ")).join("; ").split(";").filter(Boolean).forEach(r=>{let o=r.indexOf(":");if(o===-1)return;let i=r.slice(0,o).trim(),c=r.slice(o+1).trim();if(i){let a=f(i);t.style[a]=c}})}function k(t,e){for(let n of e)n instanceof HTMLElement?t.appendChild(n):t.appendChild(l(n))}function _(t,e){for(let n of m(e))n?.event&&n?.cb&&t.addEventListener(n.event,n.cb)}function l(t){let{tag:e,content:n,text:r,attrs:o,style:i,children:c,parent:a,handleEvent:d,append:v=!0,stripDiacritics:y=!0}=t;n&&r&&console.warn(`[DOMElemJS] Both "content" and "text" provided for <${e}>. "text" takes precedence \u2014 "content" will be ignored.`);let s=document.createElement(e);return r?s.textContent=r:n&&(s.innerHTML=n),o&&C(s,o,y),i&&H(s,i),c&&k(s,c),d&&_(s,d),v&&(a?S(a):document.body).appendChild(s),s}var p=class{constructor(e){this._listeners=new Map;if(this.options=e,this.elem=l(e),e.handleEvent){let n=Array.isArray(e.handleEvent)?e.handleEvent:[e.handleEvent];for(let r of n)this._trackListener(r.event,r.cb)}}addEventListener(e,n){return this.elem.addEventListener(e,n),this._trackListener(e,n),this}removeEventListener(e,n){return this.elem.removeEventListener(e,n),this._untrackListener(e,n),this}removeAllListeners(){for(let[e,n]of this._listeners)for(let r of n)this.elem.removeEventListener(e,r);this._listeners.clear()}_trackListener(e,n){this._listeners.has(e)||this._listeners.set(e,new Set),this._listeners.get(e).add(n)}_untrackListener(e,n){this._listeners.get(e)?.delete(n)}};var E=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","video","wbr"];return T(x);})();
|
|
2
2
|
//# sourceMappingURL=index.browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts"],"sourcesContent":["/**\n * DOMelemJS — a lightweight, zero-dependency library for creating\n * DOM elements from JavaScript/TypeScript.\n *\n * @example\n * ```ts\n * import { createDOMElem, DOMElem } from \"domelemjs\";\n *\n * // Functional API\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { id: \"app\" },\n * });\n *\n * // Class API\n * const div = new DOMElem({ tag: \"div\", text: \"World\" });\n * ```\n *\n * @packageDocumentation\n */\n\nexport { default as DOMElem } from \"./DOMElem\";\nexport { default as createDOMElem } from \"./createDOMElem\";\nexport type {\n CreateDOMElemOptions,\n DOMElemOptions,\n EventHandler,\n StyleInput,\n AttrsInput,\n ParentInput,\n HtmlTag,\n} from \"./types\";\n","/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n return document.querySelector(parent) as HTMLElement;\n }\n return (\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent)\n ) as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"`.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n */\nfunction applyAttrs(elem: HTMLElement, attrs: AttrsInput): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (key === \"dataset\" && typeof value === \"object\" && !Array.isArray(value)) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n NO_SPEC_CHARS_ATTRS.includes(key) ? noSpecChars(String(v)) : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n } = options;\n\n const elem = document.createElement(tag);\n\n if (content) elem.innerHTML = content;\n if (text) elem.textContent = text;\n if (attrs) applyAttrs(elem, attrs);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * document.body.appendChild(div.elem);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n }\n}\n"],"mappings":"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","names":["index_exports","__export","DOMElem","createDOMElem","makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","applyAttrs","elem","attrs","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts","../src/htmlTags.ts"],"sourcesContent":["/**\n * DOMelemJS — a lightweight, zero-dependency library for creating\n * DOM elements from JavaScript/TypeScript.\n *\n * @example\n * ```ts\n * import { createDOMElem, DOMElem } from \"domelemjs\";\n *\n * // Functional API\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { id: \"app\" },\n * });\n *\n * // Class API\n * const div = new DOMElem({ tag: \"div\", text: \"World\" });\n * ```\n *\n * @packageDocumentation\n */\n\nexport { default as DOMElem } from \"./DOMElem\";\nexport { default as createDOMElem } from \"./createDOMElem\";\nexport { HTML_TAGS } from \"./htmlTags\";\nexport type {\n CreateDOMElemOptions,\n DOMElemOptions,\n EventHandler,\n StyleInput,\n AttrsInput,\n ParentInput,\n HtmlTag,\n} from \"./types\";\nexport type { HtmlTagConst } from \"./htmlTags\";\n","/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n * @throws Will console.warn if the selector does not match any element.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n\n let el: Element | null = null;\n\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n el = document.querySelector(parent);\n } else {\n el =\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent);\n }\n\n if (!el) {\n console.warn(\n `[DOMElemJS] Parent element not found for selector: \"${parent}\". ` +\n `Falling back to document.body.`\n );\n return document.body;\n }\n\n return el as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"` when `stripDiacritics` is enabled.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n * @param stripDiacritics - Whether to strip diacritics from class/id.\n */\nfunction applyAttrs(\n elem: HTMLElement,\n attrs: AttrsInput,\n stripDiacritics: boolean\n): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (\n key === \"dataset\" &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n stripDiacritics && NO_SPEC_CHARS_ATTRS.includes(key)\n ? noSpecChars(String(v))\n : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n stripDiacritics = true,\n } = options;\n\n if (content && text) {\n console.warn(\n `[DOMElemJS] Both \"content\" and \"text\" provided for <${tag}>. ` +\n `\"text\" takes precedence — \"content\" will be ignored.`\n );\n }\n\n const elem = document.createElement(tag);\n\n if (text) {\n elem.textContent = text;\n } else if (content) {\n elem.innerHTML = content;\n }\n\n if (attrs) applyAttrs(elem, attrs, stripDiacritics);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions, EventHandler } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n * Event listeners can be added and removed via `addEventListener` /\n * `removeEventListener`.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * div.addEventListener(\"click\", () => console.log(\"clicked\"));\n * div.removeEventListener(\"click\", handler);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n private _listeners: Map<string, Set<(e: Event) => void>> = new Map();\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n\n if (options.handleEvent) {\n const events = Array.isArray(options.handleEvent)\n ? options.handleEvent\n : [options.handleEvent];\n for (const evt of events) {\n this._trackListener(evt.event, evt.cb);\n }\n }\n }\n\n /**\n * Adds an event listener to the element and tracks it for later removal.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function.\n * @returns This instance for chaining.\n */\n addEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.addEventListener(event, cb);\n this._trackListener(event, cb);\n return this;\n }\n\n /**\n * Removes a previously added event listener.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function to remove.\n * @returns This instance for chaining.\n */\n removeEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.removeEventListener(event, cb);\n this._untrackListener(event, cb);\n return this;\n }\n\n /**\n * Removes all tracked event listeners from the element.\n */\n removeAllListeners(): void {\n for (const [event, cbs] of this._listeners) {\n for (const cb of cbs) {\n this.elem.removeEventListener(event, cb);\n }\n }\n this._listeners.clear();\n }\n\n private _trackListener(event: string, cb: (e: Event) => void): void {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set());\n }\n this._listeners.get(event)!.add(cb);\n }\n\n private _untrackListener(event: string, cb: (e: Event) => void): void {\n this._listeners.get(event)?.delete(cb);\n }\n}\n","/**\n * List of standard HTML tag names.\n *\n * Provided as a `const` tuple so TypeScript can infer literal types\n * (e.g. `\"div\"` instead of `string`).\n *\n * @example\n * import { HTML_TAGS } from \"domelemjs\";\n * if (HTML_TAGS.includes(tag as HtmlTagConst)) { ... }\n */\nexport const HTML_TAGS = [\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\",\n \"b\", \"base\", \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\",\n \"canvas\", \"caption\", \"cite\", \"code\", \"col\", \"colgroup\",\n \"data\", \"datalist\", \"dd\", \"del\", \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\",\n \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hr\", \"html\",\n \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\",\n \"label\", \"legend\", \"li\", \"link\",\n \"main\", \"map\", \"mark\", \"meta\", \"meter\",\n \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\",\n \"p\", \"param\", \"picture\", \"pre\", \"progress\",\n \"q\",\n \"rp\", \"rt\", \"ruby\",\n \"s\", \"samp\", \"script\", \"section\", \"select\", \"small\", \"source\", \"span\",\n \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"svg\",\n \"table\", \"tbody\", \"td\", \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\",\n \"time\", \"title\", \"tr\", \"track\",\n \"u\", \"ul\",\n \"video\",\n \"wbr\",\n] as const;\n\n/** Union type of all valid HTML tag name literals. */\nexport type HtmlTagConst = (typeof HTML_TAGS)[number];\n"],"mappings":"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","names":["index_exports","__export","DOMElem","HTML_TAGS","createDOMElem","makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","el","applyAttrs","elem","attrs","stripDiacritics","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem","events","evt","event","cb","cbs","HTML_TAGS"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var O=(t,e)=>{for(var n in e)u(t,n,{get:e[n],enumerable:!0})},L=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of b(e))!M.call(t,o)&&o!==n&&u(t,o,{get:()=>e[o],enumerable:!(r=g(e,o))||r.enumerable});return t};var T=t=>L(u({},"__esModule",{value:!0}),t);var x={};O(x,{DOMElem:()=>p,HTML_TAGS:()=>E,createDOMElem:()=>l});module.exports=T(x);function f(t){return t.split("-").map((e,n)=>n>0?e.charAt(0).toUpperCase()+e.slice(1):e).join("")}function m(t){return t==null?[]:Array.isArray(t)?t:[t]}function h(t,e=!1){let n={\u00E1:"a",\u00E9:"e",\u00ED:"i",\u00F3:"o",\u00F6:"o",\u0151:"o",\u00FA:"u",\u00FC:"u",\u0171:"u",\u00C1:"A",\u00C9:"E",\u00CD:"I",\u00D3:"O",\u00D6:"O",\u0150:"O",\u00DA:"U",\u00DC:"U",\u0170:"U",\u00E0:"a",\u00E8:"e",\u00EC:"i",\u00F2:"o",\u00F9:"u",\u00E2:"a",\u00EA:"e",\u00EE:"i",\u00F4:"o",\u00FB:"u",\u0103:"a",\u0115:"e",\u012D:"i",\u014F:"o",\u016D:"u",\u0101:"a",\u0113:"e",\u012B:"i",\u014D:"o",\u016B:"u",\u01CE:"a",\u011B:"e",\u01D0:"i",\u01D2:"o",\u01D4:"u",\u00E4:"a",\u00EB:"e",\u00EF:"i",\u00E5:"a",\u00F8:"o",\u00E3:"a",\u00F5:"o",\u00E6:"ae",\u00E7:"c",\u011F:"g",\u0142:"l",\u00F1:"n",\u0111:"d",\u00DF:"ss",\u010F:"d",\u0165:"t",\u0148:"n",\u0159:"r",\u0161:"s",\u017E:"z",\u0158:"R",\u0160:"S",\u017D:"Z",\u00C7:"C",\u015E:"S",\u011E:"G",\u0141:"L",\u00D1:"N",\u0110:"D",\u013E:"l",\u0155:"r",\u013A:"l"},r=t;for(let[o,i]of Object.entries(n))r=r.split(o).join(i);return e?r.toLowerCase():r}var A=["class","id"];function S(t){if(t instanceof HTMLElement)return t;let e=null;return t.charAt(0)==="#"||t.charAt(0)==="."?e=document.querySelector(t):e=document.querySelector(`#${t}`)||document.querySelector(`.${t}`)||document.querySelector(t),e||(console.warn(`[DOMElemJS] Parent element not found for selector: "${t}". Falling back to document.body.`),document.body)}function C(t,e,n){for(let r of m(e))for(let[o,i]of Object.entries(r))if(i!=null)if(o==="checked")t.checked=!!i;else if(o==="dataset"&&typeof i=="object"&&!Array.isArray(i))Object.assign(t.dataset,i);else{let a=(Array.isArray(i)?i:[i]).map(d=>n&&A.includes(o)?h(String(d)):String(d));t.setAttribute(o,a.join(" "))}}function H(t,e){m(e).map(r=>typeof r=="object"&&r!==null?Object.entries(r).map(([o,i])=>`${o}: ${i}`).join("; "):m(r).join("; ")).join("; ").split(";").filter(Boolean).forEach(r=>{let o=r.indexOf(":");if(o===-1)return;let i=r.slice(0,o).trim(),c=r.slice(o+1).trim();if(i){let a=f(i);t.style[a]=c}})}function k(t,e){for(let n of e)n instanceof HTMLElement?t.appendChild(n):t.appendChild(l(n))}function _(t,e){for(let n of m(e))n?.event&&n?.cb&&t.addEventListener(n.event,n.cb)}function l(t){let{tag:e,content:n,text:r,attrs:o,style:i,children:c,parent:a,handleEvent:d,append:v=!0,stripDiacritics:y=!0}=t;n&&r&&console.warn(`[DOMElemJS] Both "content" and "text" provided for <${e}>. "text" takes precedence \u2014 "content" will be ignored.`);let s=document.createElement(e);return r?s.textContent=r:n&&(s.innerHTML=n),o&&C(s,o,y),i&&H(s,i),c&&k(s,c),d&&_(s,d),v&&(a?S(a):document.body).appendChild(s),s}var p=class{constructor(e){this._listeners=new Map;if(this.options=e,this.elem=l(e),e.handleEvent){let n=Array.isArray(e.handleEvent)?e.handleEvent:[e.handleEvent];for(let r of n)this._trackListener(r.event,r.cb)}}addEventListener(e,n){return this.elem.addEventListener(e,n),this._trackListener(e,n),this}removeEventListener(e,n){return this.elem.removeEventListener(e,n),this._untrackListener(e,n),this}removeAllListeners(){for(let[e,n]of this._listeners)for(let r of n)this.elem.removeEventListener(e,r);this._listeners.clear()}_trackListener(e,n){this._listeners.has(e)||this._listeners.set(e,new Set),this._listeners.get(e).add(n)}_untrackListener(e,n){this._listeners.get(e)?.delete(n)}};var E=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","video","wbr"];0&&(module.exports={DOMElem,HTML_TAGS,createDOMElem});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts"],"sourcesContent":["/**\n * DOMelemJS — a lightweight, zero-dependency library for creating\n * DOM elements from JavaScript/TypeScript.\n *\n * @example\n * ```ts\n * import { createDOMElem, DOMElem } from \"domelemjs\";\n *\n * // Functional API\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { id: \"app\" },\n * });\n *\n * // Class API\n * const div = new DOMElem({ tag: \"div\", text: \"World\" });\n * ```\n *\n * @packageDocumentation\n */\n\nexport { default as DOMElem } from \"./DOMElem\";\nexport { default as createDOMElem } from \"./createDOMElem\";\nexport type {\n CreateDOMElemOptions,\n DOMElemOptions,\n EventHandler,\n StyleInput,\n AttrsInput,\n ParentInput,\n HtmlTag,\n} from \"./types\";\n","/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n return document.querySelector(parent) as HTMLElement;\n }\n return (\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent)\n ) as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"`.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n */\nfunction applyAttrs(elem: HTMLElement, attrs: AttrsInput): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (key === \"dataset\" && typeof value === \"object\" && !Array.isArray(value)) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n NO_SPEC_CHARS_ATTRS.includes(key) ? noSpecChars(String(v)) : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n } = options;\n\n const elem = document.createElement(tag);\n\n if (content) elem.innerHTML = content;\n if (text) elem.textContent = text;\n if (attrs) applyAttrs(elem, attrs);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * document.body.appendChild(div.elem);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n }\n}\n"],"mappings":"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","names":["index_exports","__export","DOMElem","createDOMElem","__toCommonJS","makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","applyAttrs","elem","attrs","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts","../src/htmlTags.ts"],"sourcesContent":["/**\n * DOMelemJS — a lightweight, zero-dependency library for creating\n * DOM elements from JavaScript/TypeScript.\n *\n * @example\n * ```ts\n * import { createDOMElem, DOMElem } from \"domelemjs\";\n *\n * // Functional API\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { id: \"app\" },\n * });\n *\n * // Class API\n * const div = new DOMElem({ tag: \"div\", text: \"World\" });\n * ```\n *\n * @packageDocumentation\n */\n\nexport { default as DOMElem } from \"./DOMElem\";\nexport { default as createDOMElem } from \"./createDOMElem\";\nexport { HTML_TAGS } from \"./htmlTags\";\nexport type {\n CreateDOMElemOptions,\n DOMElemOptions,\n EventHandler,\n StyleInput,\n AttrsInput,\n ParentInput,\n HtmlTag,\n} from \"./types\";\nexport type { HtmlTagConst } from \"./htmlTags\";\n","/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n * @throws Will console.warn if the selector does not match any element.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n\n let el: Element | null = null;\n\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n el = document.querySelector(parent);\n } else {\n el =\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent);\n }\n\n if (!el) {\n console.warn(\n `[DOMElemJS] Parent element not found for selector: \"${parent}\". ` +\n `Falling back to document.body.`\n );\n return document.body;\n }\n\n return el as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"` when `stripDiacritics` is enabled.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n * @param stripDiacritics - Whether to strip diacritics from class/id.\n */\nfunction applyAttrs(\n elem: HTMLElement,\n attrs: AttrsInput,\n stripDiacritics: boolean\n): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (\n key === \"dataset\" &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n stripDiacritics && NO_SPEC_CHARS_ATTRS.includes(key)\n ? noSpecChars(String(v))\n : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n stripDiacritics = true,\n } = options;\n\n if (content && text) {\n console.warn(\n `[DOMElemJS] Both \"content\" and \"text\" provided for <${tag}>. ` +\n `\"text\" takes precedence — \"content\" will be ignored.`\n );\n }\n\n const elem = document.createElement(tag);\n\n if (text) {\n elem.textContent = text;\n } else if (content) {\n elem.innerHTML = content;\n }\n\n if (attrs) applyAttrs(elem, attrs, stripDiacritics);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions, EventHandler } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n * Event listeners can be added and removed via `addEventListener` /\n * `removeEventListener`.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * div.addEventListener(\"click\", () => console.log(\"clicked\"));\n * div.removeEventListener(\"click\", handler);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n private _listeners: Map<string, Set<(e: Event) => void>> = new Map();\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n\n if (options.handleEvent) {\n const events = Array.isArray(options.handleEvent)\n ? options.handleEvent\n : [options.handleEvent];\n for (const evt of events) {\n this._trackListener(evt.event, evt.cb);\n }\n }\n }\n\n /**\n * Adds an event listener to the element and tracks it for later removal.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function.\n * @returns This instance for chaining.\n */\n addEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.addEventListener(event, cb);\n this._trackListener(event, cb);\n return this;\n }\n\n /**\n * Removes a previously added event listener.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function to remove.\n * @returns This instance for chaining.\n */\n removeEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.removeEventListener(event, cb);\n this._untrackListener(event, cb);\n return this;\n }\n\n /**\n * Removes all tracked event listeners from the element.\n */\n removeAllListeners(): void {\n for (const [event, cbs] of this._listeners) {\n for (const cb of cbs) {\n this.elem.removeEventListener(event, cb);\n }\n }\n this._listeners.clear();\n }\n\n private _trackListener(event: string, cb: (e: Event) => void): void {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set());\n }\n this._listeners.get(event)!.add(cb);\n }\n\n private _untrackListener(event: string, cb: (e: Event) => void): void {\n this._listeners.get(event)?.delete(cb);\n }\n}\n","/**\n * List of standard HTML tag names.\n *\n * Provided as a `const` tuple so TypeScript can infer literal types\n * (e.g. `\"div\"` instead of `string`).\n *\n * @example\n * import { HTML_TAGS } from \"domelemjs\";\n * if (HTML_TAGS.includes(tag as HtmlTagConst)) { ... }\n */\nexport const HTML_TAGS = [\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\",\n \"b\", \"base\", \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\",\n \"canvas\", \"caption\", \"cite\", \"code\", \"col\", \"colgroup\",\n \"data\", \"datalist\", \"dd\", \"del\", \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\",\n \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hr\", \"html\",\n \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\",\n \"label\", \"legend\", \"li\", \"link\",\n \"main\", \"map\", \"mark\", \"meta\", \"meter\",\n \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\",\n \"p\", \"param\", \"picture\", \"pre\", \"progress\",\n \"q\",\n \"rp\", \"rt\", \"ruby\",\n \"s\", \"samp\", \"script\", \"section\", \"select\", \"small\", \"source\", \"span\",\n \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"svg\",\n \"table\", \"tbody\", \"td\", \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\",\n \"time\", \"title\", \"tr\", \"track\",\n \"u\", \"ul\",\n \"video\",\n \"wbr\",\n] as const;\n\n/** Union type of all valid HTML tag name literals. */\nexport type HtmlTagConst = (typeof HTML_TAGS)[number];\n"],"mappings":"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","names":["index_exports","__export","DOMElem","HTML_TAGS","createDOMElem","__toCommonJS","makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","el","applyAttrs","elem","attrs","stripDiacritics","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem","events","evt","event","cb","cbs","HTML_TAGS"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* List of standard HTML tag names.
|
|
3
|
+
*
|
|
4
|
+
* Provided as a `const` tuple so TypeScript can infer literal types
|
|
5
|
+
* (e.g. `"div"` instead of `string`).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { HTML_TAGS } from "domelemjs";
|
|
9
|
+
* if (HTML_TAGS.includes(tag as HtmlTagConst)) { ... }
|
|
10
|
+
*/
|
|
11
|
+
declare const HTML_TAGS: readonly ["a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "blockquote", "body", "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "u", "ul", "video", "wbr"];
|
|
12
|
+
/** Union type of all valid HTML tag name literals. */
|
|
13
|
+
type HtmlTagConst = (typeof HTML_TAGS)[number];
|
|
14
|
+
|
|
15
|
+
/** HTML tag name — a string union of valid tags, or any string for flexibility. */
|
|
16
|
+
type HtmlTag = HtmlTagConst | string;
|
|
3
17
|
/** A single CSS style value — either a string or a numeric pixel value. */
|
|
4
18
|
type StyleValue = string | number;
|
|
5
19
|
/**
|
|
@@ -62,6 +76,8 @@ interface CreateDOMElemOptions {
|
|
|
62
76
|
parent?: ParentInput;
|
|
63
77
|
handleEvent?: EventHandler | EventHandler[];
|
|
64
78
|
append?: boolean;
|
|
79
|
+
/** Whether to strip diacritics from `class` and `id` attributes. Defaults to `true`. */
|
|
80
|
+
stripDiacritics?: boolean;
|
|
65
81
|
}
|
|
66
82
|
/** Options type for the `DOMElem` class — identical to `CreateDOMElemOptions`. */
|
|
67
83
|
type DOMElemOptions = CreateDOMElemOptions;
|
|
@@ -71,6 +87,8 @@ type DOMElemOptions = CreateDOMElemOptions;
|
|
|
71
87
|
*
|
|
72
88
|
* Provides an object-oriented API for creating DOM elements.
|
|
73
89
|
* The created element is available via the `.elem` property.
|
|
90
|
+
* Event listeners can be added and removed via `addEventListener` /
|
|
91
|
+
* `removeEventListener`.
|
|
74
92
|
*
|
|
75
93
|
* @example
|
|
76
94
|
* ```ts
|
|
@@ -80,7 +98,8 @@ type DOMElemOptions = CreateDOMElemOptions;
|
|
|
80
98
|
* text: "Hello World",
|
|
81
99
|
* });
|
|
82
100
|
*
|
|
83
|
-
*
|
|
101
|
+
* div.addEventListener("click", () => console.log("clicked"));
|
|
102
|
+
* div.removeEventListener("click", handler);
|
|
84
103
|
* ```
|
|
85
104
|
*/
|
|
86
105
|
declare class DOMElem {
|
|
@@ -88,12 +107,35 @@ declare class DOMElem {
|
|
|
88
107
|
readonly elem: HTMLElement;
|
|
89
108
|
/** The options used to create the element. */
|
|
90
109
|
readonly options: DOMElemOptions;
|
|
110
|
+
private _listeners;
|
|
91
111
|
/**
|
|
92
112
|
* Creates a new DOMElem instance.
|
|
93
113
|
*
|
|
94
114
|
* @param options - Element creation options.
|
|
95
115
|
*/
|
|
96
116
|
constructor(options: DOMElemOptions);
|
|
117
|
+
/**
|
|
118
|
+
* Adds an event listener to the element and tracks it for later removal.
|
|
119
|
+
*
|
|
120
|
+
* @param event - The DOM event name.
|
|
121
|
+
* @param cb - The callback function.
|
|
122
|
+
* @returns This instance for chaining.
|
|
123
|
+
*/
|
|
124
|
+
addEventListener(event: string, cb: (e: Event) => void): this;
|
|
125
|
+
/**
|
|
126
|
+
* Removes a previously added event listener.
|
|
127
|
+
*
|
|
128
|
+
* @param event - The DOM event name.
|
|
129
|
+
* @param cb - The callback function to remove.
|
|
130
|
+
* @returns This instance for chaining.
|
|
131
|
+
*/
|
|
132
|
+
removeEventListener(event: string, cb: (e: Event) => void): this;
|
|
133
|
+
/**
|
|
134
|
+
* Removes all tracked event listeners from the element.
|
|
135
|
+
*/
|
|
136
|
+
removeAllListeners(): void;
|
|
137
|
+
private _trackListener;
|
|
138
|
+
private _untrackListener;
|
|
97
139
|
}
|
|
98
140
|
|
|
99
141
|
/**
|
|
@@ -123,4 +165,4 @@ declare class DOMElem {
|
|
|
123
165
|
*/
|
|
124
166
|
declare function createDOMElem(options: CreateDOMElemOptions): HTMLElement;
|
|
125
167
|
|
|
126
|
-
export { type AttrsInput, type CreateDOMElemOptions, DOMElem, type DOMElemOptions, type EventHandler, type HtmlTag, type ParentInput, type StyleInput, createDOMElem };
|
|
168
|
+
export { type AttrsInput, type CreateDOMElemOptions, DOMElem, type DOMElemOptions, type EventHandler, HTML_TAGS, type HtmlTag, type HtmlTagConst, type ParentInput, type StyleInput, createDOMElem };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* List of standard HTML tag names.
|
|
3
|
+
*
|
|
4
|
+
* Provided as a `const` tuple so TypeScript can infer literal types
|
|
5
|
+
* (e.g. `"div"` instead of `string`).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { HTML_TAGS } from "domelemjs";
|
|
9
|
+
* if (HTML_TAGS.includes(tag as HtmlTagConst)) { ... }
|
|
10
|
+
*/
|
|
11
|
+
declare const HTML_TAGS: readonly ["a", "abbr", "address", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "blockquote", "body", "br", "button", "canvas", "caption", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "svg", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "u", "ul", "video", "wbr"];
|
|
12
|
+
/** Union type of all valid HTML tag name literals. */
|
|
13
|
+
type HtmlTagConst = (typeof HTML_TAGS)[number];
|
|
14
|
+
|
|
15
|
+
/** HTML tag name — a string union of valid tags, or any string for flexibility. */
|
|
16
|
+
type HtmlTag = HtmlTagConst | string;
|
|
3
17
|
/** A single CSS style value — either a string or a numeric pixel value. */
|
|
4
18
|
type StyleValue = string | number;
|
|
5
19
|
/**
|
|
@@ -62,6 +76,8 @@ interface CreateDOMElemOptions {
|
|
|
62
76
|
parent?: ParentInput;
|
|
63
77
|
handleEvent?: EventHandler | EventHandler[];
|
|
64
78
|
append?: boolean;
|
|
79
|
+
/** Whether to strip diacritics from `class` and `id` attributes. Defaults to `true`. */
|
|
80
|
+
stripDiacritics?: boolean;
|
|
65
81
|
}
|
|
66
82
|
/** Options type for the `DOMElem` class — identical to `CreateDOMElemOptions`. */
|
|
67
83
|
type DOMElemOptions = CreateDOMElemOptions;
|
|
@@ -71,6 +87,8 @@ type DOMElemOptions = CreateDOMElemOptions;
|
|
|
71
87
|
*
|
|
72
88
|
* Provides an object-oriented API for creating DOM elements.
|
|
73
89
|
* The created element is available via the `.elem` property.
|
|
90
|
+
* Event listeners can be added and removed via `addEventListener` /
|
|
91
|
+
* `removeEventListener`.
|
|
74
92
|
*
|
|
75
93
|
* @example
|
|
76
94
|
* ```ts
|
|
@@ -80,7 +98,8 @@ type DOMElemOptions = CreateDOMElemOptions;
|
|
|
80
98
|
* text: "Hello World",
|
|
81
99
|
* });
|
|
82
100
|
*
|
|
83
|
-
*
|
|
101
|
+
* div.addEventListener("click", () => console.log("clicked"));
|
|
102
|
+
* div.removeEventListener("click", handler);
|
|
84
103
|
* ```
|
|
85
104
|
*/
|
|
86
105
|
declare class DOMElem {
|
|
@@ -88,12 +107,35 @@ declare class DOMElem {
|
|
|
88
107
|
readonly elem: HTMLElement;
|
|
89
108
|
/** The options used to create the element. */
|
|
90
109
|
readonly options: DOMElemOptions;
|
|
110
|
+
private _listeners;
|
|
91
111
|
/**
|
|
92
112
|
* Creates a new DOMElem instance.
|
|
93
113
|
*
|
|
94
114
|
* @param options - Element creation options.
|
|
95
115
|
*/
|
|
96
116
|
constructor(options: DOMElemOptions);
|
|
117
|
+
/**
|
|
118
|
+
* Adds an event listener to the element and tracks it for later removal.
|
|
119
|
+
*
|
|
120
|
+
* @param event - The DOM event name.
|
|
121
|
+
* @param cb - The callback function.
|
|
122
|
+
* @returns This instance for chaining.
|
|
123
|
+
*/
|
|
124
|
+
addEventListener(event: string, cb: (e: Event) => void): this;
|
|
125
|
+
/**
|
|
126
|
+
* Removes a previously added event listener.
|
|
127
|
+
*
|
|
128
|
+
* @param event - The DOM event name.
|
|
129
|
+
* @param cb - The callback function to remove.
|
|
130
|
+
* @returns This instance for chaining.
|
|
131
|
+
*/
|
|
132
|
+
removeEventListener(event: string, cb: (e: Event) => void): this;
|
|
133
|
+
/**
|
|
134
|
+
* Removes all tracked event listeners from the element.
|
|
135
|
+
*/
|
|
136
|
+
removeAllListeners(): void;
|
|
137
|
+
private _trackListener;
|
|
138
|
+
private _untrackListener;
|
|
97
139
|
}
|
|
98
140
|
|
|
99
141
|
/**
|
|
@@ -123,4 +165,4 @@ declare class DOMElem {
|
|
|
123
165
|
*/
|
|
124
166
|
declare function createDOMElem(options: CreateDOMElemOptions): HTMLElement;
|
|
125
167
|
|
|
126
|
-
export { type AttrsInput, type CreateDOMElemOptions, DOMElem, type DOMElemOptions, type EventHandler, type HtmlTag, type ParentInput, type StyleInput, createDOMElem };
|
|
168
|
+
export { type AttrsInput, type CreateDOMElemOptions, DOMElem, type DOMElemOptions, type EventHandler, HTML_TAGS, type HtmlTag, type HtmlTagConst, type ParentInput, type StyleInput, createDOMElem };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
1
|
+
function u(n){return n.split("-").map((e,t)=>t>0?e.charAt(0).toUpperCase()+e.slice(1):e).join("")}function d(n){return n==null?[]:Array.isArray(n)?n:[n]}function f(n,e=!1){let t={\u00E1:"a",\u00E9:"e",\u00ED:"i",\u00F3:"o",\u00F6:"o",\u0151:"o",\u00FA:"u",\u00FC:"u",\u0171:"u",\u00C1:"A",\u00C9:"E",\u00CD:"I",\u00D3:"O",\u00D6:"O",\u0150:"O",\u00DA:"U",\u00DC:"U",\u0170:"U",\u00E0:"a",\u00E8:"e",\u00EC:"i",\u00F2:"o",\u00F9:"u",\u00E2:"a",\u00EA:"e",\u00EE:"i",\u00F4:"o",\u00FB:"u",\u0103:"a",\u0115:"e",\u012D:"i",\u014F:"o",\u016D:"u",\u0101:"a",\u0113:"e",\u012B:"i",\u014D:"o",\u016B:"u",\u01CE:"a",\u011B:"e",\u01D0:"i",\u01D2:"o",\u01D4:"u",\u00E4:"a",\u00EB:"e",\u00EF:"i",\u00E5:"a",\u00F8:"o",\u00E3:"a",\u00F5:"o",\u00E6:"ae",\u00E7:"c",\u011F:"g",\u0142:"l",\u00F1:"n",\u0111:"d",\u00DF:"ss",\u010F:"d",\u0165:"t",\u0148:"n",\u0159:"r",\u0161:"s",\u017E:"z",\u0158:"R",\u0160:"S",\u017D:"Z",\u00C7:"C",\u015E:"S",\u011E:"G",\u0141:"L",\u00D1:"N",\u0110:"D",\u013E:"l",\u0155:"r",\u013A:"l"},r=n;for(let[i,o]of Object.entries(t))r=r.split(i).join(o);return e?r.toLowerCase():r}var v=["class","id"];function y(n){if(n instanceof HTMLElement)return n;let e=null;return n.charAt(0)==="#"||n.charAt(0)==="."?e=document.querySelector(n):e=document.querySelector(`#${n}`)||document.querySelector(`.${n}`)||document.querySelector(n),e||(console.warn(`[DOMElemJS] Parent element not found for selector: "${n}". Falling back to document.body.`),document.body)}function g(n,e,t){for(let r of d(e))for(let[i,o]of Object.entries(r))if(o!=null)if(i==="checked")n.checked=!!o;else if(i==="dataset"&&typeof o=="object"&&!Array.isArray(o))Object.assign(n.dataset,o);else{let a=(Array.isArray(o)?o:[o]).map(c=>t&&v.includes(i)?f(String(c)):String(c));n.setAttribute(i,a.join(" "))}}function b(n,e){d(e).map(r=>typeof r=="object"&&r!==null?Object.entries(r).map(([i,o])=>`${i}: ${o}`).join("; "):d(r).join("; ")).join("; ").split(";").filter(Boolean).forEach(r=>{let i=r.indexOf(":");if(i===-1)return;let o=r.slice(0,i).trim(),l=r.slice(i+1).trim();if(o){let a=u(o);n.style[a]=l}})}function M(n,e){for(let t of e)t instanceof HTMLElement?n.appendChild(t):n.appendChild(m(t))}function O(n,e){for(let t of d(e))t?.event&&t?.cb&&n.addEventListener(t.event,t.cb)}function m(n){let{tag:e,content:t,text:r,attrs:i,style:o,children:l,parent:a,handleEvent:c,append:h=!0,stripDiacritics:E=!0}=n;t&&r&&console.warn(`[DOMElemJS] Both "content" and "text" provided for <${e}>. "text" takes precedence \u2014 "content" will be ignored.`);let s=document.createElement(e);return r?s.textContent=r:t&&(s.innerHTML=t),i&&g(s,i,E),o&&b(s,o),l&&M(s,l),c&&O(s,c),h&&(a?y(a):document.body).appendChild(s),s}var p=class{constructor(e){this._listeners=new Map;if(this.options=e,this.elem=m(e),e.handleEvent){let t=Array.isArray(e.handleEvent)?e.handleEvent:[e.handleEvent];for(let r of t)this._trackListener(r.event,r.cb)}}addEventListener(e,t){return this.elem.addEventListener(e,t),this._trackListener(e,t),this}removeEventListener(e,t){return this.elem.removeEventListener(e,t),this._untrackListener(e,t),this}removeAllListeners(){for(let[e,t]of this._listeners)for(let r of t)this.elem.removeEventListener(e,r);this._listeners.clear()}_trackListener(e,t){this._listeners.has(e)||this._listeners.set(e,new Set),this._listeners.get(e).add(t)}_untrackListener(e,t){this._listeners.get(e)?.delete(t)}};var L=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","video","wbr"];export{p as DOMElem,L as HTML_TAGS,m as createDOMElem};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts"],"sourcesContent":["/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n return document.querySelector(parent) as HTMLElement;\n }\n return (\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent)\n ) as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"`.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n */\nfunction applyAttrs(elem: HTMLElement, attrs: AttrsInput): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (key === \"dataset\" && typeof value === \"object\" && !Array.isArray(value)) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n NO_SPEC_CHARS_ATTRS.includes(key) ? noSpecChars(String(v)) : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n } = options;\n\n const elem = document.createElement(tag);\n\n if (content) elem.innerHTML = content;\n if (text) elem.textContent = text;\n if (attrs) applyAttrs(elem, attrs);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * document.body.appendChild(div.elem);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n }\n}\n"],"mappings":"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","names":["makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","applyAttrs","elem","attrs","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/createDOMElem.ts","../src/DOMElem.ts","../src/htmlTags.ts"],"sourcesContent":["/**\n * Converts a kebab-case string to camelCase.\n *\n * @example\n * makeCamelCase(\"background-color\") // \"backgroundColor\"\n * makeCamelCase(\"font-size\") // \"fontSize\"\n *\n * @param s - The kebab-case string to convert.\n * @returns The camelCase version of the input.\n */\nexport function makeCamelCase(s: string): string {\n return s\n .split(\"-\")\n .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n .join(\"\");\n}\n\n/**\n * Ensures the given value is wrapped in an array.\n * Returns an empty array for `null` / `undefined`.\n *\n * @example\n * toArray(\"hello\") // [\"hello\"]\n * toArray([\"a\", \"b\"]) // [\"a\", \"b\"]\n * toArray(null) // []\n *\n * @param value - The value to normalize.\n * @returns An array containing the value, or an empty array if falsy.\n */\nexport function toArray<T>(value: T | T[] | undefined | null): T[] {\n if (value == null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Replaces accented / special characters with their ASCII equivalents.\n *\n * Supports Hungarian, Czech, Polish, Turkish, and other Latin-script diacritics.\n *\n * @example\n * noSpecChars(\"árvíztűrő\") // \"arviztuoro\"\n * noSpecChars(\"Árvíz\", true) // \"arviz\"\n *\n * @param text - The input string containing special characters.\n * @param lowercase - If `true`, the result is lowercased after replacement.\n * @returns The string with special characters replaced.\n */\nexport function noSpecChars(text: string, lowercase = false): string {\n const map: Record<string, string> = {\n á: \"a\", é: \"e\", í: \"i\", ó: \"o\", ö: \"o\", ő: \"o\",\n ú: \"u\", ü: \"u\", ű: \"u\",\n Á: \"A\", É: \"E\", Í: \"I\", Ó: \"O\", Ö: \"O\", Ő: \"O\",\n Ú: \"U\", Ü: \"U\", Ű: \"U\",\n à: \"a\", è: \"e\", ì: \"i\", ò: \"o\", ù: \"u\",\n â: \"a\", ê: \"e\", î: \"i\", ô: \"o\", û: \"u\",\n ă: \"a\", ĕ: \"e\", ĭ: \"i\", ŏ: \"o\", ŭ: \"u\",\n ā: \"a\", ē: \"e\", ī: \"i\", ō: \"o\", ū: \"u\",\n ǎ: \"a\", ě: \"e\", ǐ: \"i\", ǒ: \"o\", ǔ: \"u\",\n ä: \"a\", ë: \"e\", ï: \"i\",\n å: \"a\", ø: \"o\",\n ã: \"a\", õ: \"o\",\n æ: \"ae\",\n ç: \"c\", ğ: \"g\",\n ł: \"l\",\n ñ: \"n\",\n đ: \"d\",\n ß: \"ss\",\n ď: \"d\", ť: \"t\", ň: \"n\",\n ř: \"r\", š: \"s\", ž: \"z\",\n Ř: \"R\", Š: \"S\", Ž: \"Z\",\n Ç: \"C\", Ş: \"S\", Ğ: \"G\",\n Ł: \"L\", Ñ: \"N\", Đ: \"D\",\n ľ: \"l\", ŕ: \"r\", ĺ: \"l\",\n };\n\n let result = text;\n for (const [char, replacement] of Object.entries(map)) {\n result = result.split(char).join(replacement);\n }\n\n return lowercase ? result.toLowerCase() : result;\n}\n","import { makeCamelCase, toArray, noSpecChars } from \"./utils\";\nimport type { CreateDOMElemOptions, AttrsInput, StyleInput } from \"./types\";\n\n/** Attributes that have special characters stripped automatically. */\nconst NO_SPEC_CHARS_ATTRS = [\"class\", \"id\"];\n\n/**\n * Resolves a parent element from a string selector or HTMLElement reference.\n *\n * If the string starts with `#` or `.`, it is used directly as a querySelector\n * argument. Otherwise, it is tried first as `#<selector>` then as `.<selector>`.\n *\n * @param parent - An HTMLElement or a CSS selector string.\n * @returns The resolved HTMLElement.\n * @throws Will console.warn if the selector does not match any element.\n */\nfunction resolveParent(parent: HTMLElement | string): HTMLElement {\n if (parent instanceof HTMLElement) return parent;\n\n let el: Element | null = null;\n\n if (parent.charAt(0) === \"#\" || parent.charAt(0) === \".\") {\n el = document.querySelector(parent);\n } else {\n el =\n document.querySelector(`#${parent}`) ||\n document.querySelector(`.${parent}`) ||\n document.querySelector(parent);\n }\n\n if (!el) {\n console.warn(\n `[DOMElemJS] Parent element not found for selector: \"${parent}\". ` +\n `Falling back to document.body.`\n );\n return document.body;\n }\n\n return el as HTMLElement;\n}\n\n/**\n * Applies HTML attributes to an element from an {@link AttrsInput}.\n *\n * Handles special cases:\n * - `\"checked\"` — sets the checked property on the element.\n * - `\"dataset\"` — merges data-* attributes via `elem.dataset`.\n * - Other attributes — joined with spaces, with special characters stripped\n * for `\"class\"` and `\"id\"` when `stripDiacritics` is enabled.\n *\n * @param elem - The target element.\n * @param attrs - Attributes to apply.\n * @param stripDiacritics - Whether to strip diacritics from class/id.\n */\nfunction applyAttrs(\n elem: HTMLElement,\n attrs: AttrsInput,\n stripDiacritics: boolean\n): void {\n for (const attrObj of toArray(attrs)) {\n for (const [key, value] of Object.entries(attrObj)) {\n if (value == null) continue;\n\n if (key === \"checked\") {\n (elem as HTMLInputElement).checked = !!value;\n } else if (\n key === \"dataset\" &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n Object.assign(elem.dataset, value);\n } else {\n const rawValues = Array.isArray(value) ? value : [value];\n const values = rawValues.map((v) =>\n stripDiacritics && NO_SPEC_CHARS_ATTRS.includes(key)\n ? noSpecChars(String(v))\n : String(v)\n );\n elem.setAttribute(key, values.join(\" \"));\n }\n }\n }\n}\n\n/**\n * Applies inline CSS styles to an element from a {@link StyleInput}.\n *\n * Accepts:\n * - A CSS string: `\"color: red; font-size: 14px\"`\n * - An object: `{ color: \"red\", fontSize: \"14px\" }`\n * - An array mixing both formats\n *\n * @param elem - The target element.\n * @param style - Style input to apply.\n */\nfunction applyStyle(elem: HTMLElement, style: StyleInput): void {\n const styleParts = toArray(style)\n .map((s) => {\n if (typeof s === \"object\" && s !== null) {\n return Object.entries(s)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \");\n }\n return toArray(s).join(\"; \");\n })\n .join(\"; \");\n\n styleParts\n .split(\";\")\n .filter(Boolean)\n .forEach((styleText) => {\n const colonIndex = styleText.indexOf(\":\");\n if (colonIndex === -1) return;\n const prop = styleText.slice(0, colonIndex).trim();\n const val = styleText.slice(colonIndex + 1).trim();\n if (prop) {\n const camelProp = makeCamelCase(prop);\n (elem.style as unknown as Record<string, string>)[camelProp] = val;\n }\n });\n}\n\n/**\n * Appends child elements to a parent element.\n *\n * Each child can be either an {@link HTMLElement} or a\n * {@link CreateDOMElemOptions} object that will be recursively created.\n *\n * @param elem - The parent element to append children to.\n * @param children - Array of child elements or options.\n */\nfunction applyChildren(\n elem: HTMLElement,\n children: Array<CreateDOMElemOptions | HTMLElement>\n): void {\n for (const child of children) {\n if (child instanceof HTMLElement) {\n elem.appendChild(child);\n } else {\n elem.appendChild(createDOMElem(child));\n }\n }\n}\n\n/**\n * Attaches event listeners to an element.\n *\n * @param elem - The target element.\n * @param handleEvent - One or more {@link EventHandler} descriptors.\n */\nfunction applyEvents(\n elem: HTMLElement,\n handleEvent: CreateDOMElemOptions[\"handleEvent\"]\n): void {\n for (const evt of toArray(handleEvent)) {\n if (evt?.event && evt?.cb) {\n elem.addEventListener(evt.event, evt.cb);\n }\n }\n}\n\n/**\n * Creates a DOM element with the given configuration.\n *\n * This is the core function of DOMelemJS. It creates an HTML element,\n * applies attributes, styles, children, and event listeners, then\n * appends it to a parent element.\n *\n * @example\n * ```ts\n * const el = createDOMElem({\n * tag: \"div\",\n * text: \"Hello\",\n * attrs: { class: \"greeting\" },\n * style: { color: \"blue\" },\n * parent: \"#app\",\n * handleEvent: {\n * event: \"click\",\n * cb: () => console.log(\"clicked\"),\n * },\n * });\n * ```\n *\n * @param options - Element creation options.\n * @returns The created HTMLElement.\n */\nexport default function createDOMElem(options: CreateDOMElemOptions): HTMLElement {\n const {\n tag,\n content,\n text,\n attrs,\n style,\n children,\n parent,\n handleEvent,\n append = true,\n stripDiacritics = true,\n } = options;\n\n if (content && text) {\n console.warn(\n `[DOMElemJS] Both \"content\" and \"text\" provided for <${tag}>. ` +\n `\"text\" takes precedence — \"content\" will be ignored.`\n );\n }\n\n const elem = document.createElement(tag);\n\n if (text) {\n elem.textContent = text;\n } else if (content) {\n elem.innerHTML = content;\n }\n\n if (attrs) applyAttrs(elem, attrs, stripDiacritics);\n if (style) applyStyle(elem, style);\n if (children) applyChildren(elem, children);\n if (handleEvent) applyEvents(elem, handleEvent);\n\n if (append) {\n const target = parent ? resolveParent(parent) : document.body;\n target.appendChild(elem);\n }\n\n return elem;\n}\n","import createDOMElem from \"./createDOMElem\";\nimport type { DOMElemOptions, EventHandler } from \"./types\";\n\n/**\n * Wrapper class around {@link createDOMElem}.\n *\n * Provides an object-oriented API for creating DOM elements.\n * The created element is available via the `.elem` property.\n * Event listeners can be added and removed via `addEventListener` /\n * `removeEventListener`.\n *\n * @example\n * ```ts\n * const div = new DOMElem({\n * tag: \"div\",\n * attrs: { class: \"container\" },\n * text: \"Hello World\",\n * });\n *\n * div.addEventListener(\"click\", () => console.log(\"clicked\"));\n * div.removeEventListener(\"click\", handler);\n * ```\n */\nexport default class DOMElem {\n /** The created HTMLElement. */\n readonly elem: HTMLElement;\n\n /** The options used to create the element. */\n readonly options: DOMElemOptions;\n\n private _listeners: Map<string, Set<(e: Event) => void>> = new Map();\n\n /**\n * Creates a new DOMElem instance.\n *\n * @param options - Element creation options.\n */\n constructor(options: DOMElemOptions) {\n this.options = options;\n this.elem = createDOMElem(options);\n\n if (options.handleEvent) {\n const events = Array.isArray(options.handleEvent)\n ? options.handleEvent\n : [options.handleEvent];\n for (const evt of events) {\n this._trackListener(evt.event, evt.cb);\n }\n }\n }\n\n /**\n * Adds an event listener to the element and tracks it for later removal.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function.\n * @returns This instance for chaining.\n */\n addEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.addEventListener(event, cb);\n this._trackListener(event, cb);\n return this;\n }\n\n /**\n * Removes a previously added event listener.\n *\n * @param event - The DOM event name.\n * @param cb - The callback function to remove.\n * @returns This instance for chaining.\n */\n removeEventListener(event: string, cb: (e: Event) => void): this {\n this.elem.removeEventListener(event, cb);\n this._untrackListener(event, cb);\n return this;\n }\n\n /**\n * Removes all tracked event listeners from the element.\n */\n removeAllListeners(): void {\n for (const [event, cbs] of this._listeners) {\n for (const cb of cbs) {\n this.elem.removeEventListener(event, cb);\n }\n }\n this._listeners.clear();\n }\n\n private _trackListener(event: string, cb: (e: Event) => void): void {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set());\n }\n this._listeners.get(event)!.add(cb);\n }\n\n private _untrackListener(event: string, cb: (e: Event) => void): void {\n this._listeners.get(event)?.delete(cb);\n }\n}\n","/**\n * List of standard HTML tag names.\n *\n * Provided as a `const` tuple so TypeScript can infer literal types\n * (e.g. `\"div\"` instead of `string`).\n *\n * @example\n * import { HTML_TAGS } from \"domelemjs\";\n * if (HTML_TAGS.includes(tag as HtmlTagConst)) { ... }\n */\nexport const HTML_TAGS = [\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\",\n \"b\", \"base\", \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\",\n \"canvas\", \"caption\", \"cite\", \"code\", \"col\", \"colgroup\",\n \"data\", \"datalist\", \"dd\", \"del\", \"details\", \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\",\n \"em\", \"embed\",\n \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hr\", \"html\",\n \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\",\n \"label\", \"legend\", \"li\", \"link\",\n \"main\", \"map\", \"mark\", \"meta\", \"meter\",\n \"nav\", \"noscript\",\n \"object\", \"ol\", \"optgroup\", \"option\", \"output\",\n \"p\", \"param\", \"picture\", \"pre\", \"progress\",\n \"q\",\n \"rp\", \"rt\", \"ruby\",\n \"s\", \"samp\", \"script\", \"section\", \"select\", \"small\", \"source\", \"span\",\n \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"svg\",\n \"table\", \"tbody\", \"td\", \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\",\n \"time\", \"title\", \"tr\", \"track\",\n \"u\", \"ul\",\n \"video\",\n \"wbr\",\n] as const;\n\n/** Union type of all valid HTML tag name literals. */\nexport type HtmlTagConst = (typeof HTML_TAGS)[number];\n"],"mappings":"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","names":["makeCamelCase","s","part","i","toArray","value","noSpecChars","text","lowercase","map","result","char","replacement","NO_SPEC_CHARS_ATTRS","resolveParent","parent","el","applyAttrs","elem","attrs","stripDiacritics","attrObj","toArray","key","value","values","v","noSpecChars","applyStyle","style","s","k","styleText","colonIndex","prop","val","camelProp","makeCamelCase","applyChildren","children","child","createDOMElem","applyEvents","handleEvent","evt","options","tag","content","text","append","DOMElem","options","createDOMElem","events","evt","event","cb","cbs","HTML_TAGS"]}
|
package/package.json
CHANGED
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "domelemjs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A lightweight, zero-dependency TypeScript library for dynamically creating HTML elements from JavaScript.",
|
|
6
|
+
"sideEffects": false,
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
|
-
"module": "./dist/index.
|
|
8
|
+
"module": "./dist/index.js",
|
|
8
9
|
"types": "./dist/index.d.ts",
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
12
|
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.
|
|
13
|
-
"require": "./dist/index.
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
14
15
|
}
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"dist",
|
|
18
19
|
"README.md",
|
|
20
|
+
"README-hu.md",
|
|
19
21
|
"LICENSE"
|
|
20
22
|
],
|
|
21
23
|
"scripts": {
|
|
22
24
|
"build": "tsup",
|
|
23
25
|
"dev": "tsup --watch",
|
|
24
26
|
"typecheck": "tsc --noEmit",
|
|
25
|
-
"
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"lint": "eslint src/",
|
|
30
|
+
"lint:fix": "eslint src/ --fix",
|
|
31
|
+
"format": "prettier --write src/",
|
|
32
|
+
"format:check": "prettier --check src/",
|
|
33
|
+
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
|
|
26
34
|
},
|
|
27
35
|
"repository": {
|
|
28
36
|
"type": "git",
|
|
@@ -42,7 +50,14 @@
|
|
|
42
50
|
},
|
|
43
51
|
"homepage": "https://github.com/exphoenee/DOMelemJS#readme",
|
|
44
52
|
"devDependencies": {
|
|
53
|
+
"@eslint/js": "^9.0.0",
|
|
54
|
+
"eslint": "^9.0.0",
|
|
55
|
+
"globals": "^15.0.0",
|
|
56
|
+
"jsdom": "^24.0.0",
|
|
57
|
+
"prettier": "^3.2.0",
|
|
45
58
|
"tsup": "^8.0.0",
|
|
46
|
-
"typescript": "^5.3.0"
|
|
59
|
+
"typescript": "^5.3.0",
|
|
60
|
+
"typescript-eslint": "^8.0.0",
|
|
61
|
+
"vitest": "^1.2.0"
|
|
47
62
|
}
|
|
48
|
-
}
|
|
63
|
+
}
|