@hypen-space/web 0.4.36 → 0.4.38

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 (149) hide show
  1. package/README.md +7 -6
  2. package/dist/canvas/accessibility.js +174 -174
  3. package/dist/canvas/accessibility.js.map +1 -10
  4. package/dist/canvas/events.js +264 -360
  5. package/dist/canvas/events.js.map +1 -11
  6. package/dist/canvas/index.js +11 -47
  7. package/dist/canvas/index.js.map +1 -9
  8. package/dist/canvas/input.js +178 -289
  9. package/dist/canvas/input.js.map +1 -11
  10. package/dist/canvas/layout.js +349 -547
  11. package/dist/canvas/layout.js.map +1 -12
  12. package/dist/canvas/paint.js +1122 -1146
  13. package/dist/canvas/paint.js.map +1 -12
  14. package/dist/canvas/renderer.js +352 -2259
  15. package/dist/canvas/renderer.js.map +1 -17
  16. package/dist/canvas/text.js +129 -264
  17. package/dist/canvas/text.js.map +1 -11
  18. package/dist/canvas/types.js +7 -2
  19. package/dist/canvas/types.js.map +1 -9
  20. package/dist/canvas/utils.js +158 -161
  21. package/dist/canvas/utils.js.map +1 -10
  22. package/dist/dom/applicators/advanced-layout.js +105 -138
  23. package/dist/dom/applicators/advanced-layout.js.map +1 -10
  24. package/dist/dom/applicators/background.js +36 -76
  25. package/dist/dom/applicators/background.js.map +1 -10
  26. package/dist/dom/applicators/border.js +82 -106
  27. package/dist/dom/applicators/border.js.map +1 -10
  28. package/dist/dom/applicators/color.js +17 -58
  29. package/dist/dom/applicators/color.js.map +1 -10
  30. package/dist/dom/applicators/display.js +39 -79
  31. package/dist/dom/applicators/display.js.map +1 -10
  32. package/dist/dom/applicators/effects.js +121 -147
  33. package/dist/dom/applicators/effects.js.map +1 -10
  34. package/dist/dom/applicators/events.js +413 -450
  35. package/dist/dom/applicators/events.js.map +1 -11
  36. package/dist/dom/applicators/font.js +119 -140
  37. package/dist/dom/applicators/font.js.map +1 -10
  38. package/dist/dom/applicators/index.js +386 -1770
  39. package/dist/dom/applicators/index.js.map +1 -26
  40. package/dist/dom/applicators/layout.js +143 -149
  41. package/dist/dom/applicators/layout.js.map +1 -10
  42. package/dist/dom/applicators/margin.js +64 -105
  43. package/dist/dom/applicators/margin.js.map +1 -10
  44. package/dist/dom/applicators/padding.js +64 -105
  45. package/dist/dom/applicators/padding.js.map +1 -10
  46. package/dist/dom/applicators/size.js +169 -172
  47. package/dist/dom/applicators/size.js.map +1 -10
  48. package/dist/dom/applicators/transform.js +73 -114
  49. package/dist/dom/applicators/transform.js.map +1 -10
  50. package/dist/dom/applicators/transition.js +47 -88
  51. package/dist/dom/applicators/transition.js.map +1 -10
  52. package/dist/dom/applicators/types.js +7 -2
  53. package/dist/dom/applicators/types.js.map +1 -9
  54. package/dist/dom/applicators/typography.js +68 -109
  55. package/dist/dom/applicators/typography.js.map +1 -10
  56. package/dist/dom/canvas/index.js +49 -83
  57. package/dist/dom/canvas/index.js.map +1 -10
  58. package/dist/dom/components/app.js +16 -63
  59. package/dist/dom/components/app.js.map +1 -10
  60. package/dist/dom/components/audio.js +31 -76
  61. package/dist/dom/components/audio.js.map +1 -10
  62. package/dist/dom/components/avatar.js +41 -87
  63. package/dist/dom/components/avatar.js.map +1 -10
  64. package/dist/dom/components/badge.js +35 -83
  65. package/dist/dom/components/badge.js.map +1 -10
  66. package/dist/dom/components/button.js +26 -69
  67. package/dist/dom/components/button.js.map +1 -10
  68. package/dist/dom/components/card.js +13 -63
  69. package/dist/dom/components/card.js.map +1 -10
  70. package/dist/dom/components/center.js +21 -65
  71. package/dist/dom/components/center.js.map +1 -10
  72. package/dist/dom/components/checkbox.js +37 -82
  73. package/dist/dom/components/checkbox.js.map +1 -10
  74. package/dist/dom/components/column.js +16 -62
  75. package/dist/dom/components/column.js.map +1 -10
  76. package/dist/dom/components/container.js +11 -59
  77. package/dist/dom/components/container.js.map +1 -10
  78. package/dist/dom/components/divider.js +27 -73
  79. package/dist/dom/components/divider.js.map +1 -10
  80. package/dist/dom/components/grid.js +41 -80
  81. package/dist/dom/components/grid.js.map +1 -10
  82. package/dist/dom/components/heading.js +28 -74
  83. package/dist/dom/components/heading.js.map +1 -10
  84. package/dist/dom/components/hypenapp.js +291 -288
  85. package/dist/dom/components/hypenapp.js.map +1 -10
  86. package/dist/dom/components/image.js +18 -67
  87. package/dist/dom/components/image.js.map +1 -10
  88. package/dist/dom/components/index.js +109 -1427
  89. package/dist/dom/components/index.js.map +1 -42
  90. package/dist/dom/components/input.js +19 -69
  91. package/dist/dom/components/input.js.map +1 -10
  92. package/dist/dom/components/link.js +23 -70
  93. package/dist/dom/components/link.js.map +1 -10
  94. package/dist/dom/components/list.js +26 -72
  95. package/dist/dom/components/list.js.map +1 -10
  96. package/dist/dom/components/paragraph.js +14 -63
  97. package/dist/dom/components/paragraph.js.map +1 -10
  98. package/dist/dom/components/progressbar.js +38 -85
  99. package/dist/dom/components/progressbar.js.map +1 -10
  100. package/dist/dom/components/route.js +27 -73
  101. package/dist/dom/components/route.js.map +1 -10
  102. package/dist/dom/components/router.js +15 -62
  103. package/dist/dom/components/router.js.map +1 -10
  104. package/dist/dom/components/row.js +25 -70
  105. package/dist/dom/components/row.js.map +1 -10
  106. package/dist/dom/components/select.js +42 -85
  107. package/dist/dom/components/select.js.map +1 -10
  108. package/dist/dom/components/slider.js +31 -76
  109. package/dist/dom/components/slider.js.map +1 -10
  110. package/dist/dom/components/spacer.js +10 -60
  111. package/dist/dom/components/spacer.js.map +1 -10
  112. package/dist/dom/components/spinner.js +41 -88
  113. package/dist/dom/components/spinner.js.map +1 -10
  114. package/dist/dom/components/stack.js +19 -67
  115. package/dist/dom/components/stack.js.map +1 -10
  116. package/dist/dom/components/switch.js +50 -93
  117. package/dist/dom/components/switch.js.map +1 -10
  118. package/dist/dom/components/text.js +24 -69
  119. package/dist/dom/components/text.js.map +1 -10
  120. package/dist/dom/components/textarea.js +35 -79
  121. package/dist/dom/components/textarea.js.map +1 -10
  122. package/dist/dom/components/video.js +35 -79
  123. package/dist/dom/components/video.js.map +1 -10
  124. package/dist/dom/debug.js +159 -160
  125. package/dist/dom/debug.js.map +1 -10
  126. package/dist/dom/element-data.js +181 -143
  127. package/dist/dom/element-data.js.map +1 -10
  128. package/dist/dom/events.js +133 -142
  129. package/dist/dom/events.js.map +1 -10
  130. package/dist/dom/index.js +11 -48
  131. package/dist/dom/index.js.map +1 -9
  132. package/dist/dom/renderer.js +311 -3596
  133. package/dist/dom/renderer.js.map +1 -62
  134. package/dist/index.d.ts +2 -2
  135. package/dist/index.js +36 -53
  136. package/dist/index.js.map +1 -9
  137. package/package.json +2 -16
  138. package/src/canvas/QUICKSTART.md +4 -3
  139. package/src/canvas/README.md +3 -2
  140. package/src/dom/README.md +4 -3
  141. package/src/index.ts +2 -2
  142. package/dist/client.d.ts +0 -19
  143. package/dist/client.js +0 -45
  144. package/dist/client.js.map +0 -9
  145. package/dist/hypen.d.ts +0 -140
  146. package/dist/hypen.js +0 -3909
  147. package/dist/hypen.js.map +0 -63
  148. package/src/client.ts +0 -20
  149. package/src/hypen.ts +0 -556
