@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.
Files changed (44) hide show
  1. package/dist/src/canvas/index.js.map +1 -1
  2. package/dist/src/canvas/renderer.js.map +1 -1
  3. package/dist/src/dom/applicators/effects.js +38 -2
  4. package/dist/src/dom/applicators/effects.js.map +3 -3
  5. package/dist/src/dom/applicators/events.js +280 -397
  6. package/dist/src/dom/applicators/events.js.map +5 -4
  7. package/dist/src/dom/applicators/font.js +94 -5
  8. package/dist/src/dom/applicators/font.js.map +3 -3
  9. package/dist/src/dom/applicators/index.js +590 -425
  10. package/dist/src/dom/applicators/index.js.map +10 -9
  11. package/dist/src/dom/applicators/layout.js +33 -5
  12. package/dist/src/dom/applicators/layout.js.map +3 -3
  13. package/dist/src/dom/applicators/size.js +81 -16
  14. package/dist/src/dom/applicators/size.js.map +3 -3
  15. package/dist/src/dom/components/hypenapp.js +296 -0
  16. package/dist/src/dom/components/hypenapp.js.map +10 -0
  17. package/dist/src/dom/components/index.js +263 -1
  18. package/dist/src/dom/components/index.js.map +5 -4
  19. package/dist/src/dom/element-data.js +140 -0
  20. package/dist/src/dom/element-data.js.map +10 -0
  21. package/dist/src/dom/index.js +857 -430
  22. package/dist/src/dom/index.js.map +13 -11
  23. package/dist/src/dom/renderer.js +857 -430
  24. package/dist/src/dom/renderer.js.map +13 -11
  25. package/dist/src/hypen.js +857 -430
  26. package/dist/src/hypen.js.map +13 -11
  27. package/dist/src/index.js +862 -430
  28. package/dist/src/index.js.map +15 -12
  29. package/package.json +3 -3
  30. package/src/canvas/QUICKSTART.md +5 -7
  31. package/src/canvas/README.md +2 -2
  32. package/src/canvas/renderer.ts +1 -1
  33. package/src/dom/README.md +4 -4
  34. package/src/dom/applicators/effects.ts +45 -1
  35. package/src/dom/applicators/events.ts +348 -537
  36. package/src/dom/applicators/font.ts +127 -2
  37. package/src/dom/applicators/index.ts +117 -7
  38. package/src/dom/applicators/layout.ts +40 -4
  39. package/src/dom/applicators/size.ts +101 -16
  40. package/src/dom/components/hypenapp.ts +348 -0
  41. package/src/dom/components/index.ts +2 -0
  42. package/src/dom/element-data.ts +234 -0
  43. package/src/dom/renderer.ts +12 -9
  44. 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
- el.style.width = typeof value === "number" ? `${value}px` : String(value);
227
+ const size = parseSizeValue(value);
228
+ if (size)
229
+ el.style.width = size;
178
230
  },
179
231
  height: (el, value) => {
180
- el.style.height = typeof value === "number" ? `${value}px` : String(value);
232
+ const size = parseSizeValue(value);
233
+ if (size)
234
+ el.style.height = size;
181
235
  },
182
236
  minWidth: (el, value) => {
183
- el.style.minWidth = typeof value === "number" ? `${value}px` : String(value);
237
+ const size = parseSizeValue(value);
238
+ if (size)
239
+ el.style.minWidth = size;
184
240
  },
185
241
  minHeight: (el, value) => {
186
- el.style.minHeight = typeof value === "number" ? `${value}px` : String(value);
242
+ const size = parseSizeValue(value);
243
+ if (size)
244
+ el.style.minHeight = size;
187
245
  },
188
246
  maxWidth: (el, value) => {
189
- el.style.maxWidth = typeof value === "number" ? `${value}px` : String(value);
247
+ const size = parseSizeValue(value);
248
+ if (size)
249
+ el.style.maxWidth = size;
190
250
  },
191
251
  maxHeight: (el, value) => {
192
- el.style.maxHeight = typeof value === "number" ? `${value}px` : String(value);
252
+ const size = parseSizeValue(value);
253
+ if (size)
254
+ el.style.maxHeight = size;
193
255
  },
