@hypen-space/web 0.2.12 → 0.3.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/dist/src/canvas/index.js.map +1 -1
- package/dist/src/canvas/renderer.js.map +1 -1
- package/dist/src/dom/applicators/effects.js +38 -2
- package/dist/src/dom/applicators/effects.js.map +3 -3
- package/dist/src/dom/applicators/events.js +280 -397
- package/dist/src/dom/applicators/events.js.map +5 -4
- package/dist/src/dom/applicators/font.js +94 -5
- package/dist/src/dom/applicators/font.js.map +3 -3
- package/dist/src/dom/applicators/index.js +590 -425
- package/dist/src/dom/applicators/index.js.map +10 -9
- package/dist/src/dom/applicators/layout.js +33 -5
- package/dist/src/dom/applicators/layout.js.map +3 -3
- package/dist/src/dom/applicators/size.js +81 -16
- package/dist/src/dom/applicators/size.js.map +3 -3
- package/dist/src/dom/components/hypenapp.js +296 -0
- package/dist/src/dom/components/hypenapp.js.map +10 -0
- package/dist/src/dom/components/index.js +263 -1
- package/dist/src/dom/components/index.js.map +5 -4
- package/dist/src/dom/element-data.js +140 -0
- package/dist/src/dom/element-data.js.map +10 -0
- package/dist/src/dom/index.js +857 -430
- package/dist/src/dom/index.js.map +13 -11
- package/dist/src/dom/renderer.js +857 -430
- package/dist/src/dom/renderer.js.map +13 -11
- package/dist/src/hypen.js +857 -430
- package/dist/src/hypen.js.map +13 -11
- package/dist/src/index.js +862 -430
- package/dist/src/index.js.map +15 -12
- package/package.json +3 -3
- package/src/canvas/QUICKSTART.md +5 -7
- package/src/canvas/README.md +2 -2
- package/src/canvas/renderer.ts +1 -1
- package/src/dom/README.md +4 -4
- package/src/dom/applicators/effects.ts +45 -1
- package/src/dom/applicators/events.ts +348 -537
- package/src/dom/applicators/font.ts +127 -2
- package/src/dom/applicators/index.ts +117 -7
- package/src/dom/applicators/layout.ts +40 -4
- package/src/dom/applicators/size.ts +101 -16
- package/src/dom/components/hypenapp.ts +348 -0
- package/src/dom/components/index.ts +2 -0
- package/src/dom/element-data.ts +234 -0
- package/src/dom/renderer.ts +12 -9
- package/src/index.ts +5 -2
|
@@ -170,43 +170,108 @@ var exports_size = {};
|
|
|
170
170
|
__export(exports_size, {
|
|
171
171
|
sizeHandlers: () => sizeHandlers
|
|
172
172
|
});
|
|
173
|
+
function parseSizeValue(value) {
|
|
174
|
+
if (value === null || value === undefined)
|
|
175
|
+
return null;
|
|
176
|
+
if (typeof value === "number") {
|
|
177
|
+
return `${value}px`;
|
|
178
|
+
}
|
|
179
|
+
const str = String(value).trim().toLowerCase();
|
|
180
|
+
switch (str) {
|
|
181
|
+
case "fill":
|
|
182
|
+
case "match_parent":
|
|
183
|
+
return "100%";
|
|
184
|
+
case "wrap":
|
|
185
|
+
case "wrap_content":
|
|
186
|
+
case "auto":
|
|
187
|
+
return "auto";
|
|
188
|
+
case "infinity":
|
|
189
|
+
case "inf":
|
|
190
|
+
case "max":
|
|
191
|
+
return "100%";
|
|
192
|
+
}
|
|
193
|
+
const match = str.match(/^(-?[\d.]+)\s*(px|dp|pt|%|vw|vh|vmin|vmax|em|rem)?$/);
|
|
194
|
+
if (!match) {
|
|
195
|
+
return str;
|
|
196
|
+
}
|
|
197
|
+
const num = parseFloat(match[1]);
|
|
198
|
+
const unit = match[2] || "px";
|
|
199
|
+
switch (unit) {
|
|
200
|
+
case "px":
|
|
201
|
+
return `${num}px`;
|
|
202
|
+
case "dp":
|
|
203
|
+
case "pt":
|
|
204
|
+
return `${num}px`;
|
|
205
|
+
case "%":
|
|
206
|
+
return `${num}%`;
|
|
207
|
+
case "vw":
|
|
208
|
+
return `${num}vw`;
|
|
209
|
+
case "vh":
|
|
210
|
+
return `${num}vh`;
|
|
211
|
+
case "vmin":
|
|
212
|
+
return `${num}vmin`;
|
|
213
|
+
case "vmax":
|
|
214
|
+
return `${num}vmax`;
|
|
215
|
+
case "em":
|
|
216
|
+
return `${num}em`;
|
|
217
|
+
case "rem":
|
|
218
|
+
return `${num}rem`;
|
|
219
|
+
default:
|
|
220
|
+
return `${num}px`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
173
223
|
var sizeHandlers;
|
|
174
224
|
var init_size = __esm(() => {
|
|
175
225
|
sizeHandlers = {
|
|
176
226
|
width: (el, value) => {
|
|
177
|
-
|
|
227
|
+
const size = parseSizeValue(value);
|
|
228
|
+
if (size)
|
|
229
|
+
el.style.width = size;
|
|
178
230
|
},
|
|
179
231
|
height: (el, value) => {
|
|
180
|
-
|
|
232
|
+
const size = parseSizeValue(value);
|
|
233
|
+
if (size)
|
|
234
|
+
el.style.height = size;
|
|
181
235
|
},
|
|
182
236
|
minWidth: (el, value) => {
|
|
183
|
-
|
|
237
|
+
const size = parseSizeValue(value);
|
|
238
|
+
if (size)
|
|
239
|
+
el.style.minWidth = size;
|
|
184
240
|
},
|
|
185
241
|
minHeight: (el, value) => {
|
|
186
|
-
|
|
242
|
+
const size = parseSizeValue(value);
|
|
243
|
+
if (size)
|
|
244
|
+
el.style.minHeight = size;
|
|
187
245
|
},
|
|
188
246
|
maxWidth: (el, value) => {
|
|
189
|
-
|
|
247
|
+
const size = parseSizeValue(value);
|
|
248
|
+
if (size)
|
|
249
|
+
el.style.maxWidth = size;
|
|
190
250
|
},
|
|
191
251
|
maxHeight: (el, value) => {
|
|
192
|
-
|
|
252
|
+
const size = parseSizeValue(value);
|
|
253
|
+
if (size)
|
|
254
|
+
el.style.maxHeight = size;
|
|
193
255
|
},
|
|
194
256
|
size: (el, value) => {
|
|
195
|
-
if (typeof value === "
|
|
196
|
-
el.style.width = `${value}px`;
|
|
197
|
-
el.style.height = `${value}px`;
|
|
198
|
-
} else if (typeof value === "object" && value !== null) {
|
|
257
|
+
if (typeof value === "object" && value !== null) {
|
|
199
258
|
const obj = value;
|
|
200
259
|
if (obj.width !== undefined) {
|
|
201
|
-
|
|
260
|
+
const w = parseSizeValue(obj.width);
|
|
261
|
+
if (w)
|
|
262
|
+
el.style.width = w;
|
|
202
263
|
}
|
|
203
264
|
if (obj.height !== undefined) {
|
|
204
|
-
|
|
265
|
+
const h = parseSizeValue(obj.height);
|
|
266
|
+
if (h)
|
|
267
|
+
el.style.height = h;
|
|
205
268
|
}
|
|
206
269
|
} else {
|
|
207
|
-
const size =
|
|
208
|
-
|
|
209
|
-
|
|
270
|
+
const size = parseSizeValue(value);
|
|
271
|
+
if (size) {
|
|
272
|
+
el.style.width = size;
|
|
273
|
+
el.style.height = size;
|
|
274
|
+
}
|
|
210
275
|
}
|
|
211
276
|
},
|
|
212
277
|
fillMaxWidth: (el, value) => {
|
|
@@ -234,10 +299,64 @@ var init_size = __esm(() => {
|
|
|
234
299
|
// src/dom/applicators/font.ts
|
|
235
300
|
var exports_font = {};
|
|
236
301
|
__export(exports_font, {
|
|
237
|
-
fontHandlers: () => fontHandlers
|
|
302
|
+
fontHandlers: () => fontHandlers,
|
|
303
|
+
GoogleFonts: () => GoogleFonts
|
|
238
304
|
});
|
|
239
|
-
|
|
305
|
+
function isSystemFont(fontName) {
|
|
306
|
+
const normalized = fontName.toLowerCase().trim();
|
|
307
|
+
return systemFontKeywords.has(normalized) || normalized.startsWith("-") || normalized.startsWith("ui-");
|
|
308
|
+
}
|
|
309
|
+
function loadGoogleFont(fontName) {
|
|
310
|
+
const normalized = fontName.trim();
|
|
311
|
+
if (loadedGoogleFonts.has(normalized) || isSystemFont(normalized)) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
loadedGoogleFonts.add(normalized);
|
|
315
|
+
const link = document.createElement("link");
|
|
316
|
+
link.rel = "stylesheet";
|
|
317
|
+
link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(normalized)}:wght@100;200;300;400;500;600;700;800;900&display=swap`;
|
|
318
|
+
document.head.appendChild(link);
|
|
319
|
+
}
|
|
320
|
+
function processFontFamily(value) {
|
|
321
|
+
const fonts = value.split(",").map((f) => f.trim().replace(/["']/g, ""));
|
|
322
|
+
for (const font of fonts) {
|
|
323
|
+
if (!isSystemFont(font)) {
|
|
324
|
+
loadGoogleFont(font);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return fonts.map((f) => {
|
|
328
|
+
if (f.includes(" ") && !f.startsWith('"') && !f.startsWith("'")) {
|
|
329
|
+
return `"${f}"`;
|
|
330
|
+
}
|
|
331
|
+
return f;
|
|
332
|
+
}).join(", ");
|
|
333
|
+
}
|
|
334
|
+
var loadedGoogleFonts, systemFontKeywords, fontHandlers, GoogleFonts;
|
|
240
335
|
var init_font = __esm(() => {
|
|
336
|
+
loadedGoogleFonts = new Set;
|
|
337
|
+
systemFontKeywords = new Set([
|
|
338
|
+
"default",
|
|
339
|
+
"system",
|
|
340
|
+
"system-ui",
|
|
341
|
+
"inherit",
|
|
342
|
+
"initial",
|
|
343
|
+
"unset",
|
|
344
|
+
"serif",
|
|
345
|
+
"sans-serif",
|
|
346
|
+
"monospace",
|
|
347
|
+
"cursive",
|
|
348
|
+
"fantasy",
|
|
349
|
+
"-apple-system",
|
|
350
|
+
"BlinkMacSystemFont",
|
|
351
|
+
"Segoe UI",
|
|
352
|
+
"Arial",
|
|
353
|
+
"Helvetica",
|
|
354
|
+
"Times New Roman",
|
|
355
|
+
"Georgia",
|
|
356
|
+
"Courier New",
|
|
357
|
+
"Verdana",
|
|
358
|
+
"Tahoma"
|
|
359
|
+
]);
|
|
241
360
|
fontHandlers = {
|
|
242
361
|
fontSize: (el, value) => {
|
|
243
362
|
el.style.fontSize = typeof value === "number" ? `${value}px` : String(value);
|
|
@@ -246,15 +365,49 @@ var init_font = __esm(() => {
|
|
|
246
365
|
el.style.fontWeight = String(value);
|
|
247
366
|
},
|
|
248
367
|
fontFamily: (el, value) => {
|
|
249
|
-
|
|
368
|
+
const fontValue = String(value);
|
|
369
|
+
el.style.fontFamily = processFontFamily(fontValue);
|
|
250
370
|
},
|
|
251
371
|
textAlign: (el, value) => {
|
|
252
372
|
el.style.textAlign = String(value);
|
|
253
373
|
},
|
|
254
374
|
lineHeight: (el, value) => {
|
|
255
375
|
el.style.lineHeight = String(value);
|
|
376
|
+
},
|
|
377
|
+
fontStyle: (el, value) => {
|
|
378
|
+
el.style.fontStyle = String(value);
|
|
379
|
+
},
|
|
380
|
+
textTransform: (el, value) => {
|
|
381
|
+
el.style.textTransform = String(value);
|
|
256
382
|
}
|
|
257
383
|
};
|
|
384
|
+
GoogleFonts = {
|
|
385
|
+
preload: loadGoogleFont,
|
|
386
|
+
isLoaded: (fontName) => loadedGoogleFonts.has(fontName.trim()),
|
|
387
|
+
getLoadedFonts: () => Array.from(loadedGoogleFonts),
|
|
388
|
+
popular: [
|
|
389
|
+
"Roboto",
|
|
390
|
+
"Open Sans",
|
|
391
|
+
"Lato",
|
|
392
|
+
"Montserrat",
|
|
393
|
+
"Poppins",
|
|
394
|
+
"Inter",
|
|
395
|
+
"Nunito",
|
|
396
|
+
"Playfair Display",
|
|
397
|
+
"Merriweather",
|
|
398
|
+
"Source Code Pro",
|
|
399
|
+
"Fira Code",
|
|
400
|
+
"JetBrains Mono",
|
|
401
|
+
"Raleway",
|
|
402
|
+
"Ubuntu",
|
|
403
|
+
"Oswald",
|
|
404
|
+
"Quicksand",
|
|
405
|
+
"Work Sans",
|
|
406
|
+
"Rubik",
|
|
407
|
+
"Karla",
|
|
408
|
+
"DM Sans"
|
|
409
|
+
]
|
|
410
|
+
};
|
|
258
411
|
});
|
|
259
412
|
|
|
260
413
|
// src/dom/applicators/layout.ts
|
|
@@ -262,11 +415,39 @@ var exports_layout = {};
|
|
|
262
415
|
__export(exports_layout, {
|
|
263
416
|
layoutHandlers: () => layoutHandlers
|
|
264
417
|
});
|
|
418
|
+
function mapAlignmentValue(value) {
|
|
419
|
+
const v = String(value).toLowerCase();
|
|
420
|
+
switch (v) {
|
|
421
|
+
case "top":
|
|
422
|
+
case "start":
|
|
423
|
+
case "leading":
|
|
424
|
+
case "left":
|
|
425
|
+
return "flex-start";
|
|
426
|
+
case "bottom":
|
|
427
|
+
case "end":
|
|
428
|
+
case "trailing":
|
|
429
|
+
case "right":
|
|
430
|
+
return "flex-end";
|
|
431
|
+
case "center":
|
|
432
|
+
return "center";
|
|
433
|
+
case "spacebetween":
|
|
434
|
+
case "space-between":
|
|
435
|
+
return "space-between";
|
|
436
|
+
case "spacearound":
|
|
437
|
+
case "space-around":
|
|
438
|
+
return "space-around";
|
|
439
|
+
case "spaceevenly":
|
|
440
|
+
case "space-evenly":
|
|
441
|
+
return "space-evenly";
|
|
442
|
+
default:
|
|
443
|
+
return v;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
265
446
|
var layoutHandlers;
|
|
266
447
|
var init_layout = __esm(() => {
|
|
267
448
|
layoutHandlers = {
|
|
268
449
|
verticalAlignment: (el, value) => {
|
|
269
|
-
const val = String(value);
|
|
450
|
+
const val = mapAlignmentValue(String(value));
|
|
270
451
|
const flexDirection = getComputedStyle(el).flexDirection;
|
|
271
452
|
if (flexDirection === "column" || flexDirection === "column-reverse") {
|
|
272
453
|
el.style.justifyContent = val;
|
|
@@ -275,7 +456,7 @@ var init_layout = __esm(() => {
|
|
|
275
456
|
}
|
|
276
457
|
},
|
|
277
458
|
horizontalAlignment: (el, value) => {
|
|
278
|
-
const val = String(value);
|
|
459
|
+
const val = mapAlignmentValue(String(value));
|
|
279
460
|
const flexDirection = getComputedStyle(el).flexDirection;
|
|
280
461
|
if (flexDirection === "column" || flexDirection === "column-reverse") {
|
|
281
462
|
el.style.alignItems = val;
|
|
@@ -284,10 +465,10 @@ var init_layout = __esm(() => {
|
|
|
284
465
|
}
|
|
285
466
|
},
|
|
286
467
|
horizontalAlign: (el, value) => {
|
|
287
|
-
el.style.justifyContent = String(value);
|
|
468
|
+
el.style.justifyContent = mapAlignmentValue(String(value));
|
|
288
469
|
},
|
|
289
470
|
verticalAlign: (el, value) => {
|
|
290
|
-
el.style.alignItems = String(value);
|
|
471
|
+
el.style.alignItems = mapAlignmentValue(String(value));
|
|
291
472
|
},
|
|
292
473
|
gap: (el, value) => {
|
|
293
474
|
el.style.gap = typeof value === "number" ? `${value}px` : String(value);
|
|
@@ -330,11 +511,105 @@ var init_layout = __esm(() => {
|
|
|
330
511
|
};
|
|
331
512
|
});
|
|
332
513
|
|
|
514
|
+
// src/dom/element-data.ts
|
|
515
|
+
import { getElementDisposables } from "@hypen-space/core";
|
|
516
|
+
function getHypenData(element) {
|
|
517
|
+
let data = elementDataMap.get(element);
|
|
518
|
+
if (!data) {
|
|
519
|
+
data = {};
|
|
520
|
+
elementDataMap.set(element, data);
|
|
521
|
+
}
|
|
522
|
+
return data;
|
|
523
|
+
}
|
|
524
|
+
function hasHypenData(element) {
|
|
525
|
+
return elementDataMap.has(element);
|
|
526
|
+
}
|
|
527
|
+
function clearHypenData(element) {
|
|
528
|
+
elementDataMap.delete(element);
|
|
529
|
+
}
|
|
530
|
+
function getEngine(element) {
|
|
531
|
+
return getHypenData(element).engine;
|
|
532
|
+
}
|
|
533
|
+
function setEngine(element, engine) {
|
|
534
|
+
getHypenData(element).engine = engine;
|
|
535
|
+
}
|
|
536
|
+
function findEngine(element) {
|
|
537
|
+
let current = element;
|
|
538
|
+
while (current) {
|
|
539
|
+
const engine = getEngine(current);
|
|
540
|
+
if (engine)
|
|
541
|
+
return engine;
|
|
542
|
+
current = current.parentElement;
|
|
543
|
+
}
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
function getRegisteredEvents(element) {
|
|
547
|
+
const data = getHypenData(element);
|
|
548
|
+
if (!data.registeredEvents) {
|
|
549
|
+
data.registeredEvents = new Set;
|
|
550
|
+
}
|
|
551
|
+
return data.registeredEvents;
|
|
552
|
+
}
|
|
553
|
+
function isEventRegistered(element, eventKey) {
|
|
554
|
+
return getRegisteredEvents(element).has(eventKey);
|
|
555
|
+
}
|
|
556
|
+
function registerEvent(element, eventKey) {
|
|
557
|
+
getRegisteredEvents(element).add(eventKey);
|
|
558
|
+
}
|
|
559
|
+
function unregisterEvent(element, eventKey) {
|
|
560
|
+
getRegisteredEvents(element).delete(eventKey);
|
|
561
|
+
}
|
|
562
|
+
function getKeyTarget(element) {
|
|
563
|
+
return getHypenData(element).keyTarget;
|
|
564
|
+
}
|
|
565
|
+
function setKeyTarget(element, key) {
|
|
566
|
+
getHypenData(element).keyTarget = key;
|
|
567
|
+
}
|
|
568
|
+
function getMeta(element, key) {
|
|
569
|
+
return getHypenData(element).meta?.[key];
|
|
570
|
+
}
|
|
571
|
+
function setMeta(element, key, value) {
|
|
572
|
+
const data = getHypenData(element);
|
|
573
|
+
if (!data.meta) {
|
|
574
|
+
data.meta = {};
|
|
575
|
+
}
|
|
576
|
+
data.meta[key] = value;
|
|
577
|
+
}
|
|
578
|
+
function disposeHypenElement(element) {
|
|
579
|
+
try {
|
|
580
|
+
const disposables = getElementDisposables(element);
|
|
581
|
+
disposables.dispose();
|
|
582
|
+
} catch {}
|
|
583
|
+
clearHypenData(element);
|
|
584
|
+
}
|
|
585
|
+
function getLegacyEngine(element) {
|
|
586
|
+
const engine = getEngine(element);
|
|
587
|
+
if (engine)
|
|
588
|
+
return engine;
|
|
589
|
+
return element[HYPEN_ENGINE_SYMBOL] ?? element.__hypenEngine;
|
|
590
|
+
}
|
|
591
|
+
function setLegacyEngine(element, engine) {
|
|
592
|
+
setEngine(element, engine);
|
|
593
|
+
element.__hypenEngine = engine;
|
|
594
|
+
}
|
|
595
|
+
var elementDataMap, HYPEN_ENGINE_SYMBOL, REGISTERED_EVENTS_SYMBOL, KEY_TARGET_SYMBOL;
|
|
596
|
+
var init_element_data = __esm(() => {
|
|
597
|
+
elementDataMap = new WeakMap;
|
|
598
|
+
HYPEN_ENGINE_SYMBOL = Symbol.for("hypen.engine");
|
|
599
|
+
REGISTERED_EVENTS_SYMBOL = Symbol.for("hypen.registeredEvents");
|
|
600
|
+
KEY_TARGET_SYMBOL = Symbol.for("hypen.keyTarget");
|
|
601
|
+
});
|
|
602
|
+
|
|
333
603
|
// src/dom/applicators/events.ts
|
|
334
604
|
var exports_events = {};
|
|
335
605
|
__export(exports_events, {
|
|
336
606
|
eventHandlers: () => eventHandlers
|
|
337
607
|
});
|
|
608
|
+
import {
|
|
609
|
+
getElementDisposables as getElementDisposables2,
|
|
610
|
+
disposableListener,
|
|
611
|
+
disposableTimeout
|
|
612
|
+
} from "@hypen-space/core";
|
|
338
613
|
function toPlainObject(value) {
|
|
339
614
|
if (value instanceof Map) {
|
|
340
615
|
const obj = {};
|
|
@@ -380,7 +655,13 @@ function extractActionDetails(value) {
|
|
|
380
655
|
}
|
|
381
656
|
for (const [key, val] of Object.entries(plain)) {
|
|
382
657
|
if (key !== "0") {
|
|
383
|
-
|
|
658
|
+
if (/^\d+$/.test(key) && val && typeof val === "object" && !Array.isArray(val)) {
|
|
659
|
+
for (const [innerKey, innerVal] of Object.entries(val)) {
|
|
660
|
+
payload[innerKey] = innerVal;
|
|
661
|
+
}
|
|
662
|
+
} else {
|
|
663
|
+
payload[key] = val;
|
|
664
|
+
}
|
|
384
665
|
}
|
|
385
666
|
}
|
|
386
667
|
}
|
|
@@ -418,420 +699,203 @@ function extractEventData(event, element) {
|
|
|
418
699
|
}
|
|
419
700
|
return data;
|
|
420
701
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
console.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : extractEventData(event, element);
|
|
438
|
-
console.log(`[EventApplicator] onClick payload:`, payload);
|
|
439
|
-
const engine = element.__hypenEngine;
|
|
440
|
-
if (engine) {
|
|
441
|
-
engine.dispatchAction(actionName, payload);
|
|
442
|
-
} else {
|
|
443
|
-
console.warn(`[EventApplicator] No engine attached to element for onClick`);
|
|
444
|
-
}
|
|
445
|
-
};
|
|
446
|
-
element.__hypenClickListener = listener;
|
|
447
|
-
element.addEventListener("click", listener);
|
|
448
|
-
console.log(`[EventApplicator] onClick handler attached for action: ${actionName}`);
|
|
449
|
-
},
|
|
450
|
-
onPress: (element, value) => {
|
|
451
|
-
eventHandlers.onClick(element, value);
|
|
452
|
-
},
|
|
453
|
-
onChange: (element, value) => {
|
|
454
|
-
const { actionName } = extractActionDetails(value);
|
|
455
|
-
if (!actionName) {
|
|
456
|
-
console.warn(`[EventApplicator] onChange value must be an action reference starting with @, got:`, value);
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
const existingListener = element.__hypenChangeListener;
|
|
460
|
-
if (existingListener) {
|
|
461
|
-
element.removeEventListener("change", existingListener);
|
|
462
|
-
}
|
|
463
|
-
const listener = (event) => {
|
|
464
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onChange fired, dispatching action: ${actionName}`);
|
|
465
|
-
const payload = extractEventData(event, element);
|
|
466
|
-
const engine = element.__hypenEngine;
|
|
467
|
-
if (engine) {
|
|
468
|
-
engine.dispatchAction(actionName, payload);
|
|
469
|
-
} else {
|
|
470
|
-
console.warn(`[EventApplicator] No engine attached to element for onChange`);
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
element.__hypenChangeListener = listener;
|
|
474
|
-
element.addEventListener("change", listener);
|
|
475
|
-
console.log(`[EventApplicator] onChange handler attached for action: ${actionName}`);
|
|
476
|
-
},
|
|
477
|
-
onSubmit: (element, value) => {
|
|
478
|
-
const { actionName } = extractActionDetails(value);
|
|
479
|
-
if (!actionName) {
|
|
480
|
-
console.warn(`[EventApplicator] onSubmit value must be an action reference starting with @, got:`, value);
|
|
702
|
+
function createEventHandler(eventType, options = {}) {
|
|
703
|
+
return (element, value) => {
|
|
704
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
705
|
+
if (!actionName) {
|
|
706
|
+
console.warn(`[EventApplicator] ${eventType} requires an action reference starting with @, got:`, value);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const disposables = getElementDisposables2(element);
|
|
710
|
+
const eventKey = `${eventType}:${actionName}`;
|
|
711
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
registerEvent(element, eventKey);
|
|
715
|
+
let throttleTimer = null;
|
|
716
|
+
const listener = (event) => {
|
|
717
|
+
if (options.throttleMs && throttleTimer) {
|
|
481
718
|
return;
|
|
482
719
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
720
|
+
if (options.throttleMs) {
|
|
721
|
+
throttleTimer = disposableTimeout(() => {
|
|
722
|
+
throttleTimer = null;
|
|
723
|
+
}, options.throttleMs);
|
|
486
724
|
}
|
|
487
|
-
|
|
488
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onSubmit fired, dispatching action: ${actionName}`);
|
|
725
|
+
if (options.preventDefault) {
|
|
489
726
|
event.preventDefault();
|
|
490
|
-
const payload = extractEventData(event, element);
|
|
491
|
-
const engine = element.__hypenEngine;
|
|
492
|
-
if (engine) {
|
|
493
|
-
engine.dispatchAction(actionName, payload);
|
|
494
|
-
} else {
|
|
495
|
-
console.warn(`[EventApplicator] No engine attached to element for onSubmit`);
|
|
496
|
-
}
|
|
497
|
-
};
|
|
498
|
-
element.__hypenSubmitListener = listener;
|
|
499
|
-
element.addEventListener("submit", listener);
|
|
500
|
-
console.log(`[EventApplicator] onSubmit handler attached for action: ${actionName}`);
|
|
501
|
-
},
|
|
502
|
-
onInput: (element, value) => {
|
|
503
|
-
console.log(`[EventApplicator] onInput called with value:`, value);
|
|
504
|
-
const { actionName } = extractActionDetails(value);
|
|
505
|
-
if (!actionName) {
|
|
506
|
-
console.warn(`[EventApplicator] onInput value must be an action reference starting with @, got:`, value);
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
const existingListener = element.__hypenInputListener;
|
|
510
|
-
if (existingListener) {
|
|
511
|
-
element.removeEventListener("input", existingListener);
|
|
512
727
|
}
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
type: event.type,
|
|
518
|
-
timestamp: Date.now(),
|
|
519
|
-
value: target.value,
|
|
520
|
-
input: target.value
|
|
521
|
-
};
|
|
522
|
-
console.log(`[EventApplicator] onInput payload:`, payload);
|
|
523
|
-
const engine = element.__hypenEngine;
|
|
524
|
-
if (engine) {
|
|
525
|
-
engine.dispatchAction(actionName, payload);
|
|
526
|
-
} else {
|
|
527
|
-
console.warn(`[EventApplicator] No engine attached to element for onInput`);
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
element.__hypenInputListener = listener;
|
|
531
|
-
element.addEventListener("input", listener);
|
|
532
|
-
console.log(`[EventApplicator] onInput handler attached for action: ${actionName}`);
|
|
533
|
-
},
|
|
534
|
-
onKey: (element, value) => {
|
|
535
|
-
console.log(`[EventApplicator] onKey called with value:`, value);
|
|
536
|
-
const { actionName } = extractActionDetails(value);
|
|
537
|
-
if (actionName) {
|
|
538
|
-
const existingListener = element.__hypenKeyListener;
|
|
539
|
-
if (existingListener) {
|
|
540
|
-
element.removeEventListener("keydown", existingListener);
|
|
541
|
-
}
|
|
542
|
-
const listener = (event) => {
|
|
543
|
-
if (event.key === "Enter") {
|
|
544
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (Enter), dispatching action: ${actionName}`);
|
|
545
|
-
event.preventDefault();
|
|
546
|
-
const target = event.target;
|
|
547
|
-
const payload = {
|
|
548
|
-
type: event.type,
|
|
549
|
-
timestamp: Date.now(),
|
|
550
|
-
key: event.key,
|
|
551
|
-
code: event.code,
|
|
552
|
-
value: target.value,
|
|
553
|
-
input: target.value,
|
|
554
|
-
ctrlKey: event.ctrlKey,
|
|
555
|
-
shiftKey: event.shiftKey,
|
|
556
|
-
altKey: event.altKey,
|
|
557
|
-
metaKey: event.metaKey
|
|
558
|
-
};
|
|
559
|
-
const engine = element.__hypenEngine;
|
|
560
|
-
if (engine) {
|
|
561
|
-
engine.dispatchAction(actionName, payload);
|
|
562
|
-
} else {
|
|
563
|
-
console.warn(`[EventApplicator] No engine attached to element for onKey`);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
element.__hypenKeyListener = listener;
|
|
568
|
-
element.addEventListener("keydown", listener);
|
|
569
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} (triggers on Enter)`);
|
|
570
|
-
} else {
|
|
571
|
-
console.warn(`[EventApplicator] onKey value must be an action reference starting with @, got: ${value}`);
|
|
728
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : options.extractPayload ? options.extractPayload(event, element) : extractEventData(event, element);
|
|
729
|
+
const engine = getEngine(element);
|
|
730
|
+
if (engine) {
|
|
731
|
+
engine.dispatchAction(actionName, payload);
|
|
572
732
|
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
if (actionName) {
|
|
582
|
-
const targetKey = element.__hypenKeyTarget || "Enter";
|
|
583
|
-
const existingListener = element.__hypenKeyListener;
|
|
584
|
-
if (existingListener) {
|
|
585
|
-
element.removeEventListener("keydown", existingListener);
|
|
586
|
-
}
|
|
587
|
-
const listener = (event) => {
|
|
588
|
-
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
589
|
-
if (event.key === keyToMatch) {
|
|
590
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (${keyToMatch}), dispatching action: ${actionName}`);
|
|
591
|
-
event.preventDefault();
|
|
592
|
-
const target = event.target;
|
|
593
|
-
const payload = {
|
|
594
|
-
type: event.type,
|
|
595
|
-
timestamp: Date.now(),
|
|
596
|
-
key: event.key,
|
|
597
|
-
code: event.code,
|
|
598
|
-
value: target.value,
|
|
599
|
-
input: target.value,
|
|
600
|
-
ctrlKey: event.ctrlKey,
|
|
601
|
-
shiftKey: event.shiftKey,
|
|
602
|
-
altKey: event.altKey,
|
|
603
|
-
metaKey: event.metaKey
|
|
604
|
-
};
|
|
605
|
-
const engine = element.__hypenEngine;
|
|
606
|
-
if (engine) {
|
|
607
|
-
engine.dispatchAction(actionName, payload);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
};
|
|
611
|
-
element.__hypenKeyListener = listener;
|
|
612
|
-
element.addEventListener("keydown", listener);
|
|
613
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} on key: ${targetKey}`);
|
|
614
|
-
}
|
|
615
|
-
},
|
|
616
|
-
onScroll: (element, value) => {
|
|
617
|
-
console.log(`[EventApplicator] onScroll called with value:`, value);
|
|
618
|
-
const { actionName } = extractActionDetails(value);
|
|
619
|
-
if (actionName) {
|
|
620
|
-
const existingListener = element.__hypenScrollListener;
|
|
621
|
-
if (existingListener) {
|
|
622
|
-
element.removeEventListener("scroll", existingListener);
|
|
623
|
-
}
|
|
624
|
-
let throttleTimer = null;
|
|
625
|
-
const listener = (event) => {
|
|
626
|
-
if (throttleTimer)
|
|
627
|
-
return;
|
|
628
|
-
throttleTimer = setTimeout(() => {
|
|
629
|
-
throttleTimer = null;
|
|
630
|
-
}, 100);
|
|
631
|
-
const target = event.target;
|
|
632
|
-
const scrollTop = target.scrollTop;
|
|
633
|
-
const scrollHeight = target.scrollHeight;
|
|
634
|
-
const clientHeight = target.clientHeight;
|
|
635
|
-
const scrollPercentage = scrollTop / (scrollHeight - clientHeight) * 100;
|
|
636
|
-
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
637
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onScroll fired, scrollTop: ${scrollTop}, nearBottom: ${nearBottom}`);
|
|
638
|
-
const payload = {
|
|
639
|
-
type: "scroll",
|
|
640
|
-
timestamp: Date.now(),
|
|
641
|
-
scrollTop,
|
|
642
|
-
scrollLeft: target.scrollLeft,
|
|
643
|
-
scrollHeight,
|
|
644
|
-
scrollWidth: target.scrollWidth,
|
|
645
|
-
clientHeight,
|
|
646
|
-
clientWidth: target.clientWidth,
|
|
647
|
-
scrollPercentage: Math.round(scrollPercentage),
|
|
648
|
-
nearBottom,
|
|
649
|
-
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
650
|
-
atTop: scrollTop === 0
|
|
651
|
-
};
|
|
652
|
-
const engine = element.__hypenEngine;
|
|
653
|
-
if (engine) {
|
|
654
|
-
engine.dispatchAction(actionName, payload);
|
|
655
|
-
} else {
|
|
656
|
-
console.warn(`[EventApplicator] No engine attached to element for onScroll`);
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
element.__hypenScrollListener = listener;
|
|
660
|
-
element.addEventListener("scroll", listener, { passive: true });
|
|
661
|
-
console.log(`[EventApplicator] onScroll handler attached for action: ${actionName}`);
|
|
662
|
-
} else {
|
|
663
|
-
console.warn(`[EventApplicator] onScroll value must be an action reference starting with @, got: ${value}`);
|
|
664
|
-
}
|
|
665
|
-
},
|
|
666
|
-
onLongClick: (element, value) => {
|
|
667
|
-
console.log(`[EventApplicator] onLongClick called with value:`, value);
|
|
668
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
669
|
-
if (!actionName) {
|
|
670
|
-
console.warn(`[EventApplicator] onLongClick value must be an action reference, got:`, value);
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
const existingDownListener = element.__hypenLongClickDownListener;
|
|
674
|
-
const existingUpListener = element.__hypenLongClickUpListener;
|
|
675
|
-
if (existingDownListener) {
|
|
676
|
-
element.removeEventListener("pointerdown", existingDownListener);
|
|
677
|
-
}
|
|
678
|
-
if (existingUpListener) {
|
|
679
|
-
element.removeEventListener("pointerup", existingUpListener);
|
|
680
|
-
element.removeEventListener("pointerleave", existingUpListener);
|
|
681
|
-
}
|
|
682
|
-
let longClickTimer = null;
|
|
683
|
-
const LONG_CLICK_THRESHOLD = 500;
|
|
684
|
-
const downListener = (event) => {
|
|
685
|
-
longClickTimer = setTimeout(() => {
|
|
686
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onLongClick fired, dispatching action: ${actionName}`);
|
|
687
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
688
|
-
type: "longclick",
|
|
689
|
-
timestamp: Date.now(),
|
|
690
|
-
clientX: event.clientX,
|
|
691
|
-
clientY: event.clientY
|
|
692
|
-
};
|
|
693
|
-
const engine = element.__hypenEngine;
|
|
694
|
-
if (engine) {
|
|
695
|
-
engine.dispatchAction(actionName, payload);
|
|
696
|
-
} else {
|
|
697
|
-
console.warn(`[EventApplicator] No engine attached to element for onLongClick`);
|
|
698
|
-
}
|
|
699
|
-
longClickTimer = null;
|
|
700
|
-
}, LONG_CLICK_THRESHOLD);
|
|
701
|
-
};
|
|
702
|
-
const upListener = () => {
|
|
703
|
-
if (longClickTimer) {
|
|
704
|
-
clearTimeout(longClickTimer);
|
|
705
|
-
longClickTimer = null;
|
|
706
|
-
}
|
|
707
|
-
};
|
|
708
|
-
element.__hypenLongClickDownListener = downListener;
|
|
709
|
-
element.__hypenLongClickUpListener = upListener;
|
|
710
|
-
element.addEventListener("pointerdown", downListener);
|
|
711
|
-
element.addEventListener("pointerup", upListener);
|
|
712
|
-
element.addEventListener("pointerleave", upListener);
|
|
713
|
-
console.log(`[EventApplicator] onLongClick handler attached for action: ${actionName}`);
|
|
714
|
-
},
|
|
715
|
-
onFocus: (element, value) => {
|
|
716
|
-
console.log(`[EventApplicator] onFocus called with value:`, value);
|
|
717
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
718
|
-
if (!actionName) {
|
|
719
|
-
console.warn(`[EventApplicator] onFocus value must be an action reference, got:`, value);
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
const existingListener = element.__hypenFocusListener;
|
|
723
|
-
if (existingListener) {
|
|
724
|
-
element.removeEventListener("focus", existingListener);
|
|
733
|
+
};
|
|
734
|
+
disposables.add(disposableListener(element, eventType, listener, {
|
|
735
|
+
passive: options.passive
|
|
736
|
+
}));
|
|
737
|
+
disposables.addCallback(() => {
|
|
738
|
+
unregisterEvent(element, eventKey);
|
|
739
|
+
if (throttleTimer) {
|
|
740
|
+
throttleTimer.dispose();
|
|
725
741
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
748
|
-
if (!actionName) {
|
|
749
|
-
console.warn(`[EventApplicator] onBlur value must be an action reference, got:`, value);
|
|
742
|
+
});
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
function createKeyHandler(defaultKey = "Enter") {
|
|
746
|
+
return (element, value) => {
|
|
747
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
748
|
+
if (!actionName) {
|
|
749
|
+
console.warn(`[EventApplicator] onKey requires an action reference starting with @, got:`, value);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
const disposables = getElementDisposables2(element);
|
|
753
|
+
const eventKey = `keydown:${actionName}:${defaultKey}`;
|
|
754
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
registerEvent(element, eventKey);
|
|
758
|
+
const targetKey = getKeyTarget(element) || defaultKey;
|
|
759
|
+
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
760
|
+
const listener = (event) => {
|
|
761
|
+
const keyEvent = event;
|
|
762
|
+
if (keyEvent.key !== keyToMatch) {
|
|
750
763
|
return;
|
|
751
764
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
if (engine) {
|
|
766
|
-
engine.dispatchAction(actionName, payload);
|
|
767
|
-
} else {
|
|
768
|
-
console.warn(`[EventApplicator] No engine attached to element for onBlur`);
|
|
769
|
-
}
|
|
765
|
+
event.preventDefault();
|
|
766
|
+
const target = event.target;
|
|
767
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
768
|
+
type: event.type,
|
|
769
|
+
timestamp: Date.now(),
|
|
770
|
+
key: keyEvent.key,
|
|
771
|
+
code: keyEvent.code,
|
|
772
|
+
value: target.value,
|
|
773
|
+
input: target.value,
|
|
774
|
+
ctrlKey: keyEvent.ctrlKey,
|
|
775
|
+
shiftKey: keyEvent.shiftKey,
|
|
776
|
+
altKey: keyEvent.altKey,
|
|
777
|
+
metaKey: keyEvent.metaKey
|
|
770
778
|
};
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
},
|
|
775
|
-
onMouseEnter: (element, value) => {
|
|
776
|
-
console.log(`[EventApplicator] onMouseEnter called with value:`, value);
|
|
777
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
778
|
-
if (!actionName) {
|
|
779
|
-
console.warn(`[EventApplicator] onMouseEnter value must be an action reference, got:`, value);
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
const existingListener = element.__hypenMouseEnterListener;
|
|
783
|
-
if (existingListener) {
|
|
784
|
-
element.removeEventListener("mouseenter", existingListener);
|
|
779
|
+
const engine = getEngine(element);
|
|
780
|
+
if (engine) {
|
|
781
|
+
engine.dispatchAction(actionName, payload);
|
|
785
782
|
}
|
|
786
|
-
|
|
787
|
-
|
|
783
|
+
};
|
|
784
|
+
disposables.add(disposableListener(element, "keydown", listener));
|
|
785
|
+
disposables.addCallback(() => {
|
|
786
|
+
unregisterEvent(element, eventKey);
|
|
787
|
+
});
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
function createLongClickHandler(thresholdMs = 500) {
|
|
791
|
+
return (element, value) => {
|
|
792
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
793
|
+
if (!actionName) {
|
|
794
|
+
console.warn(`[EventApplicator] onLongClick requires an action reference starting with @, got:`, value);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
const disposables = getElementDisposables2(element);
|
|
798
|
+
const eventKey = `longclick:${actionName}`;
|
|
799
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
registerEvent(element, eventKey);
|
|
803
|
+
let longClickTimer = null;
|
|
804
|
+
const downListener = (event) => {
|
|
805
|
+
const pointerEvent = event;
|
|
806
|
+
longClickTimer = disposableTimeout(() => {
|
|
788
807
|
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
789
|
-
type: "
|
|
808
|
+
type: "longclick",
|
|
790
809
|
timestamp: Date.now(),
|
|
791
|
-
clientX:
|
|
792
|
-
clientY:
|
|
810
|
+
clientX: pointerEvent.clientX,
|
|
811
|
+
clientY: pointerEvent.clientY
|
|
793
812
|
};
|
|
794
|
-
const engine = element
|
|
813
|
+
const engine = getEngine(element);
|
|
795
814
|
if (engine) {
|
|
796
815
|
engine.dispatchAction(actionName, payload);
|
|
797
|
-
} else {
|
|
798
|
-
console.warn(`[EventApplicator] No engine attached to element for onMouseEnter`);
|
|
799
816
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
808
|
-
if (!actionName) {
|
|
809
|
-
console.warn(`[EventApplicator] onMouseLeave value must be an action reference, got:`, value);
|
|
810
|
-
return;
|
|
817
|
+
longClickTimer = null;
|
|
818
|
+
}, thresholdMs);
|
|
819
|
+
};
|
|
820
|
+
const cancelListener = () => {
|
|
821
|
+
if (longClickTimer) {
|
|
822
|
+
longClickTimer.dispose();
|
|
823
|
+
longClickTimer = null;
|
|
811
824
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
825
|
+
};
|
|
826
|
+
disposables.add(disposableListener(element, "pointerdown", downListener));
|
|
827
|
+
disposables.add(disposableListener(element, "pointerup", cancelListener));
|
|
828
|
+
disposables.add(disposableListener(element, "pointerleave", cancelListener));
|
|
829
|
+
disposables.addCallback(() => {
|
|
830
|
+
unregisterEvent(element, eventKey);
|
|
831
|
+
cancelListener();
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
var inputPayload = (event, element) => {
|
|
836
|
+
const target = element;
|
|
837
|
+
return {
|
|
838
|
+
type: event.type,
|
|
839
|
+
timestamp: Date.now(),
|
|
840
|
+
value: target.value,
|
|
841
|
+
input: target.value
|
|
842
|
+
};
|
|
843
|
+
}, scrollPayload = (_event, element) => {
|
|
844
|
+
const scrollTop = element.scrollTop;
|
|
845
|
+
const scrollHeight = element.scrollHeight;
|
|
846
|
+
const clientHeight = element.clientHeight;
|
|
847
|
+
const scrollPercentage = scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) * 100 : 0;
|
|
848
|
+
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
849
|
+
return {
|
|
850
|
+
type: "scroll",
|
|
851
|
+
timestamp: Date.now(),
|
|
852
|
+
scrollTop,
|
|
853
|
+
scrollLeft: element.scrollLeft,
|
|
854
|
+
scrollHeight,
|
|
855
|
+
scrollWidth: element.scrollWidth,
|
|
856
|
+
clientHeight,
|
|
857
|
+
clientWidth: element.clientWidth,
|
|
858
|
+
scrollPercentage: Math.round(scrollPercentage),
|
|
859
|
+
nearBottom,
|
|
860
|
+
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
861
|
+
atTop: scrollTop === 0
|
|
862
|
+
};
|
|
863
|
+
}, focusPayload = (event, element) => ({
|
|
864
|
+
type: event.type,
|
|
865
|
+
timestamp: Date.now(),
|
|
866
|
+
value: element.value ?? undefined
|
|
867
|
+
}), mousePayload = (event, _element) => {
|
|
868
|
+
const mouseEvent = event;
|
|
869
|
+
return {
|
|
870
|
+
type: event.type,
|
|
871
|
+
timestamp: Date.now(),
|
|
872
|
+
clientX: mouseEvent.clientX,
|
|
873
|
+
clientY: mouseEvent.clientY
|
|
874
|
+
};
|
|
875
|
+
}, eventHandlers;
|
|
876
|
+
var init_events = __esm(() => {
|
|
877
|
+
init_element_data();
|
|
878
|
+
eventHandlers = {
|
|
879
|
+
onClick: createEventHandler("click"),
|
|
880
|
+
onPress: createEventHandler("click"),
|
|
881
|
+
onChange: createEventHandler("change"),
|
|
882
|
+
onSubmit: createEventHandler("submit", { preventDefault: true }),
|
|
883
|
+
onInput: createEventHandler("input", { extractPayload: inputPayload }),
|
|
884
|
+
onKey: createKeyHandler("Enter"),
|
|
885
|
+
"onKey.key": (element, value) => {
|
|
886
|
+
setKeyTarget(element, String(value));
|
|
887
|
+
},
|
|
888
|
+
"onKey.action": createKeyHandler("Enter"),
|
|
889
|
+
onScroll: createEventHandler("scroll", {
|
|
890
|
+
throttleMs: 100,
|
|
891
|
+
passive: true,
|
|
892
|
+
extractPayload: scrollPayload
|
|
893
|
+
}),
|
|
894
|
+
onLongClick: createLongClickHandler(500),
|
|
895
|
+
onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
|
|
896
|
+
onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
|
|
897
|
+
onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
|
|
898
|
+
onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload })
|
|
835
899
|
};
|
|
836
900
|
});
|
|
837
901
|
|
|
@@ -997,7 +1061,43 @@ var effectsHandlers;
|
|
|
997
1061
|
var init_effects = __esm(() => {
|
|
998
1062
|
effectsHandlers = {
|
|
999
1063
|
boxShadow: (el, value) => {
|
|
1000
|
-
|
|
1064
|
+
if (typeof value === "string") {
|
|
1065
|
+
el.style.boxShadow = value;
|
|
1066
|
+
} else if (typeof value === "object" && value !== null) {
|
|
1067
|
+
const obj = value;
|
|
1068
|
+
const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
|
|
1069
|
+
const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
|
|
1070
|
+
const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "0px";
|
|
1071
|
+
const spread = typeof obj.spread === "number" ? `${obj.spread}px` : obj.spread ?? "0px";
|
|
1072
|
+
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
1073
|
+
const inset = obj.inset ? "inset " : "";
|
|
1074
|
+
el.style.boxShadow = `${inset}${x} ${y} ${blur} ${spread} ${color}`;
|
|
1075
|
+
} else if (typeof value === "number") {
|
|
1076
|
+
el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
shadow: (el, value) => {
|
|
1080
|
+
if (typeof value === "object" && value !== null) {
|
|
1081
|
+
const obj = value;
|
|
1082
|
+
const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
|
|
1083
|
+
const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
|
|
1084
|
+
const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "4px";
|
|
1085
|
+
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
1086
|
+
el.style.boxShadow = `${x} ${y} ${blur} ${color}`;
|
|
1087
|
+
} else if (typeof value === "number") {
|
|
1088
|
+
el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
|
|
1089
|
+
} else {
|
|
1090
|
+
el.style.boxShadow = String(value);
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
elevation: (el, value) => {
|
|
1094
|
+
const level = typeof value === "number" ? value : parseInt(String(value), 10);
|
|
1095
|
+
if (!isNaN(level) && level >= 0) {
|
|
1096
|
+
const y = level * 0.5;
|
|
1097
|
+
const blur = level * 1.5;
|
|
1098
|
+
const opacity = Math.min(0.1 + level * 0.02, 0.4);
|
|
1099
|
+
el.style.boxShadow = `0 ${y}px ${blur}px rgba(0,0,0,${opacity})`;
|
|
1100
|
+
}
|
|
1001
1101
|
},
|
|
1002
1102
|
textShadow: (el, value) => {
|
|
1003
1103
|
el.style.textShadow = String(value);
|
|
@@ -1315,6 +1415,28 @@ var init_transition = __esm(() => {
|
|
|
1315
1415
|
});
|
|
1316
1416
|
|
|
1317
1417
|
// src/dom/applicators/index.ts
|
|
1418
|
+
var BREAKPOINTS = {
|
|
1419
|
+
sm: "640px",
|
|
1420
|
+
md: "768px",
|
|
1421
|
+
lg: "1024px",
|
|
1422
|
+
xl: "1280px",
|
|
1423
|
+
"2xl": "1536px"
|
|
1424
|
+
};
|
|
1425
|
+
var variantStyleSheet = null;
|
|
1426
|
+
var insertedRules = new Set;
|
|
1427
|
+
function getVariantStyleSheet() {
|
|
1428
|
+
if (!variantStyleSheet) {
|
|
1429
|
+
const style = document.createElement("style");
|
|
1430
|
+
style.id = "hypen-variants";
|
|
1431
|
+
document.head.appendChild(style);
|
|
1432
|
+
variantStyleSheet = style.sheet;
|
|
1433
|
+
}
|
|
1434
|
+
return variantStyleSheet;
|
|
1435
|
+
}
|
|
1436
|
+
function hashValue(value) {
|
|
1437
|
+
return String(value).replace(/[^a-zA-Z0-9]/g, "").slice(0, 8);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1318
1440
|
class ApplicatorRegistry {
|
|
1319
1441
|
handlers = new Map;
|
|
1320
1442
|
elementState = new WeakMap;
|
|
@@ -1462,12 +1584,55 @@ class ApplicatorRegistry {
|
|
|
1462
1584
|
}
|
|
1463
1585
|
}
|
|
1464
1586
|
setStyleProperty(element, name, value) {
|
|
1465
|
-
const
|
|
1587
|
+
const atIndex = name.indexOf("@");
|
|
1588
|
+
const colonIndex = name.indexOf(":");
|
|
1589
|
+
if (atIndex !== -1) {
|
|
1590
|
+
const prop = name.slice(0, atIndex);
|
|
1591
|
+
const breakpoint = name.slice(atIndex + 1);
|
|
1592
|
+
const minWidth = BREAKPOINTS[breakpoint];
|
|
1593
|
+
if (minWidth) {
|
|
1594
|
+
const cssName2 = this.toKebabCase(prop);
|
|
1595
|
+
const cssValue = this.formatCssValue(cssName2, value);
|
|
1596
|
+
const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${breakpoint}-${hashValue(value)}`;
|
|
1597
|
+
const ruleKey = `${className}:${cssValue}`;
|
|
1598
|
+
if (!insertedRules.has(ruleKey)) {
|
|
1599
|
+
const sheet = getVariantStyleSheet();
|
|
1600
|
+
sheet.insertRule(`@media (min-width: ${minWidth}) { .${className} { ${cssName2}: ${cssValue}; } }`, sheet.cssRules.length);
|
|
1601
|
+
insertedRules.add(ruleKey);
|
|
1602
|
+
}
|
|
1603
|
+
element.classList.add(className);
|
|
1604
|
+
}
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
if (colonIndex !== -1) {
|
|
1608
|
+
const prop = name.slice(0, colonIndex);
|
|
1609
|
+
const state = name.slice(colonIndex + 1);
|
|
1610
|
+
const validStates = ["hover", "focus", "active", "disabled", "focus-visible", "focus-within"];
|
|
1611
|
+
if (validStates.includes(state)) {
|
|
1612
|
+
const cssName2 = this.toKebabCase(prop);
|
|
1613
|
+
const cssValue = this.formatCssValue(cssName2, value);
|
|
1614
|
+
const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${state}-${hashValue(value)}`;
|
|
1615
|
+
const ruleKey = `${className}:${cssValue}`;
|
|
1616
|
+
if (!insertedRules.has(ruleKey)) {
|
|
1617
|
+
const sheet = getVariantStyleSheet();
|
|
1618
|
+
sheet.insertRule(`.${className}:${state} { ${cssName2}: ${cssValue}; }`, sheet.cssRules.length);
|
|
1619
|
+
insertedRules.add(ruleKey);
|
|
1620
|
+
}
|
|
1621
|
+
element.classList.add(className);
|
|
1622
|
+
}
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
const cssName = this.toKebabCase(name);
|
|
1626
|
+
element.style.setProperty(cssName, this.formatCssValue(cssName, value));
|
|
1627
|
+
}
|
|
1628
|
+
toKebabCase(name) {
|
|
1629
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
1630
|
+
}
|
|
1631
|
+
formatCssValue(cssName, value) {
|
|
1466
1632
|
if (typeof value === "number" && this.needsUnit(cssName)) {
|
|
1467
|
-
|
|
1468
|
-
} else {
|
|
1469
|
-
element.style.setProperty(cssName, String(value));
|
|
1633
|
+
return `${value}px`;
|
|
1470
1634
|
}
|
|
1635
|
+
return String(value);
|
|
1471
1636
|
}
|
|
1472
1637
|
needsUnit(prop) {
|
|
1473
1638
|
const unitless = [
|
|
@@ -1545,4 +1710,4 @@ export {
|
|
|
1545
1710
|
ApplicatorRegistry
|
|
1546
1711
|
};
|
|
1547
1712
|
|
|
1548
|
-
//# debugId=
|
|
1713
|
+
//# debugId=FA4B7415966A312264756E2164756E21
|