@@ -1,1787 +1,403 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- function __accessProp(key) {
6
- return this[key];
7
- }
8
- var __toCommonJS = (from) => {
9
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
- if (entry)
11
- return entry;
12
- entry = __defProp({}, "__esModule", { value: true });
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (var key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(entry, key))
16
- __defProp(entry, key, {
17
- get: __accessProp.bind(from, key),
18
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
- });
20
- }
21
- __moduleCache.set(from, entry);
22
- return entry;
23
- };
24
- var __moduleCache;
25
- var __returnValue = (v) => v;
26
- function __exportSetter(name, newValue) {
27
- this[name] = __returnValue.bind(null, newValue);
28
- }
29
- var __export = (target, all) => {
30
- for (var name in all)
31
- __defProp(target, name, {
32
- get: all[name],
33
- enumerable: true,
34
- configurable: true,
35
- set: __exportSetter.bind(all, name)
36
- });
37
- };
38
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
39
-
40
- // src/dom/applicators/padding.ts
41
- var getNumericValue = (value) => {
42
- if (typeof value === "number")
43
- return value;
44
- if (typeof value === "object" && value["0"] !== undefined)
45
- return Number(value["0"]);
46
- if (typeof value === "string")
47
- return parseFloat(value);
48
- return null;
49
- };
50
- var paddingHandler = (el, value) => {
51
- if (typeof value === "number") {
52
- el.style.padding = `${value}px`;
53
- } else if (typeof value === "object") {
54
- if (value["0"] !== undefined && Object.keys(value).length === 1) {
55
- el.style.padding = `${value["0"]}px`;
56
- } else {
57
- if (value.left !== undefined)
58
- el.style.paddingLeft = `${value.left}px`;
59
- if (value.right !== undefined)
60
- el.style.paddingRight = `${value.right}px`;
61
- if (value.top !== undefined)
62
- el.style.paddingTop = `${value.top}px`;
63
- if (value.bottom !== undefined)
64
- el.style.paddingBottom = `${value.bottom}px`;
65
- }
66
- } else {
67
- el.style.padding = String(value);
68
- }
69
- };
70
- var paddingTopHandler = (el, value) => {
71
- const v = getNumericValue(value);
72
- if (v !== null)
73
- el.style.paddingTop = `${v}px`;
74
- };
75
- var paddingBottomHandler = (el, value) => {
76
- const v = getNumericValue(value);
77
- if (v !== null)
78
- el.style.paddingBottom = `${v}px`;
79
- };
80
- var paddingLeftHandler = (el, value) => {
81
- const v = getNumericValue(value);
82
- if (v !== null)
83
- el.style.paddingLeft = `${v}px`;
84
- };
85
- var paddingRightHandler = (el, value) => {
86
- const v = getNumericValue(value);
87
- if (v !== null)
88
- el.style.paddingRight = `${v}px`;
89
- };
90
- var paddingHorizontalHandler = (el, value) => {
91
- const v = getNumericValue(value);
92
- if (v !== null) {
93
- el.style.paddingLeft = `${v}px`;
94
- el.style.paddingRight = `${v}px`;
95
- }
96
- };
97
- var paddingVerticalHandler = (el, value) => {
98
- const v = getNumericValue(value);
99
- if (v !== null) {
100
- el.style.paddingTop = `${v}px`;
101
- el.style.paddingBottom = `${v}px`;
102
- }
103
- };
104
-
105
- // src/dom/applicators/margin.ts
106
- var getNumericValue2 = (value) => {
107
- if (typeof value === "number")
108
- return value;
109
- if (typeof value === "object" && value["0"] !== undefined)
110
- return Number(value["0"]);
111
- if (typeof value === "string")
112
- return parseFloat(value);
113
- return null;
114
- };
115
- var marginHandler = (el, value) => {
116
- if (typeof value === "number") {
117
- el.style.margin = `${value}px`;
118
- } else if (typeof value === "object") {
119
- if (value["0"] !== undefined && Object.keys(value).length === 1) {
120
- el.style.margin = `${value["0"]}px`;
121
- } else {
122
- if (value.left !== undefined)
123
- el.style.marginLeft = `${value.left}px`;
124
- if (value.right !== undefined)
125
- el.style.marginRight = `${value.right}px`;
126
- if (value.top !== undefined)
127
- el.style.marginTop = `${value.top}px`;
128
- if (value.bottom !== undefined)
129
- el.style.marginBottom = `${value.bottom}px`;
130
- }
131
- } else {
132
- el.style.margin = String(value);
133
- }
134
- };
135
- var marginTopHandler = (el, value) => {
136
- const v = getNumericValue2(value);
137
- if (v !== null)
138
- el.style.marginTop = `${v}px`;
139
- };
140
- var marginBottomHandler = (el, value) => {
141
- const v = getNumericValue2(value);
142
- if (v !== null)
143
- el.style.marginBottom = `${v}px`;
144
- };
145
- var marginLeftHandler = (el, value) => {
146
- const v = getNumericValue2(value);
147
- if (v !== null)
148
- el.style.marginLeft = `${v}px`;
149
- };
150
- var marginRightHandler = (el, value) => {
151
- const v = getNumericValue2(value);
152
- if (v !== null)
153
- el.style.marginRight = `${v}px`;
154
- };
155
- var marginHorizontalHandler = (el, value) => {
156
- const v = getNumericValue2(value);
157
- if (v !== null) {
158
- el.style.marginLeft = `${v}px`;
159
- el.style.marginRight = `${v}px`;
160
- }
161
- };
162
- var marginVerticalHandler = (el, value) => {
163
- const v = getNumericValue2(value);
164
- if (v !== null) {
165
- el.style.marginTop = `${v}px`;
166
- el.style.marginBottom = `${v}px`;
167
- }
168
- };
169
-
170
- // src/dom/applicators/color.ts
171
- var colorHandlers = {
172
- color: (el, value) => {
173
- el.style.color = String(value);
174
- },
175
- backgroundColor: (el, value) => {
176
- el.style.backgroundColor = String(value);
177
- },
178
- borderColor: (el, value) => {
179
- el.style.borderColor = String(value);
180
- },
181
- opacity: (el, value) => {
182
- el.style.opacity = String(value);
183
- }
184
- };
185
-
186
- // src/dom/applicators/border.ts
187
- var borderHandlers = {
188
- border: (el, value) => {
189
- if (typeof value === "number") {
190
- el.style.borderWidth = `${value}px`;
191
- el.style.borderStyle = "solid";
192
- } else if (typeof value === "object" && value !== null) {
193
- const obj = value;
194
- if (obj.width !== undefined) {
195
- el.style.borderWidth = typeof obj.width === "number" ? `${obj.width}px` : String(obj.width);
196
- }
197
- if (obj.color !== undefined) {
198
- el.style.borderColor = String(obj.color);
199
- }
200
- if (obj.style !== undefined) {
201
- el.style.borderStyle = String(obj.style);
202
- } else {
203
- el.style.borderStyle = "solid";
204
- }
205
- if (obj.radius !== undefined) {
206
- el.style.borderRadius = typeof obj.radius === "number" ? `${obj.radius}px` : String(obj.radius);
207
- }
208
- } else if (typeof value === "string") {
209
- el.style.border = value;
210
- }
211
- },
212
- borderWidth: (el, value) => {
213
- el.style.borderWidth = typeof value === "number" ? `${value}px` : String(value);
214
- },
215
- borderStyle: (el, value) => {
216
- el.style.borderStyle = String(value);
217
- },
218
- borderRadius: (el, value) => {
219
- if (typeof value === "number") {
220
- el.style.borderRadius = `${value}px`;
221
- } else if (typeof value === "object" && value !== null) {
222
- const obj = value;
223
- const topLeft = obj.topLeft ?? obj.topStart ?? 0;
224
- const topRight = obj.topRight ?? obj.topEnd ?? 0;
225
- const bottomRight = obj.bottomRight ?? obj.bottomEnd ?? 0;
226
- const bottomLeft = obj.bottomLeft ?? obj.bottomStart ?? 0;
227
- const formatValue = (v) => typeof v === "number" ? `${v}px` : String(v);
228
- el.style.borderRadius = `${formatValue(topLeft)} ${formatValue(topRight)} ${formatValue(bottomRight)} ${formatValue(bottomLeft)}`;
229
- } else {
230
- el.style.borderRadius = String(value);
231
- }
232
- },
233
- cornerRadius: (el, value) => {
234
- if (typeof value === "number") {
235
- el.style.borderRadius = `${value}px`;
236
- } else if (typeof value === "object" && value !== null) {
237
- const obj = value;
238
- const topLeft = obj.topLeft ?? obj.topStart ?? 0;
239
- const topRight = obj.topRight ?? obj.topEnd ?? 0;
240
- const bottomRight = obj.bottomRight ?? obj.bottomEnd ?? 0;
241
- const bottomLeft = obj.bottomLeft ?? obj.bottomStart ?? 0;
242
- const formatValue = (v) => typeof v === "number" ? `${v}px` : String(v);
243
- el.style.borderRadius = `${formatValue(topLeft)} ${formatValue(topRight)} ${formatValue(bottomRight)} ${formatValue(bottomLeft)}`;
244
- } else {
245
- el.style.borderRadius = String(value);
246
- }
247
- }
248
- };
249
-
250
- // src/dom/applicators/size.ts
251
- function parseSizeValue(value) {
252
- if (value === null || value === undefined)
253
- return null;
254
- if (typeof value === "number") {
255
- return `${value}px`;
256
- }
257
- const str = String(value).trim().toLowerCase();
258
- switch (str) {
259
- case "fill":
260
- case "match_parent":
261
- return "100%";
262
- case "wrap":
263
- case "wrap_content":
264
- case "auto":
265
- return "auto";
266
- case "infinity":
267
- case "inf":
268
- case "max":
269
- return "100%";
270
- }
271
- const match = str.match(/^(-?[\d.]+)\s*(px|dp|pt|%|vw|vh|vmin|vmax|em|rem)?$/);
272
- if (!match) {
273
- return str;
274
- }
275
- const num = parseFloat(match[1]);
276
- const unit = match[2] || "px";
277
- switch (unit) {
278
- case "px":
279
- return `${num}px`;
280
- case "dp":
281
- case "pt":
282
- return `${num}px`;
283
- case "%":
284
- return `${num}%`;
285
- case "vw":
286
- return `${num}vw`;
287
- case "vh":
288
- return `${num}vh`;
289
- case "vmin":
290
- return `${num}vmin`;
291
- case "vmax":
292
- return `${num}vmax`;
293
- case "em":
294
- return `${num}em`;
295
- case "rem":
296
- return `${num}rem`;
297
- default:
298
- return `${num}px`;
299
- }
300
- }
301
- var sizeHandlers = {
302
- width: (el, value) => {
303
- const size = parseSizeValue(value);
304
- if (size)
305
- el.style.width = size;
306
- },
307
- height: (el, value) => {
308
- const size = parseSizeValue(value);
309
- if (size)
310
- el.style.height = size;
311
- },
312
- minWidth: (el, value) => {
313
- const size = parseSizeValue(value);
314
- if (size)
315
- el.style.minWidth = size;
316
- },
317
- minHeight: (el, value) => {
318
- const size = parseSizeValue(value);
319
- if (size)
320
- el.style.minHeight = size;
321
- },
322
- maxWidth: (el, value) => {
323
- const size = parseSizeValue(value);
324
- if (size)
325
- el.style.maxWidth = size;
326
- },
327
- maxHeight: (el, value) => {
328
- const size = parseSizeValue(value);
329
- if (size)
330
- el.style.maxHeight = size;
331
- },
332
- size: (el, value) => {
333
- if (typeof value === "object" && value !== null) {
334
- const obj = value;
335
- if (obj.width !== undefined) {
336
- const w = parseSizeValue(obj.width);
337
- if (w)
338
- el.style.width = w;
339
- }
340
- if (obj.height !== undefined) {
341
- const h = parseSizeValue(obj.height);
342
- if (h)
343
- el.style.height = h;
344
- }
345
- } else {
346
- const size = parseSizeValue(value);
347
- if (size) {
348
- el.style.width = size;
349
- el.style.height = size;
350
- }
351
- }
352
- },
353
- fillMaxWidth: (el, value) => {
354
- if (value === false)
355
- return;
356
- const fraction = typeof value === "number" ? value : 1;
357
- if (fraction === 1) {
358
- el.style.alignSelf = "stretch";
359
- el.style.width = "100%";
360
- el.style.minWidth = "0";
361
- } else {
362
- el.style.width = `${fraction * 100}%`;
363
- }
364
- el.style.justifySelf = "stretch";
365
- },
366
- fillMaxHeight: (el, value) => {
367
- if (value === false)
368
- return;
369
- const fraction = typeof value === "number" ? value : 1;
370
- el.style.height = `${fraction * 100}%`;
371
- },
372
- fillMaxSize: (el, value) => {
373
- if (value === false)
374
- return;
375
- const fraction = typeof value === "number" ? value : 1;
376
- el.style.width = `${fraction * 100}%`;
377
- el.style.height = `${fraction * 100}%`;
378
- el.style.alignSelf = "stretch";
379
- el.style.minWidth = "0";
380
- }
381
- };
382
-
383
- // src/dom/applicators/font.ts
384
- var loadedGoogleFonts = new Set;
385
- var systemFontKeywords = new Set([
386
- "default",
387
- "system",
388
- "system-ui",
389
- "inherit",
390
- "initial",
391
- "unset",
392
- "serif",
393
- "sans-serif",
394
- "monospace",
395
- "cursive",
396
- "fantasy",
397
- "-apple-system",
398
- "BlinkMacSystemFont",
399
- "Segoe UI",
400
- "Arial",
401
- "Helvetica",
402
- "Times New Roman",
403
- "Georgia",
404
- "Courier New",
405
- "Verdana",
406
- "Tahoma"
407
- ]);
408
- function isSystemFont(fontName) {
409
- const normalized = fontName.toLowerCase().trim();
410
- return systemFontKeywords.has(normalized) || normalized.startsWith("-") || normalized.startsWith("ui-");
411
- }
412
- function loadGoogleFont(fontName) {
413
- const normalized = fontName.trim();
414
- if (loadedGoogleFonts.has(normalized) || isSystemFont(normalized)) {
415
- return;
416
- }
417
- loadedGoogleFonts.add(normalized);
418
- const link = document.createElement("link");
419
- link.rel = "stylesheet";
420
- link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(normalized)}:wght@100;200;300;400;500;600;700;800;900&display=swap`;
421
- document.head.appendChild(link);
422
- }
423
- function processFontFamily(value) {
424
- const fonts = value.split(",").map((f) => f.trim().replace(/["']/g, ""));
425
- for (const font of fonts) {
426
- if (!isSystemFont(font)) {
427
- loadGoogleFont(font);
428
- }
429
- }
430
- return fonts.map((f) => {
431
- if (f.includes(" ") && !f.startsWith('"') && !f.startsWith("'")) {
432
- return `"${f}"`;
433
- }
434
- return f;
435
- }).join(", ");
436
- }
437
- var fontHandlers = {
438
- fontSize: (el, value) => {
439
- el.style.fontSize = typeof value === "number" ? `${value}px` : String(value);
440
- },
441
- fontWeight: (el, value) => {
442
- el.style.fontWeight = String(value);
443
- },
444
- fontFamily: (el, value) => {
445
- const fontValue = String(value);
446
- el.style.fontFamily = processFontFamily(fontValue);
447
- },
448
- textAlign: (el, value) => {
449
- el.style.textAlign = String(value);
450
- },
451
- lineHeight: (el, value) => {
452
- el.style.lineHeight = String(value);
453
- },
454
- fontStyle: (el, value) => {
455
- el.style.fontStyle = String(value);
456
- },
457
- textTransform: (el, value) => {
458
- el.style.textTransform = String(value);
459
- }
460
- };
461
- var GoogleFonts = {
462
- preload: loadGoogleFont,
463
- isLoaded: (fontName) => loadedGoogleFonts.has(fontName.trim()),
464
- getLoadedFonts: () => Array.from(loadedGoogleFonts),
465
- popular: [
466
- "Roboto",
467
- "Open Sans",
468
- "Lato",
469
- "Montserrat",
470
- "Poppins",
471
- "Inter",
472
- "Nunito",
473
- "Playfair Display",
474
- "Merriweather",
475
- "Source Code Pro",
476
- "Fira Code",
477
- "JetBrains Mono",
478
- "Raleway",
479
- "Ubuntu",
480
- "Oswald",
481
- "Quicksand",
482
- "Work Sans",
483
- "Rubik",
484
- "Karla",
485
- "DM Sans"
486
- ]
487
- };
488
-
489
- // src/dom/applicators/layout.ts
490
- function mapAlignmentValue(value) {
491
- const v = String(value).toLowerCase();
492
- switch (v) {
493
- case "top":
494
- case "start":
495
- case "leading":
496
- case "left":
497
- return "flex-start";
498
- case "bottom":
499
- case "end":
500
- case "trailing":
501
- case "right":
502
- return "flex-end";
503
- case "center":
504
- return "center";
505
- case "spacebetween":
506
- case "space-between":
507
- return "space-between";
508
- case "spacearound":
509
- case "space-around":
510
- return "space-around";
511
- case "spaceevenly":
512
- case "space-evenly":
513
- return "space-evenly";
514
- default:
515
- return v;
516
- }
517
- }
518
- var layoutHandlers = {
519
- verticalAlignment: (el, value) => {
520
- const val = mapAlignmentValue(String(value));
521
- const display = el.style.display || getComputedStyle(el).display;
522
- const flexDirection = el.style.flexDirection || getComputedStyle(el).flexDirection;
523
- if (display === "grid") {
524
- el.style.alignItems = val;
525
- } else if (flexDirection === "column" || flexDirection === "column-reverse") {
526
- el.style.justifyContent = val;
527
- } else {
528
- el.style.alignItems = val;
529
- }
530
- },
531
- horizontalAlignment: (el, value) => {
532
- const val = mapAlignmentValue(String(value));
533
- const display = el.style.display || getComputedStyle(el).display;
534
- const flexDirection = el.style.flexDirection || getComputedStyle(el).flexDirection;
535
- if (display === "grid") {
536
- el.style.justifyItems = val;
537
- } else if (flexDirection === "column" || flexDirection === "column-reverse") {
538
- el.style.alignItems = val;
539
- } else if (flexDirection === "row" || flexDirection === "row-reverse") {
540
- el.style.justifyContent = val;
541
- if (val !== "flex-start" && el.style.overflow !== "auto" && el.style.overflowX !== "auto") {
542
- el.style.width = "100%";
543
- }
544
- } else {
545
- el.style.justifyContent = val;
546
- }
547
- },
548
- horizontalAlign: (el, value) => {
549
- el.style.justifyContent = mapAlignmentValue(String(value));
550
- },
551
- verticalAlign: (el, value) => {
552
- el.style.alignItems = mapAlignmentValue(String(value));
553
- },
554
- gap: (el, value) => {
555
- el.style.gap = typeof value === "number" ? `${value}px` : String(value);
556
- },
557
- weight: (el, value) => {
558
- el.style.flex = String(value);
559
- el.dataset.hypenFlex = "true";
560
- },
561
- flex: (el, value) => {
562
- el.style.flex = String(value);
563
- el.dataset.hypenFlex = "true";
564
- },
565
- flexGrow: (el, value) => {
566
- el.style.flexGrow = String(value);
567
- },
568
- flexShrink: (el, value) => {
569
- el.style.flexShrink = String(value);
570
- },
571
- cursor: (el, value) => {
572
- el.style.cursor = String(value);
573
- },
574
- overflow: (el, value) => {
575
- el.style.overflow = String(value);
576
- },
577
- scrollable: (el, value) => {
578
- if (value === true || value === "true") {
579
- el.style.overflow = "auto";
580
- } else if (value === false || value === "false") {
581
- el.style.overflow = "hidden";
582
- } else if (value === "vertical") {
583
- el.style.overflowX = "hidden";
584
- el.style.overflowY = "auto";
585
- } else if (value === "horizontal") {
586
- el.style.overflowX = "auto";
587
- el.style.overflowY = "hidden";
588
- } else if (value === "both") {
589
- el.style.overflow = "auto";
590
- } else {
591
- el.style.overflow = String(value);
592
- }
593
- }
594
- };
595
-
596
- // src/dom/element-data.ts
597
- import { getElementDisposables } from "@hypen-space/core/disposable";
598
- var elementDataMap = new WeakMap;
599
- function getHypenData(element) {
600
- let data = elementDataMap.get(element);
601
- if (!data) {
602
- data = {};
603
- elementDataMap.set(element, data);
604
- }
605
- return data;
606
- }
607
- function hasHypenData(element) {
608
- return elementDataMap.has(element);
609
- }
610
- function clearHypenData(element) {
611
- elementDataMap.delete(element);
612
- }
613
- function getEngine(element) {
614
- return getHypenData(element).engine;
615
- }
616
- function setEngine(element, engine) {
617
- getHypenData(element).engine = engine;
618
- }
619
- function findEngine(element) {
620
- let current = element;
621
- while (current) {
622
- const engine = getEngine(current);
623
- if (engine)
624
- return engine;
625
- current = current.parentElement;
626
- }
627
- return;
628
- }
629
- function getRegisteredEvents(element) {
630
- const data = getHypenData(element);
631
- if (!data.registeredEvents) {
632
- data.registeredEvents = new Set;
633
- }
634
- return data.registeredEvents;
635
- }
636
- function isEventRegistered(element, eventKey) {
637
- return getRegisteredEvents(element).has(eventKey);
638
- }
639
- function registerEvent(element, eventKey) {
640
- getRegisteredEvents(element).add(eventKey);
641
- }
642
- function unregisterEvent(element, eventKey) {
643
- getRegisteredEvents(element).delete(eventKey);
644
- }
645
- function getKeyTarget(element) {
646
- return getHypenData(element).keyTarget;
647
- }
648
- function setKeyTarget(element, key) {
649
- getHypenData(element).keyTarget = key;
650
- }
651
- function getMeta(element, key) {
652
- return getHypenData(element).meta?.[key];
653
- }
654
- function setMeta(element, key, value) {
655
- const data = getHypenData(element);
656
- if (!data.meta) {
657
- data.meta = {};
658
- }
659
- data.meta[key] = value;
660
- }
661
- function disposeHypenElement(element) {
662
- try {
663
- const disposables = getElementDisposables(element);
664
- disposables.dispose();
665
- } catch {}
666
- clearHypenData(element);
667
- }
668
- var HYPEN_ENGINE_SYMBOL = Symbol.for("hypen.engine");
669
- var REGISTERED_EVENTS_SYMBOL = Symbol.for("hypen.registeredEvents");
670
- var KEY_TARGET_SYMBOL = Symbol.for("hypen.keyTarget");
671
- function getLegacyEngine(element) {
672
- const engine = getEngine(element);
673
- if (engine)
674
- return engine;
675
- return element[HYPEN_ENGINE_SYMBOL] ?? element.__hypenEngine;
676
- }
677
- function setLegacyEngine(element, engine) {
678
- setEngine(element, engine);
679
- element.__hypenEngine = engine;
680
- }
681
-
682
- // src/dom/applicators/events.ts
683
- import {
684
- getElementDisposables as getElementDisposables2,
685
- disposableListener,
686
- disposableTimeout
687
- } from "@hypen-space/core/disposable";
688
- import { frameworkLoggers } from "@hypen-space/core/logger";
689
- var log = frameworkLoggers.events;
690
- function toPlainObject(value) {
691
- if (value instanceof Map) {
692
- const obj = {};
693
- for (const [key, val] of value.entries()) {
694
- obj[key] = toPlainObject(val);
695
- }
696
- return obj;
697
- }
698
- if (Array.isArray(value)) {
699
- return value.map((item) => toPlainObject(item));
700
- }
701
- if (value && typeof value === "object") {
702
- const obj = {};
703
- for (const [key, val] of Object.entries(value)) {
704
- obj[key] = toPlainObject(val);
1
+ /**
2
+ * Applicator Registry
3
+ *
4
+ * Handles style applicators (modifiers) for Hypen components
5
+ */
6
+ // Static imports for all applicator handlers (avoids circular dependency)
7
+ import { paddingHandler, paddingTopHandler, paddingBottomHandler, paddingLeftHandler, paddingRightHandler, paddingHorizontalHandler, paddingVerticalHandler, } from "./padding.js";
8
+ import { marginHandler, marginTopHandler, marginBottomHandler, marginLeftHandler, marginRightHandler, marginHorizontalHandler, marginVerticalHandler, } from "./margin.js";
9
+ import { colorHandlers } from "./color.js";
10
+ import { borderHandlers } from "./border.js";
11
+ import { sizeHandlers } from "./size.js";
12
+ import { fontHandlers } from "./font.js";
13
+ import { layoutHandlers } from "./layout.js";
14
+ import { eventHandlers } from "./events.js";
15
+ import { typographyHandlers } from "./typography.js";
16
+ import { transformHandlers } from "./transform.js";
17
+ import { effectsHandlers } from "./effects.js";
18
+ import { advancedLayoutHandlers } from "./advanced-layout.js";
19
+ import { backgroundHandlers } from "./background.js";
20
+ import { displayHandlers } from "./display.js";
21
+ import { transitionHandlers } from "./transition.js";
22
+ /**
23
+ * Tailwind breakpoint values for responsive variants
24
+ */
25
+ const BREAKPOINTS = {
26
+ sm: '640px',
27
+ md: '768px',
28
+ lg: '1024px',
29
+ xl: '1280px',
30
+ '2xl': '1536px',
31
+ };
32
+ /**
33
+ * Singleton stylesheet for variant CSS rules
34
+ */
35
+ let variantStyleSheet = null;
36
+ /**
37
+ * Track inserted rules to avoid duplicates
38
+ */
39
+ const insertedRules = new Set();
40
+ /**
41
+ * Get or create the variant stylesheet
42
+ */
43
+ function getVariantStyleSheet() {
44
+ if (!variantStyleSheet) {
45
+ const style = document.createElement('style');
46
+ style.id = 'hypen-variants';
47
+ document.head.appendChild(style);
48
+ variantStyleSheet = style.sheet;
705
49
  }
706
- return obj;
707
- }
708
- return value;
50
+ return variantStyleSheet;
709
51
  }
710
- function extractActionDetails(value) {
711
- if (typeof value === "string") {
712
- if (!value.startsWith("@")) {
713
- return { actionName: null, payload: {} };
714
- }
715
- let actionName = value.substring(1);
716
- if (actionName.startsWith("actions.")) {
717
- actionName = actionName.substring(8);
718
- }
719
- return { actionName, payload: {} };
720
- }
721
- if (value && typeof value === "object") {
722
- const plain = toPlainObject(value);
723
- const payload = {};
724
- let actionName = null;
725
- if (plain && typeof plain === "object") {
726
- const actionValue = plain["0"];
727
- if (typeof actionValue === "string" && actionValue.startsWith("@")) {
728
- actionName = actionValue.substring(1);
729
- if (actionName.startsWith("actions.")) {
730
- actionName = actionName.substring(8);
52
+ /**
53
+ * Generate a simple hash for deduplication
54
+ */
55
+ function hashValue(value) {
56
+ return String(value).replace(/[^a-zA-Z0-9]/g, '').slice(0, 8);
57
+ }
58
+ export class ApplicatorRegistry {
59
+ handlers = new Map();
60
+ elementState = new WeakMap();
61
+ constructor() {
62
+ this.registerDefaults();
63
+ }
64
+ /**
65
+ * Register an applicator handler
66
+ */
67
+ register(name, handler) {
68
+ this.handlers.set(name, handler);
69
+ }
70
+ /**
71
+ * Apply an applicator to an element
72
+ */
73
+ apply(element, name, value) {
74
+ // Parse applicator metadata so we can normalize event arguments and retain legacy behavior
75
+ const { handlerName, argKey, aggregate, fallbackName } = this.parseApplicatorName(name);
76
+ const handler = this.handlers.get(handlerName);
77
+ const state = this.getElementState(element);
78
+ const previous = state.get(handlerName);
79
+ if (aggregate && argKey !== null) {
80
+ // Merge event payload updates with the previously applied arguments so handlers
81
+ // always receive the full payload object (prevents stale dispatch data)
82
+ const merged = this.mergeAggregateState(previous, argKey, this.normalizeValue(value));
83
+ state.set(handlerName, merged);
84
+ if (handler) {
85
+ handler(element, merged);
86
+ }
87
+ else {
88
+ // Fallback: set as CSS property using the original name if no handler exists
89
+ this.setStyleProperty(element, fallbackName, value);
90
+ }
91
+ return;
731
92
  }
732
- }
733
- for (const [key, val] of Object.entries(plain)) {
734
- if (key !== "0") {
735
- if (/^\d+$/.test(key) && val && typeof val === "object" && !Array.isArray(val)) {
736
- for (const [innerKey, innerVal] of Object.entries(val)) {
737
- payload[innerKey] = innerVal;
93
+ if (handler) {
94
+ if (this.isEventApplicator(handlerName)) {
95
+ const normalizedValue = this.normalizeEventValue(previous, value);
96
+ state.set(handlerName, normalizedValue);
97
+ handler(element, normalizedValue);
98
+ }
99
+ else {
100
+ state.set(handlerName, value);
101
+ handler(element, value);
738
102
  }
739
- } else {
740
- payload[key] = val;
741
- }
742
103
  }
743
- }
744
- }
745
- return { actionName, payload };
746
- }
747
- return { actionName: null, payload: {} };
748
- }
749
- function extractEventData(event, element) {
750
- const data = {
751
- type: event.type,
752
- timestamp: Date.now()
753
- };
754
- if (event instanceof MouseEvent) {
755
- data.clientX = event.clientX;
756
- data.clientY = event.clientY;
757
- data.button = event.button;
758
- }
759
- if (event instanceof KeyboardEvent) {
760
- data.key = event.key;
761
- data.code = event.code;
762
- data.ctrlKey = event.ctrlKey;
763
- data.shiftKey = event.shiftKey;
764
- data.altKey = event.altKey;
765
- data.metaKey = event.metaKey;
766
- }
767
- if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
768
- data.value = element.value;
769
- }
770
- if (element instanceof HTMLSelectElement) {
771
- data.value = element.value;
772
- data.selectedIndex = element.selectedIndex;
773
- }
774
- if (event.type === "submit" && element instanceof HTMLFormElement) {
775
- data.formData = new FormData(element);
776
- }
777
- return data;
778
- }
779
- function createEventHandler(eventType, options = {}) {
780
- return (element, value) => {
781
- const { actionName, payload: customPayload } = extractActionDetails(value);
782
- if (!actionName) {
783
- log.warn(`${eventType} requires an action reference starting with @, got:`, value);
784
- return;
785
- }
786
- const disposables = getElementDisposables2(element);
787
- const eventKey = `${eventType}:${actionName}`;
788
- if (getRegisteredEvents(element).has(eventKey)) {
789
- return;
790
- }
791
- registerEvent(element, eventKey);
792
- let throttleTimer = null;
793
- const listener = (event) => {
794
- if (options.throttleMs && throttleTimer) {
795
- return;
796
- }
797
- if (options.throttleMs) {
798
- throttleTimer = disposableTimeout(() => {
799
- throttleTimer = null;
800
- }, options.throttleMs);
801
- }
802
- if (options.preventDefault) {
803
- event.preventDefault();
804
- }
805
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : options.extractPayload ? options.extractPayload(event, element) : extractEventData(event, element);
806
- const engine = getEngine(element);
807
- if (engine) {
808
- try {
809
- engine.dispatchAction(actionName, payload);
810
- } catch (err) {
811
- log.error(`Error dispatching action "${actionName}":`, err);
104
+ else {
105
+ // Fallback: set as CSS property
106
+ this.setStyleProperty(element, handlerName, value);
812
107
  }
813
- }
814
- };
815
- disposables.add(disposableListener(element, eventType, listener, {
816
- passive: options.passive
817
- }));
818
- disposables.addCallback(() => {
819
- unregisterEvent(element, eventKey);
820
- if (throttleTimer) {
821
- throttleTimer.dispose();
822
- }
823
- });
824
- };
825
- }
826
- function createKeyHandler(defaultKey = "Enter") {
827
- return (element, value) => {
828
- const { actionName, payload: customPayload } = extractActionDetails(value);
829
- if (!actionName) {
830
- log.warn(`onKey requires an action reference starting with @, got:`, value);
831
- return;
832
108
  }
833
- const disposables = getElementDisposables2(element);
834
- const eventKey = `keydown:${actionName}:${defaultKey}`;
835
- if (getRegisteredEvents(element).has(eventKey)) {
836
- return;
837
- }
838
- registerEvent(element, eventKey);
839
- const targetKey = getKeyTarget(element) || defaultKey;
840
- const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
841
- const listener = (event) => {
842
- const keyEvent = event;
843
- if (keyEvent.key !== keyToMatch) {
844
- return;
845
- }
846
- event.preventDefault();
847
- const target = event.target;
848
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
849
- type: event.type,
850
- timestamp: Date.now(),
851
- key: keyEvent.key,
852
- code: keyEvent.code,
853
- value: target.value,
854
- input: target.value,
855
- ctrlKey: keyEvent.ctrlKey,
856
- shiftKey: keyEvent.shiftKey,
857
- altKey: keyEvent.altKey,
858
- metaKey: keyEvent.metaKey
859
- };
860
- const engine = getEngine(element);
861
- if (engine) {
862
- engine.dispatchAction(actionName, payload);
863
- }
864
- };
865
- disposables.add(disposableListener(element, "keydown", listener));
866
- disposables.addCallback(() => {
867
- unregisterEvent(element, eventKey);
868
- });
869
- };
870
- }
871
- function createLongClickHandler(thresholdMs = 500) {
872
- return (element, value) => {
873
- const { actionName, payload: customPayload } = extractActionDetails(value);
874
- if (!actionName) {
875
- log.warn(`onLongClick requires an action reference starting with @, got:`, value);
876
- return;
877
- }
878
- const disposables = getElementDisposables2(element);
879
- const eventKey = `longclick:${actionName}`;
880
- if (getRegisteredEvents(element).has(eventKey)) {
881
- return;
882
- }
883
- registerEvent(element, eventKey);
884
- let longClickTimer = null;
885
- const downListener = (event) => {
886
- const pointerEvent = event;
887
- longClickTimer = disposableTimeout(() => {
888
- const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
889
- type: "longclick",
890
- timestamp: Date.now(),
891
- clientX: pointerEvent.clientX,
892
- clientY: pointerEvent.clientY
893
- };
894
- const engine = getEngine(element);
895
- if (engine) {
896
- engine.dispatchAction(actionName, payload);
109
+ /**
110
+ * Parse applicator name to handle indexed and event argument formats
111
+ * e.g., "fontSize.0" -> { handlerName: "fontSize" }
112
+ * "onClick.id" -> { handlerName: "onClick", aggregate: true, argKey: "id" }
113
+ * Keeps compound names like "padding.top" as-is so they can fall back to CSS.
114
+ */
115
+ parseApplicatorName(name) {
116
+ const dotIndex = name.indexOf('.');
117
+ if (dotIndex === -1) {
118
+ return { handlerName: name, argKey: null, aggregate: false, fallbackName: name };
897
119
  }
898
- longClickTimer = null;
899
- }, thresholdMs);
900
- };
901
- const cancelListener = () => {
902
- if (longClickTimer) {
903
- longClickTimer.dispose();
904
- longClickTimer = null;
905
- }
906
- };
907
- disposables.add(disposableListener(element, "pointerdown", downListener));
908
- disposables.add(disposableListener(element, "pointerup", cancelListener));
909
- disposables.add(disposableListener(element, "pointerleave", cancelListener));
910
- disposables.addCallback(() => {
911
- unregisterEvent(element, eventKey);
912
- cancelListener();
913
- });
914
- };
915
- }
916
- var inputPayload = (event, element) => {
917
- const target = element;
918
- return {
919
- type: event.type,
920
- timestamp: Date.now(),
921
- value: target.value,
922
- input: target.value
923
- };
924
- };
925
- var scrollPayload = (_event, element) => {
926
- const scrollTop = element.scrollTop;
927
- const scrollHeight = element.scrollHeight;
928
- const clientHeight = element.clientHeight;
929
- const scrollPercentage = scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) * 100 : 0;
930
- const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
931
- return {
932
- type: "scroll",
933
- timestamp: Date.now(),
934
- scrollTop,
935
- scrollLeft: element.scrollLeft,
936
- scrollHeight,
937
- scrollWidth: element.scrollWidth,
938
- clientHeight,
939
- clientWidth: element.clientWidth,
940
- scrollPercentage: Math.round(scrollPercentage),
941
- nearBottom,
942
- atBottom: scrollHeight - scrollTop === clientHeight,
943
- atTop: scrollTop === 0
944
- };
945
- };
946
- var focusPayload = (event, element) => ({
947
- type: event.type,
948
- timestamp: Date.now(),
949
- value: element.value ?? undefined
950
- });
951
- var mousePayload = (event, _element) => {
952
- const mouseEvent = event;
953
- return {
954
- type: event.type,
955
- timestamp: Date.now(),
956
- clientX: mouseEvent.clientX,
957
- clientY: mouseEvent.clientY
958
- };
959
- };
960
- var eventHandlers = {
961
- onClick: createEventHandler("click"),
962
- onPress: createEventHandler("click"),
963
- onChange: createEventHandler("change"),
964
- onSubmit: createEventHandler("submit", { preventDefault: true }),
965
- onInput: createEventHandler("input", { extractPayload: inputPayload }),
966
- onKey: createKeyHandler("Enter"),
967
- "onKey.key": (element, value) => {
968
- setKeyTarget(element, String(value));
969
- },
970
- "onKey.action": createKeyHandler("Enter"),
971
- onScroll: createEventHandler("scroll", {
972
- throttleMs: 100,
973
- passive: true,
974
- extractPayload: scrollPayload
975
- }),
976
- onLongClick: createLongClickHandler(500),
977
- onLongPress: createLongClickHandler(500),
978
- onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
979
- onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
980
- onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
981
- onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload }),
982
- bind: (element, value) => {
983
- const bindPath = typeof value === "string" ? value : null;
984
- if (!bindPath)
985
- return;
986
- const disposables = getElementDisposables2(element);
987
- const eventKey = `bind:${bindPath}`;
988
- if (getRegisteredEvents(element).has(eventKey))
989
- return;
990
- registerEvent(element, eventKey);
991
- const hypenType = element.dataset?.hypenType;
992
- if (hypenType === "checkbox" || hypenType === "switch") {
993
- const input = element.querySelector('input[type="checkbox"]');
994
- if (!input)
995
- return;
996
- const listener = () => {
997
- const engine = getEngine(element);
998
- if (engine) {
999
- engine.dispatchAction("__hypen_bind", {
1000
- path: bindPath,
1001
- value: input.checked
1002
- });
120
+ const baseName = name.substring(0, dotIndex);
121
+ const argKey = name.substring(dotIndex + 1);
122
+ if (this.handlers.has(baseName) && this.isEventApplicator(baseName)) {
123
+ return { handlerName: baseName, argKey, aggregate: true, fallbackName: name };
1003
124
  }
1004
- };
1005
- disposables.add(disposableListener(input, "change", listener, { passive: true }));
1006
- } else if (element instanceof HTMLSelectElement) {
1007
- const listener = () => {
1008
- const engine = getEngine(element);
1009
- if (engine) {
1010
- engine.dispatchAction("__hypen_bind", {
1011
- path: bindPath,
1012
- value: element.value
1013
- });
125
+ if (/^\d+$/.test(argKey)) {
126
+ return { handlerName: baseName, argKey: null, aggregate: false, fallbackName: baseName };
1014
127
  }
1015
- };
1016
- disposables.add(disposableListener(element, "change", listener, { passive: true }));
1017
- } else if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
1018
- const listener = () => {
1019
- const engine = getEngine(element);
1020
- if (engine) {
1021
- engine.dispatchAction("__hypen_bind", {
1022
- path: bindPath,
1023
- value: element.value
1024
- });
128
+ return { handlerName: name, argKey: null, aggregate: false, fallbackName: name };
129
+ }
130
+ /**
131
+ * Get or initialize per-element applicator state used for merging event payloads
132
+ */
133
+ getElementState(element) {
134
+ let state = this.elementState.get(element);
135
+ if (!state) {
136
+ state = new Map();
137
+ this.elementState.set(element, state);
1025
138
  }
1026
- };
1027
- disposables.add(disposableListener(element, "input", listener, { passive: true }));
1028
- } else {
1029
- log.warn(`.bind() is not supported on element type "${element.dataset?.hypenType || element.tagName}". ` + `Supported types: input, textarea, checkbox, switch, select.`);
1030
- unregisterEvent(element, eventKey);
1031
- return;
1032
- }
1033
- disposables.addCallback(() => unregisterEvent(element, eventKey));
1034
- }
1035
- };
1036
-
1037
- // src/dom/applicators/typography.ts
1038
- var typographyHandlers = {
1039
- textAlign: (el, value) => {
1040
- el.style.textAlign = String(value);
1041
- },
1042
- textTransform: (el, value) => {
1043
- el.style.textTransform = String(value);
1044
- },
1045
- textDecoration: (el, value) => {
1046
- el.style.textDecoration = String(value);
1047
- },
1048
- textDecorationColor: (el, value) => {
1049
- el.style.textDecorationColor = String(value);
1050
- },
1051
- textDecorationStyle: (el, value) => {
1052
- el.style.textDecorationStyle = String(value);
1053
- },
1054
- textDecorationThickness: (el, value) => {
1055
- el.style.textDecorationThickness = typeof value === "number" ? `${value}px` : String(value);
1056
- },
1057
- letterSpacing: (el, value) => {
1058
- el.style.letterSpacing = typeof value === "number" ? `${value}px` : String(value);
1059
- },
1060
- wordSpacing: (el, value) => {
1061
- el.style.wordSpacing = typeof value === "number" ? `${value}px` : String(value);
1062
- },
1063
- lineHeight: (el, value) => {
1064
- el.style.lineHeight = String(value);
1065
- },
1066
- textIndent: (el, value) => {
1067
- el.style.textIndent = typeof value === "number" ? `${value}px` : String(value);
1068
- },
1069
- textOverflow: (el, value) => {
1070
- el.style.textOverflow = String(value);
1071
- },
1072
- whiteSpace: (el, value) => {
1073
- el.style.whiteSpace = String(value);
1074
- },
1075
- wordBreak: (el, value) => {
1076
- el.style.wordBreak = String(value);
1077
- },
1078
- verticalAlign: (el, value) => {
1079
- el.style.verticalAlign = String(value);
1080
- },
1081
- fontVariant: (el, value) => {
1082
- el.style.fontVariant = String(value);
1083
- },
1084
- fontStretch: (el, value) => {
1085
- el.style.fontStretch = String(value);
1086
- },
1087
- fontStyle: (el, value) => {
1088
- el.style.fontStyle = String(value);
1089
- },
1090
- writingMode: (el, value) => {
1091
- el.style.writingMode = String(value);
1092
- },
1093
- maxLines: (el, value) => {
1094
- const lines = typeof value === "number" ? value : parseInt(String(value), 10);
1095
- if (!isNaN(lines) && lines > 0) {
1096
- el.style.display = "-webkit-box";
1097
- el.style.setProperty("-webkit-line-clamp", String(lines));
1098
- el.style.setProperty("-webkit-box-orient", "vertical");
1099
- el.style.overflow = "hidden";
1100
- }
1101
- }
1102
- };
1103
-
1104
- // src/dom/applicators/transform.ts
1105
- var transformHandlers = {
1106
- transform: (el, value) => {
1107
- el.style.transform = String(value);
1108
- },
1109
- transformOrigin: (el, value) => {
1110
- el.style.transformOrigin = String(value);
1111
- },
1112
- translateX: (el, value) => {
1113
- const current = el.style.transform || "";
1114
- const val = typeof value === "number" ? `${value}px` : String(value);
1115
- el.style.transform = current ? `${current} translateX(${val})` : `translateX(${val})`;
1116
- },
1117
- translateY: (el, value) => {
1118
- const current = el.style.transform || "";
1119
- const val = typeof value === "number" ? `${value}px` : String(value);
1120
- el.style.transform = current ? `${current} translateY(${val})` : `translateY(${val})`;
1121
- },
1122
- translateZ: (el, value) => {
1123
- const current = el.style.transform || "";
1124
- const val = typeof value === "number" ? `${value}px` : String(value);
1125
- el.style.transform = current ? `${current} translateZ(${val})` : `translateZ(${val})`;
1126
- },
1127
- rotate: (el, value) => {
1128
- const current = el.style.transform || "";
1129
- const val = String(value);
1130
- el.style.transform = current ? `${current} rotate(${val})` : `rotate(${val})`;
1131
- },
1132
- rotateX: (el, value) => {
1133
- const current = el.style.transform || "";
1134
- const val = String(value);
1135
- el.style.transform = current ? `${current} rotateX(${val})` : `rotateX(${val})`;
1136
- },
1137
- rotateY: (el, value) => {
1138
- const current = el.style.transform || "";
1139
- const val = String(value);
1140
- el.style.transform = current ? `${current} rotateY(${val})` : `rotateY(${val})`;
1141
- },
1142
- rotateZ: (el, value) => {
1143
- const current = el.style.transform || "";
1144
- const val = String(value);
1145
- el.style.transform = current ? `${current} rotateZ(${val})` : `rotateZ(${val})`;
1146
- },
1147
- scale: (el, value) => {
1148
- const current = el.style.transform || "";
1149
- el.style.transform = current ? `${current} scale(${value})` : `scale(${value})`;
1150
- },
1151
- scaleX: (el, value) => {
1152
- const current = el.style.transform || "";
1153
- el.style.transform = current ? `${current} scaleX(${value})` : `scaleX(${value})`;
1154
- },
1155
- scaleY: (el, value) => {
1156
- const current = el.style.transform || "";
1157
- el.style.transform = current ? `${current} scaleY(${value})` : `scaleY(${value})`;
1158
- },
1159
- skew: (el, value) => {
1160
- const current = el.style.transform || "";
1161
- el.style.transform = current ? `${current} skew(${value})` : `skew(${value})`;
1162
- },
1163
- skewX: (el, value) => {
1164
- const current = el.style.transform || "";
1165
- el.style.transform = current ? `${current} skewX(${value})` : `skewX(${value})`;
1166
- },
1167
- skewY: (el, value) => {
1168
- const current = el.style.transform || "";
1169
- el.style.transform = current ? `${current} skewY(${value})` : `skewY(${value})`;
1170
- },
1171
- perspective: (el, value) => {
1172
- el.style.perspective = typeof value === "number" ? `${value}px` : String(value);
1173
- }
1174
- };
1175
-
1176
- // src/dom/applicators/effects.ts
1177
- var effectsHandlers = {
1178
- boxShadow: (el, value) => {
1179
- if (typeof value === "string") {
1180
- el.style.boxShadow = value;
1181
- } else if (typeof value === "object" && value !== null) {
1182
- const obj = value;
1183
- const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
1184
- const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
1185
- const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "0px";
1186
- const spread = typeof obj.spread === "number" ? `${obj.spread}px` : obj.spread ?? "0px";
1187
- const color = obj.color ?? "rgba(0,0,0,0.2)";
1188
- const inset = obj.inset ? "inset " : "";
1189
- el.style.boxShadow = `${inset}${x} ${y} ${blur} ${spread} ${color}`;
1190
- } else if (typeof value === "number") {
1191
- el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
1192
- }
1193
- },
1194
- shadow: (el, value) => {
1195
- if (typeof value === "object" && value !== null) {
1196
- const obj = value;
1197
- const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
1198
- const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
1199
- const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "4px";
1200
- const color = obj.color ?? "rgba(0,0,0,0.2)";
1201
- el.style.boxShadow = `${x} ${y} ${blur} ${color}`;
1202
- } else if (typeof value === "number") {
1203
- el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
1204
- } else {
1205
- el.style.boxShadow = String(value);
1206
- }
1207
- },
1208
- elevation: (el, value) => {
1209
- const level = typeof value === "number" ? value : parseInt(String(value), 10);
1210
- if (!isNaN(level) && level >= 0) {
1211
- const y = level * 0.5;
1212
- const blur = level * 1.5;
1213
- const opacity = Math.min(0.1 + level * 0.02, 0.4);
1214
- el.style.boxShadow = `0 ${y}px ${blur}px rgba(0,0,0,${opacity})`;
1215
- }
1216
- },
1217
- textShadow: (el, value) => {
1218
- el.style.textShadow = String(value);
1219
- },
1220
- filter: (el, value) => {
1221
- el.style.filter = String(value);
1222
- },
1223
- backdropFilter: (el, value) => {
1224
- el.style.backdropFilter = String(value);
1225
- },
1226
- blur: (el, value) => {
1227
- const val = typeof value === "number" ? `${value}px` : String(value);
1228
- const current = el.style.filter || "";
1229
- el.style.filter = current ? `${current} blur(${val})` : `blur(${val})`;
1230
- },
1231
- brightness: (el, value) => {
1232
- const current = el.style.filter || "";
1233
- el.style.filter = current ? `${current} brightness(${value})` : `brightness(${value})`;
1234
- },
1235
- contrast: (el, value) => {
1236
- const current = el.style.filter || "";
1237
- el.style.filter = current ? `${current} contrast(${value})` : `contrast(${value})`;
1238
- },
1239
- grayscale: (el, value) => {
1240
- const current = el.style.filter || "";
1241
- el.style.filter = current ? `${current} grayscale(${value})` : `grayscale(${value})`;
1242
- },
1243
- hueRotate: (el, value) => {
1244
- const val = String(value);
1245
- const current = el.style.filter || "";
1246
- el.style.filter = current ? `${current} hue-rotate(${val})` : `hue-rotate(${val})`;
1247
- },
1248
- invert: (el, value) => {
1249
- const current = el.style.filter || "";
1250
- el.style.filter = current ? `${current} invert(${value})` : `invert(${value})`;
1251
- },
1252
- saturate: (el, value) => {
1253
- const current = el.style.filter || "";
1254
- el.style.filter = current ? `${current} saturate(${value})` : `saturate(${value})`;
1255
- },
1256
- sepia: (el, value) => {
1257
- const current = el.style.filter || "";
1258
- el.style.filter = current ? `${current} sepia(${value})` : `sepia(${value})`;
1259
- },
1260
- dropShadow: (el, value) => {
1261
- const current = el.style.filter || "";
1262
- el.style.filter = current ? `${current} drop-shadow(${value})` : `drop-shadow(${value})`;
1263
- },
1264
- mixBlendMode: (el, value) => {
1265
- el.style.mixBlendMode = String(value);
1266
- },
1267
- backgroundBlendMode: (el, value) => {
1268
- el.style.backgroundBlendMode = String(value);
1269
- },
1270
- clipPath: (el, value) => {
1271
- el.style.clipPath = String(value);
1272
- },
1273
- mask: (el, value) => {
1274
- el.style.mask = String(value);
1275
- },
1276
- maskImage: (el, value) => {
1277
- el.style.maskImage = String(value);
1278
- }
1279
- };
1280
-
1281
- // src/dom/applicators/advanced-layout.ts
1282
- var advancedLayoutHandlers = {
1283
- flexDirection: (el, value) => {
1284
- el.style.flexDirection = String(value);
1285
- },
1286
- flexWrap: (el, value) => {
1287
- el.style.flexWrap = String(value);
1288
- },
1289
- flexBasis: (el, value) => {
1290
- el.style.flexBasis = typeof value === "number" ? `${value}px` : String(value);
1291
- },
1292
- alignContent: (el, value) => {
1293
- el.style.alignContent = String(value);
1294
- },
1295
- order: (el, value) => {
1296
- el.style.order = String(value);
1297
- },
1298
- gridTemplateColumns: (el, value) => {
1299
- el.style.gridTemplateColumns = String(value);
1300
- },
1301
- gridTemplateRows: (el, value) => {
1302
- el.style.gridTemplateRows = String(value);
1303
- },
1304
- gridColumns: (el, value) => {
1305
- if (typeof value === "number") {
1306
- el.style.gridTemplateColumns = `repeat(${value}, 1fr)`;
1307
- } else {
1308
- el.style.gridTemplateColumns = String(value);
1309
- }
1310
- },
1311
- gridRows: (el, value) => {
1312
- if (typeof value === "number") {
1313
- el.style.gridTemplateRows = `repeat(${value}, 1fr)`;
1314
- } else {
1315
- el.style.gridTemplateRows = String(value);
1316
- }
1317
- },
1318
- gridTemplateAreas: (el, value) => {
1319
- el.style.gridTemplateAreas = String(value);
1320
- },
1321
- gridColumn: (el, value) => {
1322
- el.style.gridColumn = String(value);
1323
- },
1324
- gridRow: (el, value) => {
1325
- el.style.gridRow = String(value);
1326
- },
1327
- gridArea: (el, value) => {
1328
- el.style.gridArea = String(value);
1329
- },
1330
- gridAutoFlow: (el, value) => {
1331
- el.style.gridAutoFlow = String(value);
1332
- },
1333
- gridAutoColumns: (el, value) => {
1334
- el.style.gridAutoColumns = String(value);
1335
- },
1336
- gridAutoRows: (el, value) => {
1337
- el.style.gridAutoRows = String(value);
1338
- },
1339
- rowGap: (el, value) => {
1340
- el.style.rowGap = typeof value === "number" ? `${value}px` : String(value);
1341
- },
1342
- columnGap: (el, value) => {
1343
- el.style.columnGap = typeof value === "number" ? `${value}px` : String(value);
1344
- },
1345
- placeItems: (el, value) => {
1346
- el.style.placeItems = String(value);
1347
- },
1348
- placeContent: (el, value) => {
1349
- el.style.placeContent = String(value);
1350
- },
1351
- placeSelf: (el, value) => {
1352
- el.style.placeSelf = String(value);
1353
- },
1354
- position: (el, value) => {
1355
- el.style.position = String(value);
1356
- },
1357
- top: (el, value) => {
1358
- el.style.top = typeof value === "number" ? `${value}px` : String(value);
1359
- },
1360
- right: (el, value) => {
1361
- el.style.right = typeof value === "number" ? `${value}px` : String(value);
1362
- },
1363
- bottom: (el, value) => {
1364
- el.style.bottom = typeof value === "number" ? `${value}px` : String(value);
1365
- },
1366
- left: (el, value) => {
1367
- el.style.left = typeof value === "number" ? `${value}px` : String(value);
1368
- },
1369
- inset: (el, value) => {
1370
- el.style.inset = typeof value === "number" ? `${value}px` : String(value);
1371
- },
1372
- zIndex: (el, value) => {
1373
- el.style.zIndex = String(value);
1374
- }
1375
- };
1376
-
1377
- // src/dom/applicators/background.ts
1378
- var backgroundHandlers = {
1379
- backgroundImage: (el, value) => {
1380
- el.style.backgroundImage = String(value);
1381
- },
1382
- backgroundSize: (el, value) => {
1383
- el.style.backgroundSize = String(value);
1384
- },
1385
- backgroundPosition: (el, value) => {
1386
- el.style.backgroundPosition = String(value);
1387
- },
1388
- backgroundRepeat: (el, value) => {
1389
- el.style.backgroundRepeat = String(value);
1390
- },
1391
- backgroundAttachment: (el, value) => {
1392
- el.style.backgroundAttachment = String(value);
1393
- },
1394
- backgroundClip: (el, value) => {
1395
- el.style.backgroundClip = String(value);
1396
- },
1397
- backgroundOrigin: (el, value) => {
1398
- el.style.backgroundOrigin = String(value);
1399
- },
1400
- linearGradient: (el, value) => {
1401
- el.style.backgroundImage = `linear-gradient(${value})`;
1402
- },
1403
- radialGradient: (el, value) => {
1404
- el.style.backgroundImage = `radial-gradient(${value})`;
1405
- },
1406
- conicGradient: (el, value) => {
1407
- el.style.backgroundImage = `conic-gradient(${value})`;
1408
- }
1409
- };
1410
-
1411
- // src/dom/applicators/display.ts
1412
- var displayHandlers = {
1413
- display: (el, value) => {
1414
- el.style.display = String(value);
1415
- },
1416
- visibility: (el, value) => {
1417
- el.style.visibility = String(value);
1418
- },
1419
- overflowX: (el, value) => {
1420
- el.style.overflowX = String(value);
1421
- },
1422
- overflowY: (el, value) => {
1423
- el.style.overflowY = String(value);
1424
- },
1425
- pointerEvents: (el, value) => {
1426
- el.style.pointerEvents = String(value);
1427
- },
1428
- userSelect: (el, value) => {
1429
- el.style.userSelect = String(value);
1430
- },
1431
- resize: (el, value) => {
1432
- el.style.resize = String(value);
1433
- },
1434
- boxSizing: (el, value) => {
1435
- el.style.boxSizing = String(value);
1436
- },
1437
- aspectRatio: (el, value) => {
1438
- el.style.aspectRatio = String(value);
1439
- },
1440
- objectFit: (el, value) => {
1441
- el.style.objectFit = String(value);
1442
- },
1443
- objectPosition: (el, value) => {
1444
- el.style.objectPosition = String(value);
1445
- }
1446
- };
1447
-
1448
- // src/dom/applicators/transition.ts
1449
- var transitionHandlers = {
1450
- transition: (el, value) => {
1451
- el.style.transition = String(value);
1452
- },
1453
- transitionProperty: (el, value) => {
1454
- el.style.transitionProperty = String(value);
1455
- },
1456
- transitionDuration: (el, value) => {
1457
- el.style.transitionDuration = String(value);
1458
- },
1459
- transitionTimingFunction: (el, value) => {
1460
- el.style.transitionTimingFunction = String(value);
1461
- },
1462
- transitionDelay: (el, value) => {
1463
- el.style.transitionDelay = String(value);
1464
- },
1465
- animation: (el, value) => {
1466
- el.style.animation = String(value);
1467
- },
1468
- animationName: (el, value) => {
1469
- el.style.animationName = String(value);
1470
- },
1471
- animationDuration: (el, value) => {
1472
- el.style.animationDuration = String(value);
1473
- },
1474
- animationTimingFunction: (el, value) => {
1475
- el.style.animationTimingFunction = String(value);
1476
- },
1477
- animationDelay: (el, value) => {
1478
- el.style.animationDelay = String(value);
1479
- },
1480
- animationIterationCount: (el, value) => {
1481
- el.style.animationIterationCount = String(value);
1482
- },
1483
- animationDirection: (el, value) => {
1484
- el.style.animationDirection = String(value);
1485
- },
1486
- animationFillMode: (el, value) => {
1487
- el.style.animationFillMode = String(value);
1488
- },
1489
- animationPlayState: (el, value) => {
1490
- el.style.animationPlayState = String(value);
1491
- }
1492
- };
1493
-
1494
- // src/dom/applicators/index.ts
1495
- var BREAKPOINTS = {
1496
- sm: "640px",
1497
- md: "768px",
1498
- lg: "1024px",
1499
- xl: "1280px",
1500
- "2xl": "1536px"
1501
- };
1502
- var variantStyleSheet = null;
1503
- var insertedRules = new Set;
1504
- function getVariantStyleSheet() {
1505
- if (!variantStyleSheet) {
1506
- const style = document.createElement("style");
1507
- style.id = "hypen-variants";
1508
- document.head.appendChild(style);
1509
- variantStyleSheet = style.sheet;
1510
- }
1511
- return variantStyleSheet;
1512
- }
1513
- function hashValue(value) {
1514
- return String(value).replace(/[^a-zA-Z0-9]/g, "").slice(0, 8);
1515
- }
1516
-
1517
- class ApplicatorRegistry {
1518
- handlers = new Map;
1519
- elementState = new WeakMap;
1520
- constructor() {
1521
- this.registerDefaults();
1522
- }
1523
- register(name, handler) {
1524
- this.handlers.set(name, handler);
1525
- }
1526
- apply(element, name, value) {
1527
- const { handlerName, argKey, aggregate, fallbackName } = this.parseApplicatorName(name);
1528
- const handler = this.handlers.get(handlerName);
1529
- const state = this.getElementState(element);
1530
- const previous = state.get(handlerName);
1531
- if (aggregate && argKey !== null) {
1532
- const merged = this.mergeAggregateState(previous, argKey, this.normalizeValue(value));
1533
- state.set(handlerName, merged);
1534
- if (handler) {
1535
- handler(element, merged);
1536
- } else {
1537
- this.setStyleProperty(element, fallbackName, value);
1538
- }
1539
- return;
1540
- }
1541
- if (handler) {
1542
- if (this.isEventApplicator(handlerName)) {
1543
- const normalizedValue = this.normalizeEventValue(previous, value);
1544
- state.set(handlerName, normalizedValue);
1545
- handler(element, normalizedValue);
1546
- } else {
1547
- state.set(handlerName, value);
1548
- handler(element, value);
1549
- }
1550
- } else {
1551
- this.setStyleProperty(element, handlerName, value);
1552
- }
1553
- }
1554
- parseApplicatorName(name) {
1555
- const dotIndex = name.indexOf(".");
1556
- if (dotIndex === -1) {
1557
- return { handlerName: name, argKey: null, aggregate: false, fallbackName: name };
1558
- }
1559
- const baseName = name.substring(0, dotIndex);
1560
- const argKey = name.substring(dotIndex + 1);
1561
- if (this.handlers.has(baseName) && this.isEventApplicator(baseName)) {
1562
- return { handlerName: baseName, argKey, aggregate: true, fallbackName: name };
1563
- }
1564
- if (/^\d+$/.test(argKey)) {
1565
- return { handlerName: baseName, argKey: null, aggregate: false, fallbackName: baseName };
1566
- }
1567
- return { handlerName: name, argKey: null, aggregate: false, fallbackName: name };
1568
- }
1569
- getElementState(element) {
1570
- let state = this.elementState.get(element);
1571
- if (!state) {
1572
- state = new Map;
1573
- this.elementState.set(element, state);
1574
- }
1575
- return state;
1576
- }
1577
- mergeAggregateState(previous, argKey, value) {
1578
- const base = this.cloneAggregateState(previous);
1579
- if (value === undefined) {
1580
- delete base[argKey];
1581
- } else {
1582
- base[argKey] = value;
1583
- }
1584
- return base;
1585
- }
1586
- cloneAggregateState(previous) {
1587
- if (previous && typeof previous === "object" && !Array.isArray(previous)) {
1588
- return { ...previous };
1589
- }
1590
- if (typeof previous === "string") {
1591
- return { "0": previous };
1592
- }
1593
- return {};
1594
- }
1595
- normalizeEventValue(previous, value) {
1596
- const normalizedInput = this.normalizeValue(value);
1597
- const base = this.cloneAggregateState(previous);
1598
- if (normalizedInput && typeof normalizedInput === "object" && !Array.isArray(normalizedInput)) {
1599
- const next = { ...base, ...normalizedInput };
1600
- if (!Object.prototype.hasOwnProperty.call(next, "0") && base["0"] !== undefined) {
1601
- next["0"] = base["0"];
1602
- }
1603
- return next;
1604
- }
1605
- if (normalizedInput !== undefined) {
1606
- base["0"] = normalizedInput;
1607
- }
1608
- return base;
1609
- }
1610
- normalizeValue(value) {
1611
- if (value instanceof Map) {
1612
- const obj = {};
1613
- for (const [key, val] of value.entries()) {
1614
- obj[key] = this.normalizeValue(val);
1615
- }
1616
- return obj;
1617
- }
1618
- if (Array.isArray(value)) {
1619
- return value.map((item) => this.normalizeValue(item));
1620
- }
1621
- if (value && typeof value === "object") {
1622
- const obj = {};
1623
- for (const [key, val] of Object.entries(value)) {
1624
- obj[key] = this.normalizeValue(val);
1625
- }
1626
- return obj;
1627
- }
1628
- return value;
1629
- }
1630
- isEventApplicator(name) {
1631
- return /^on[A-Z]/.test(name);
1632
- }
1633
- applyAll(element, applicators) {
1634
- const grouped = new Map;
1635
- for (const [name, value] of Object.entries(applicators)) {
1636
- const dotIndex = name.indexOf(".");
1637
- const baseName = dotIndex !== -1 ? name.substring(0, dotIndex) : name;
1638
- const argKey = dotIndex !== -1 ? name.substring(dotIndex + 1) : null;
1639
- if (!grouped.has(baseName)) {
1640
- grouped.set(baseName, {});
1641
- }
1642
- const args = grouped.get(baseName);
1643
- if (argKey !== null) {
1644
- args[argKey] = value;
1645
- } else {
1646
- args["__value"] = value;
1647
- }
1648
- }
1649
- for (const [baseName, args] of grouped.entries()) {
1650
- if (Object.keys(args).length === 1) {
1651
- if ("__value" in args) {
1652
- this.apply(element, baseName, args["__value"]);
1653
- } else if ("0" in args) {
1654
- this.apply(element, baseName, args["0"]);
1655
- } else {
1656
- this.apply(element, baseName, args);
139
+ return state;
140
+ }
141
+ /**
142
+ * Merge updated event argument into previously stored payload snapshot
143
+ */
144
+ mergeAggregateState(previous, argKey, value) {
145
+ const base = this.cloneAggregateState(previous);
146
+ if (value === undefined) {
147
+ delete base[argKey];
1657
148
  }
1658
- } else {
1659
- this.apply(element, baseName, args);
1660
- }
1661
- }
1662
- }
1663
- setStyleProperty(element, name, value) {
1664
- const atIndex = name.indexOf("@");
1665
- const colonIndex = name.indexOf(":");
1666
- if (atIndex !== -1) {
1667
- const prop = name.slice(0, atIndex);
1668
- const breakpoint = name.slice(atIndex + 1);
1669
- const minWidth = BREAKPOINTS[breakpoint];
1670
- if (minWidth) {
1671
- const cssName2 = this.toKebabCase(prop);
1672
- const cssValue = this.formatCssValue(cssName2, value);
1673
- const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${breakpoint}-${hashValue(value)}`;
1674
- const ruleKey = `${className}:${cssValue}`;
1675
- if (!insertedRules.has(ruleKey)) {
1676
- const sheet = getVariantStyleSheet();
1677
- sheet.insertRule(`@media (min-width: ${minWidth}) { .${className} { ${cssName2}: ${cssValue}; } }`, sheet.cssRules.length);
1678
- insertedRules.add(ruleKey);
149
+ else {
150
+ base[argKey] = value;
1679
151
  }
1680
- element.classList.add(className);
1681
- }
1682
- return;
1683
- }
1684
- if (colonIndex !== -1) {
1685
- const prop = name.slice(0, colonIndex);
1686
- const state = name.slice(colonIndex + 1);
1687
- const validStates = ["hover", "focus", "active", "disabled", "focus-visible", "focus-within"];
1688
- if (validStates.includes(state)) {
1689
- const cssName2 = this.toKebabCase(prop);
1690
- const cssValue = this.formatCssValue(cssName2, value);
1691
- const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${state}-${hashValue(value)}`;
1692
- const ruleKey = `${className}:${cssValue}`;
1693
- if (!insertedRules.has(ruleKey)) {
1694
- const sheet = getVariantStyleSheet();
1695
- sheet.insertRule(`.${className}:${state} { ${cssName2}: ${cssValue}; }`, sheet.cssRules.length);
1696
- insertedRules.add(ruleKey);
152
+ return base;
153
+ }
154
+ /**
155
+ * Convert stored state into a mutable payload object we can merge into
156
+ */
157
+ cloneAggregateState(previous) {
158
+ if (previous && typeof previous === "object" && !Array.isArray(previous)) {
159
+ return { ...previous };
160
+ }
161
+ if (typeof previous === "string") {
162
+ return { "0": previous };
163
+ }
164
+ return {};
165
+ }
166
+ /**
167
+ * Normalize event value updates so action payload arguments persist across SetProp orderings
168
+ */
169
+ normalizeEventValue(previous, value) {
170
+ const normalizedInput = this.normalizeValue(value);
171
+ const base = this.cloneAggregateState(previous);
172
+ if (normalizedInput && typeof normalizedInput === "object" && !Array.isArray(normalizedInput)) {
173
+ const next = { ...base, ...normalizedInput };
174
+ if (!Object.prototype.hasOwnProperty.call(next, "0") && base["0"] !== undefined) {
175
+ next["0"] = base["0"];
176
+ }
177
+ return next;
178
+ }
179
+ if (normalizedInput !== undefined) {
180
+ base["0"] = normalizedInput;
181
+ }
182
+ return base;
183
+ }
184
+ /**
185
+ * Convert Maps (from WASM) and nested structures into plain JS values we can merge safely
186
+ */
187
+ normalizeValue(value) {
188
+ if (value instanceof Map) {
189
+ const obj = {};
190
+ for (const [key, val] of value.entries()) {
191
+ obj[key] = this.normalizeValue(val);
192
+ }
193
+ return obj;
194
+ }
195
+ if (Array.isArray(value)) {
196
+ return value.map((item) => this.normalizeValue(item));
197
+ }
198
+ if (value && typeof value === "object") {
199
+ const obj = {};
200
+ for (const [key, val] of Object.entries(value)) {
201
+ obj[key] = this.normalizeValue(val);
202
+ }
203
+ return obj;
204
+ }
205
+ return value;
206
+ }
207
+ /**
208
+ * Determine if a handler name follows the event applicator naming convention
209
+ */
210
+ isEventApplicator(name) {
211
+ return /^on[A-Z]/.test(name);
212
+ }
213
+ /**
214
+ * Apply multiple applicators
215
+ */
216
+ applyAll(element, applicators) {
217
+ //console.log(`[ApplicatorRegistry] Applying applicators:`, applicators);
218
+ // Group applicators by their base name (treat applicators like components with arguments)
219
+ // e.g., "onClick.0", "onClick.id", "onClick.title" -> onClick: {0: ..., id: ..., title: ...}
220
+ const grouped = new Map();
221
+ for (const [name, value] of Object.entries(applicators)) {
222
+ // Extract base name and argument key
223
+ const dotIndex = name.indexOf('.');
224
+ const baseName = dotIndex !== -1 ? name.substring(0, dotIndex) : name;
225
+ const argKey = dotIndex !== -1 ? name.substring(dotIndex + 1) : null;
226
+ if (!grouped.has(baseName)) {
227
+ grouped.set(baseName, {});
228
+ }
229
+ const args = grouped.get(baseName);
230
+ if (argKey !== null) {
231
+ // This is an argument (e.g., "onClick.0" or "onClick.id")
232
+ args[argKey] = value;
233
+ }
234
+ else {
235
+ // This is a single-value applicator (e.g., "padding")
236
+ args['__value'] = value;
237
+ }
238
+ }
239
+ // Apply each applicator with its arguments
240
+ for (const [baseName, args] of grouped.entries()) {
241
+ // If it's a single value (either __value or just "0"), pass just the value
242
+ if (Object.keys(args).length === 1) {
243
+ if ('__value' in args) {
244
+ this.apply(element, baseName, args['__value']);
245
+ }
246
+ else if ('0' in args) {
247
+ // Single positional argument (e.g., padding.0 -> just pass the value)
248
+ this.apply(element, baseName, args['0']);
249
+ }
250
+ else {
251
+ // Single named argument? Pass the whole object
252
+ this.apply(element, baseName, args);
253
+ }
254
+ }
255
+ else {
256
+ // Multiple arguments - pass the entire args object
257
+ this.apply(element, baseName, args);
258
+ }
1697
259
  }
1698
- element.classList.add(className);
1699
- }
1700
- return;
1701
- }
1702
- const cssName = this.toKebabCase(name);
1703
- element.style.setProperty(cssName, this.formatCssValue(cssName, value));
1704
- }
1705
- toKebabCase(name) {
1706
- return name.replace(/([A-Z])/g, "-$1").toLowerCase();
1707
- }
1708
- formatCssValue(cssName, value) {
1709
- if (typeof value === "number" && this.needsUnit(cssName)) {
1710
- return `${value}px`;
1711
- }
1712
- return String(value);
1713
- }
1714
- needsUnit(prop) {
1715
- const unitless = [
1716
- "opacity",
1717
- "z-index",
1718
- "font-weight",
1719
- "line-height",
1720
- "flex",
1721
- "flex-grow",
1722
- "flex-shrink",
1723
- "order"
1724
- ];
1725
- return !unitless.includes(prop);
1726
- }
1727
- registerDefaults() {
1728
- this.register("padding", paddingHandler);
1729
- this.register("paddingTop", paddingTopHandler);
1730
- this.register("paddingBottom", paddingBottomHandler);
1731
- this.register("paddingLeft", paddingLeftHandler);
1732
- this.register("paddingRight", paddingRightHandler);
1733
- this.register("paddingHorizontal", paddingHorizontalHandler);
1734
- this.register("paddingVertical", paddingVerticalHandler);
1735
- this.register("margin", marginHandler);
1736
- this.register("marginTop", marginTopHandler);
1737
- this.register("marginBottom", marginBottomHandler);
1738
- this.register("marginLeft", marginLeftHandler);
1739
- this.register("marginRight", marginRightHandler);
1740
- this.register("marginHorizontal", marginHorizontalHandler);
1741
- this.register("marginVertical", marginVerticalHandler);
1742
- for (const [name, handler] of Object.entries(colorHandlers)) {
1743
- this.register(name, handler);
1744
- }
1745
- for (const [name, handler] of Object.entries(borderHandlers)) {
1746
- this.register(name, handler);
1747
- }
1748
- for (const [name, handler] of Object.entries(sizeHandlers)) {
1749
- this.register(name, handler);
1750
- }
1751
- for (const [name, handler] of Object.entries(fontHandlers)) {
1752
- this.register(name, handler);
1753
- }
1754
- for (const [name, handler] of Object.entries(layoutHandlers)) {
1755
- this.register(name, handler);
1756
- }
1757
- for (const [name, handler] of Object.entries(eventHandlers)) {
1758
- this.register(name, handler);
1759
- }
1760
- for (const [name, handler] of Object.entries(typographyHandlers)) {
1761
- this.register(name, handler);
1762
- }
1763
- for (const [name, handler] of Object.entries(transformHandlers)) {
1764
- this.register(name, handler);
1765
- }
1766
- for (const [name, handler] of Object.entries(effectsHandlers)) {
1767
- this.register(name, handler);
1768
- }
1769
- for (const [name, handler] of Object.entries(advancedLayoutHandlers)) {
1770
- this.register(name, handler);
1771
- }
1772
- for (const [name, handler] of Object.entries(backgroundHandlers)) {
1773
- this.register(name, handler);
1774
- }
1775
- for (const [name, handler] of Object.entries(displayHandlers)) {
1776
- this.register(name, handler);
1777
260
  }
1778
- for (const [name, handler] of Object.entries(transitionHandlers)) {
1779
- this.register(name, handler);
261
+ /**
262
+ * Set a CSS property with automatic unit handling and variant support
263
+ */
264
+ setStyleProperty(element, name, value) {
265
+ const atIndex = name.indexOf('@');
266
+ const colonIndex = name.indexOf(':');
267
+ // Responsive variant: padding@md, width@lg, etc.
268
+ if (atIndex !== -1) {
269
+ const prop = name.slice(0, atIndex);
270
+ const breakpoint = name.slice(atIndex + 1);
271
+ const minWidth = BREAKPOINTS[breakpoint];
272
+ if (minWidth) {
273
+ const cssName = this.toKebabCase(prop);
274
+ const cssValue = this.formatCssValue(cssName, value);
275
+ const className = `hypen-${cssName.replace(/[^a-zA-Z0-9-]/g, '')}-${breakpoint}-${hashValue(value)}`;
276
+ const ruleKey = `${className}:${cssValue}`;
277
+ // Avoid duplicate rule insertion
278
+ if (!insertedRules.has(ruleKey)) {
279
+ const sheet = getVariantStyleSheet();
280
+ sheet.insertRule(`@media (min-width: ${minWidth}) { .${className} { ${cssName}: ${cssValue}; } }`, sheet.cssRules.length);
281
+ insertedRules.add(ruleKey);
282
+ }
283
+ element.classList.add(className);
284
+ }
285
+ return;
286
+ }
287
+ // State variant: background-color:hover, border-color:focus, etc.
288
+ if (colonIndex !== -1) {
289
+ const prop = name.slice(0, colonIndex);
290
+ const state = name.slice(colonIndex + 1);
291
+ // Only handle known CSS pseudo-states
292
+ const validStates = ['hover', 'focus', 'active', 'disabled', 'focus-visible', 'focus-within'];
293
+ if (validStates.includes(state)) {
294
+ const cssName = this.toKebabCase(prop);
295
+ const cssValue = this.formatCssValue(cssName, value);
296
+ const className = `hypen-${cssName.replace(/[^a-zA-Z0-9-]/g, '')}-${state}-${hashValue(value)}`;
297
+ const ruleKey = `${className}:${cssValue}`;
298
+ // Avoid duplicate rule insertion
299
+ if (!insertedRules.has(ruleKey)) {
300
+ const sheet = getVariantStyleSheet();
301
+ sheet.insertRule(`.${className}:${state} { ${cssName}: ${cssValue}; }`, sheet.cssRules.length);
302
+ insertedRules.add(ruleKey);
303
+ }
304
+ element.classList.add(className);
305
+ }
306
+ return;
307
+ }
308
+ // Normal property: convert camelCase to kebab-case and apply
309
+ const cssName = this.toKebabCase(name);
310
+ element.style.setProperty(cssName, this.formatCssValue(cssName, value));
311
+ }
312
+ /**
313
+ * Convert camelCase to kebab-case
314
+ */
315
+ toKebabCase(name) {
316
+ return name.replace(/([A-Z])/g, "-$1").toLowerCase();
317
+ }
318
+ /**
319
+ * Format a CSS value with automatic unit handling
320
+ */
321
+ formatCssValue(cssName, value) {
322
+ if (typeof value === "number" && this.needsUnit(cssName)) {
323
+ return `${value}px`;
324
+ }
325
+ return String(value);
326
+ }
327
+ /**
328
+ * Check if a property needs a unit
329
+ */
330
+ needsUnit(prop) {
331
+ const unitless = [
332
+ "opacity",
333
+ "z-index",
334
+ "font-weight",
335
+ "line-height",
336
+ "flex",
337
+ "flex-grow",
338
+ "flex-shrink",
339
+ "order",
340
+ ];
341
+ return !unitless.includes(prop);
342
+ }
343
+ /**
344
+ * Register default applicator handlers
345
+ * Uses statically imported handlers (defined at top of file) to avoid circular dependencies
346
+ */
347
+ registerDefaults() {
348
+ this.register("padding", paddingHandler);
349
+ this.register("paddingTop", paddingTopHandler);
350
+ this.register("paddingBottom", paddingBottomHandler);
351
+ this.register("paddingLeft", paddingLeftHandler);
352
+ this.register("paddingRight", paddingRightHandler);
353
+ this.register("paddingHorizontal", paddingHorizontalHandler);
354
+ this.register("paddingVertical", paddingVerticalHandler);
355
+ this.register("margin", marginHandler);
356
+ this.register("marginTop", marginTopHandler);
357
+ this.register("marginBottom", marginBottomHandler);
358
+ this.register("marginLeft", marginLeftHandler);
359
+ this.register("marginRight", marginRightHandler);
360
+ this.register("marginHorizontal", marginHorizontalHandler);
361
+ this.register("marginVertical", marginVerticalHandler);
362
+ for (const [name, handler] of Object.entries(colorHandlers)) {
363
+ this.register(name, handler);
364
+ }
365
+ for (const [name, handler] of Object.entries(borderHandlers)) {
366
+ this.register(name, handler);
367
+ }
368
+ for (const [name, handler] of Object.entries(sizeHandlers)) {
369
+ this.register(name, handler);
370
+ }
371
+ for (const [name, handler] of Object.entries(fontHandlers)) {
372
+ this.register(name, handler);
373
+ }
374
+ for (const [name, handler] of Object.entries(layoutHandlers)) {
375
+ this.register(name, handler);
376
+ }
377
+ for (const [name, handler] of Object.entries(eventHandlers)) {
378
+ this.register(name, handler);
379
+ }
380
+ for (const [name, handler] of Object.entries(typographyHandlers)) {
381
+ this.register(name, handler);
382
+ }
383
+ for (const [name, handler] of Object.entries(transformHandlers)) {
384
+ this.register(name, handler);
385
+ }
386
+ for (const [name, handler] of Object.entries(effectsHandlers)) {
387
+ this.register(name, handler);
388
+ }
389
+ for (const [name, handler] of Object.entries(advancedLayoutHandlers)) {
390
+ this.register(name, handler);
391
+ }
392
+ for (const [name, handler] of Object.entries(backgroundHandlers)) {
393
+ this.register(name, handler);
394
+ }
395
+ for (const [name, handler] of Object.entries(displayHandlers)) {
396
+ this.register(name, handler);
397
+ }
398
+ for (const [name, handler] of Object.entries(transitionHandlers)) {
399
+ this.register(name, handler);
400
+ }
1780
401
  }
1781
- }
1782
402
  }
1783
- export {
1784
- ApplicatorRegistry
1785
- };
1786
-
1787
- //# debugId=B381B58060F7445564756E2164756E21
403
+ //# sourceMappingURL=index.js.map