194
256
  size: (el, value) => {
195
- if (typeof value === "number") {
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
- el.style.width = typeof obj.width === "number" ? `${obj.width}px` : String(obj.width);
260
+ const w = parseSizeValue(obj.width);
261
+ if (w)
262
+ el.style.width = w;
202
263
  }
203
264
  if (obj.height !== undefined) {
204
- el.style.height = typeof obj.height === "number" ? `${obj.height}px` : String(obj.height);
265
+ const h = parseSizeValue(obj.height);
266
+ if (h)
267
+ el.style.height = h;
205
268
  }
206
269
  } else {
207
- const size = String(value);
208
- el.style.width = size;
209
- el.style.height = size;
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
- var fontHandlers;
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
- el.style.fontFamily = String(value);
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
- payload[key] = val;
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
- var eventHandlers;
422
- var init_events = __esm(() => {
423
- eventHandlers = {
424
- onClick: (element, value) => {
425
- console.log(`[EventApplicator] onClick called with value:`, value);
426
- const { actionName, payload: customPayload } = extractActionDetails(value);
427
- if (!actionName) {
428
- console.warn(`[EventApplicator] onClick value must be an action reference, got:`, value);
429
- return;
430
- }
431
- const existingListener = element.__hypenClickListener;
432
- if (existingListener) {
433
- element.removeEventListener("click", existingListener);
434
- }
435
- const listener = (event) => {
436
- console.log(`\uD83D\uDD25 [EventApplicator] onClick fired, dispatching action: ${actionName}`);
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
- const existingListener = element.__hypenSubmitListener;
484
- if (existingListener) {
485
- element.removeEventListener("submit", existingListener);
720
+ if (options.throttleMs) {
721
+ throttleTimer = disposableTimeout(() => {
722
+ throttleTimer = null;
723
+ }, options.throttleMs);
486
724
  }
487
- const listener = (event) => {
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 listener = (event) => {
514
- console.log(`\uD83D\uDD25 [EventApplicator] onInput fired, dispatching action: ${actionName}`);
515
- const target = event.target;
516
- const payload = {
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
- "onKey.key": (element, keyValue) => {
575
- console.log(`[EventApplicator] onKey.key called with value:`, keyValue);
576
- element.__hypenKeyTarget = keyValue;
577
- },
578
- "onKey.action": (element, value) => {
579
- console.log(`[EventApplicator] onKey.action called with value:`, value);
580
- const { actionName } = extractActionDetails(value);
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
- const listener = (event) => {
727
- console.log(`\uD83D\uDD25 [EventApplicator] onFocus fired, dispatching action: ${actionName}`);
728
- const target = event.target;
729
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
730
- type: "focus",
731
- timestamp: Date.now(),
732
- value: target.value ?? undefined
733
- };
734
- const engine = element.__hypenEngine;
735
- if (engine) {
736
- engine.dispatchAction(actionName, payload);
737
- } else {
738
- console.warn(`[EventApplicator] No engine attached to element for onFocus`);
739
- }
740
- };
741
- element.__hypenFocusListener = listener;
742
- element.addEventListener("focus", listener);
743
- console.log(`[EventApplicator] onFocus handler attached for action: ${actionName}`);
744
- },
745
- onBlur: (element, value) => {
746
- console.log(`[EventApplicator] onBlur called with value:`, value);
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
- const existingListener = element.__hypenBlurListener;
753
- if (existingListener) {
754
- element.removeEventListener("blur", existingListener);
755
- }
756
- const listener = (event) => {
757
- console.log(`\uD83D\uDD25 [EventApplicator] onBlur fired, dispatching action: ${actionName}`);
758
- const target = event.target;
759
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
760
- type: "blur",
761
- timestamp: Date.now(),
762
- value: target.value ?? undefined
763
- };
764
- const engine = element.__hypenEngine;
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
- element.__hypenBlurListener = listener;
772
- element.addEventListener("blur", listener);
773
- console.log(`[EventApplicator] onBlur handler attached for action: ${actionName}`);
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
- const listener = (event) => {
787
- console.log(`\uD83D\uDD25 [EventApplicator] onMouseEnter fired, dispatching action: ${actionName}`);
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: "mouseenter",
808
+ type: "longclick",
790
809
  timestamp: Date.now(),
791
- clientX: event.clientX,
792
- clientY: event.clientY
810
+ clientX: pointerEvent.clientX,
811
+ clientY: pointerEvent.clientY
793
812
  };
794
- const engine = element.__hypenEngine;
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
- element.__hypenMouseEnterListener = listener;
802
- element.addEventListener("mouseenter", listener);
803
- console.log(`[EventApplicator] onMouseEnter handler attached for action: ${actionName}`);
804
- },
805
- onMouseLeave: (element, value) => {
806
- console.log(`[EventApplicator] onMouseLeave called with value:`, value);
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
- const existingListener = element.__hypenMouseLeaveListener;
813
- if (existingListener) {
814
- element.removeEventListener("mouseleave", existingListener);
815
- }
816
- const listener = (event) => {
817
- console.log(`\uD83D\uDD25 [EventApplicator] onMouseLeave fired, dispatching action: ${actionName}`);
818
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
819
- type: "mouseleave",
820
- timestamp: Date.now(),
821
- clientX: event.clientX,
822
- clientY: event.clientY
823
- };
824
- const engine = element.__hypenEngine;
825
- if (engine) {
826
- engine.dispatchAction(actionName, payload);
827
- } else {
828
- console.warn(`[EventApplicator] No engine attached to element for onMouseLeave`);
829
- }
830
- };
831
- element.__hypenMouseLeaveListener = listener;
832
- element.addEventListener("mouseleave", listener);
833
- console.log(`[EventApplicator] onMouseLeave handler attached for action: ${actionName}`);
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
- el.style.boxShadow = String(value);
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 cssName = name.replace(/([A-Z])/g, "-$1").toLowerCase();
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
- element.style.setProperty(cssName, `${value}px`);
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=4E66FE319E3D673364756E2164756E21
1713
+ //# debugId=FA4B7415966A312264756E2164756E21