@hypen-space/web 0.2.12 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/dom/applicators/effects.js +38 -2
- package/dist/src/dom/applicators/effects.js.map +3 -3
- package/dist/src/dom/applicators/events.js +280 -397
- package/dist/src/dom/applicators/events.js.map +5 -4
- package/dist/src/dom/applicators/font.js +94 -5
- package/dist/src/dom/applicators/font.js.map +3 -3
- package/dist/src/dom/applicators/index.js +590 -425
- package/dist/src/dom/applicators/index.js.map +10 -9
- package/dist/src/dom/applicators/layout.js +33 -5
- package/dist/src/dom/applicators/layout.js.map +3 -3
- package/dist/src/dom/applicators/size.js +81 -16
- package/dist/src/dom/applicators/size.js.map +3 -3
- package/dist/src/dom/components/hypenapp.js +296 -0
- package/dist/src/dom/components/hypenapp.js.map +10 -0
- package/dist/src/dom/components/index.js +263 -1
- package/dist/src/dom/components/index.js.map +5 -4
- package/dist/src/dom/element-data.js +140 -0
- package/dist/src/dom/element-data.js.map +10 -0
- package/dist/src/dom/index.js +857 -430
- package/dist/src/dom/index.js.map +13 -11
- package/dist/src/dom/renderer.js +857 -430
- package/dist/src/dom/renderer.js.map +13 -11
- package/dist/src/hypen.js +857 -430
- package/dist/src/hypen.js.map +13 -11
- package/dist/src/index.js +862 -430
- package/dist/src/index.js.map +15 -12
- package/package.json +3 -3
- package/src/canvas/QUICKSTART.md +2 -4
- package/src/dom/applicators/effects.ts +45 -1
- package/src/dom/applicators/events.ts +348 -537
- package/src/dom/applicators/font.ts +127 -2
- package/src/dom/applicators/index.ts +117 -7
- package/src/dom/applicators/layout.ts +40 -4
- package/src/dom/applicators/size.ts +101 -16
- package/src/dom/components/hypenapp.ts +348 -0
- package/src/dom/components/index.ts +2 -0
- package/src/dom/element-data.ts +234 -0
- package/src/dom/renderer.ts +8 -5
- package/src/index.ts +3 -0
package/dist/src/dom/index.js
CHANGED
|
@@ -973,6 +973,266 @@ var init_route = __esm(() => {
|
|
|
973
973
|
};
|
|
974
974
|
});
|
|
975
975
|
|
|
976
|
+
// src/dom/components/hypenapp.ts
|
|
977
|
+
var exports_hypenapp = {};
|
|
978
|
+
__export(exports_hypenapp, {
|
|
979
|
+
hypenAppHandler: () => hypenAppHandler,
|
|
980
|
+
disconnectHypenApp: () => disconnectHypenApp
|
|
981
|
+
});
|
|
982
|
+
import { RemoteEngine } from "@hypen-space/core/remote/client";
|
|
983
|
+
function applyPatches(container, nodes, patches, engine, onRoot) {
|
|
984
|
+
for (const patch of patches) {
|
|
985
|
+
switch (patch.type) {
|
|
986
|
+
case "create": {
|
|
987
|
+
const el = createElement(patch.element_type, patch.props || {});
|
|
988
|
+
el.dataset.hypenId = patch.id;
|
|
989
|
+
el.__hypenEngine = engine;
|
|
990
|
+
nodes.set(patch.id, el);
|
|
991
|
+
break;
|
|
992
|
+
}
|
|
993
|
+
case "setProp": {
|
|
994
|
+
const el = nodes.get(patch.id);
|
|
995
|
+
if (el) {
|
|
996
|
+
applyProp(el, patch.name, patch.value);
|
|
997
|
+
}
|
|
998
|
+
break;
|
|
999
|
+
}
|
|
1000
|
+
case "setText": {
|
|
1001
|
+
const el = nodes.get(patch.id);
|
|
1002
|
+
if (el) {
|
|
1003
|
+
el.textContent = patch.text;
|
|
1004
|
+
}
|
|
1005
|
+
break;
|
|
1006
|
+
}
|
|
1007
|
+
case "insert": {
|
|
1008
|
+
const parentId = patch.parent_id;
|
|
1009
|
+
const parent = parentId === "root" ? container : nodes.get(parentId);
|
|
1010
|
+
const child = nodes.get(patch.id);
|
|
1011
|
+
const beforeId = patch.before_id;
|
|
1012
|
+
if (parent && child) {
|
|
1013
|
+
if (parentId === "root") {
|
|
1014
|
+
onRoot(patch.id);
|
|
1015
|
+
}
|
|
1016
|
+
if (beforeId) {
|
|
1017
|
+
const before = nodes.get(beforeId);
|
|
1018
|
+
if (before && before.parentNode === parent) {
|
|
1019
|
+
parent.insertBefore(child, before);
|
|
1020
|
+
} else if (!parent.contains(child)) {
|
|
1021
|
+
parent.appendChild(child);
|
|
1022
|
+
}
|
|
1023
|
+
} else if (!parent.contains(child)) {
|
|
1024
|
+
parent.appendChild(child);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
break;
|
|
1028
|
+
}
|
|
1029
|
+
case "move": {
|
|
1030
|
+
const parentId = patch.parent_id;
|
|
1031
|
+
const parent = parentId === "root" ? container : nodes.get(parentId);
|
|
1032
|
+
const child = nodes.get(patch.id);
|
|
1033
|
+
const beforeId = patch.before_id;
|
|
1034
|
+
if (parent && child) {
|
|
1035
|
+
if (beforeId) {
|
|
1036
|
+
const before = nodes.get(beforeId);
|
|
1037
|
+
if (before && before.parentNode === parent) {
|
|
1038
|
+
parent.insertBefore(child, before);
|
|
1039
|
+
}
|
|
1040
|
+
} else {
|
|
1041
|
+
parent.appendChild(child);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
break;
|
|
1045
|
+
}
|
|
1046
|
+
case "remove": {
|
|
1047
|
+
const el = nodes.get(patch.id);
|
|
1048
|
+
if (el && el.parentNode) {
|
|
1049
|
+
el.parentNode.removeChild(el);
|
|
1050
|
+
}
|
|
1051
|
+
nodes.delete(patch.id);
|
|
1052
|
+
break;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function createElement(type, props) {
|
|
1058
|
+
const normalizedType = type.toLowerCase();
|
|
1059
|
+
const tagMap = {
|
|
1060
|
+
column: "div",
|
|
1061
|
+
row: "div",
|
|
1062
|
+
text: "span",
|
|
1063
|
+
button: "button",
|
|
1064
|
+
input: "input",
|
|
1065
|
+
image: "img",
|
|
1066
|
+
container: "div",
|
|
1067
|
+
box: "div",
|
|
1068
|
+
center: "div",
|
|
1069
|
+
list: "div",
|
|
1070
|
+
spacer: "div",
|
|
1071
|
+
stack: "div",
|
|
1072
|
+
divider: "hr",
|
|
1073
|
+
grid: "div",
|
|
1074
|
+
card: "div",
|
|
1075
|
+
heading: "h2",
|
|
1076
|
+
link: "a",
|
|
1077
|
+
textarea: "textarea",
|
|
1078
|
+
checkbox: "input",
|
|
1079
|
+
select: "select",
|
|
1080
|
+
slider: "input",
|
|
1081
|
+
switch: "input",
|
|
1082
|
+
spinner: "div",
|
|
1083
|
+
badge: "span",
|
|
1084
|
+
avatar: "img",
|
|
1085
|
+
progressbar: "div",
|
|
1086
|
+
video: "video",
|
|
1087
|
+
audio: "audio"
|
|
1088
|
+
};
|
|
1089
|
+
const tag = tagMap[normalizedType] || "div";
|
|
1090
|
+
const el = document.createElement(tag);
|
|
1091
|
+
el.dataset.hypenType = normalizedType;
|
|
1092
|
+
if (normalizedType === "column") {
|
|
1093
|
+
el.style.display = "flex";
|
|
1094
|
+
el.style.flexDirection = "column";
|
|
1095
|
+
} else if (normalizedType === "row") {
|
|
1096
|
+
el.style.display = "flex";
|
|
1097
|
+
el.style.flexDirection = "row";
|
|
1098
|
+
} else if (normalizedType === "center") {
|
|
1099
|
+
el.style.display = "flex";
|
|
1100
|
+
el.style.alignItems = "center";
|
|
1101
|
+
el.style.justifyContent = "center";
|
|
1102
|
+
} else if (normalizedType === "text") {
|
|
1103
|
+
if (props["0"]) {
|
|
1104
|
+
el.textContent = String(props["0"]);
|
|
1105
|
+
}
|
|
1106
|
+
} else if (normalizedType === "button") {
|
|
1107
|
+
el.style.cursor = "pointer";
|
|
1108
|
+
} else if (normalizedType === "checkbox" || normalizedType === "switch") {
|
|
1109
|
+
el.type = "checkbox";
|
|
1110
|
+
} else if (normalizedType === "slider") {
|
|
1111
|
+
el.type = "range";
|
|
1112
|
+
}
|
|
1113
|
+
return el;
|
|
1114
|
+
}
|
|
1115
|
+
function applyProp(el, name, value) {
|
|
1116
|
+
if (name === "0" || name === "text") {
|
|
1117
|
+
el.textContent = String(value);
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
const styleProps = {
|
|
1121
|
+
padding: "padding",
|
|
1122
|
+
margin: "margin",
|
|
1123
|
+
backgroundColor: "backgroundColor",
|
|
1124
|
+
background: "background",
|
|
1125
|
+
color: "color",
|
|
1126
|
+
fontSize: "fontSize",
|
|
1127
|
+
fontWeight: "fontWeight",
|
|
1128
|
+
width: "width",
|
|
1129
|
+
height: "height",
|
|
1130
|
+
minWidth: "minWidth",
|
|
1131
|
+
minHeight: "minHeight",
|
|
1132
|
+
maxWidth: "maxWidth",
|
|
1133
|
+
maxHeight: "maxHeight",
|
|
1134
|
+
borderRadius: "borderRadius",
|
|
1135
|
+
border: "border",
|
|
1136
|
+
gap: "gap",
|
|
1137
|
+
flex: "flex",
|
|
1138
|
+
alignItems: "alignItems",
|
|
1139
|
+
justifyContent: "justifyContent",
|
|
1140
|
+
opacity: "opacity",
|
|
1141
|
+
overflow: "overflow"
|
|
1142
|
+
};
|
|
1143
|
+
if (styleProps[name]) {
|
|
1144
|
+
const cssValue = typeof value === "number" ? `${value}px` : String(value);
|
|
1145
|
+
el.style[styleProps[name]] = cssValue;
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
if (name === "onClick" || name === "onclick") {
|
|
1149
|
+
el.onclick = () => {
|
|
1150
|
+
const engine = el.__hypenEngine;
|
|
1151
|
+
if (engine && typeof value === "string" && value.startsWith("@actions.")) {
|
|
1152
|
+
const action = value.replace("@actions.", "");
|
|
1153
|
+
engine.dispatchAction(action);
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
el.setAttribute(name, String(value));
|
|
1159
|
+
}
|
|
1160
|
+
function disconnectHypenApp(element) {
|
|
1161
|
+
const instance = activeInstances.get(element);
|
|
1162
|
+
if (instance) {
|
|
1163
|
+
instance.engine.disconnect();
|
|
1164
|
+
activeInstances.delete(element);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
var activeInstances, hypenAppHandler;
|
|
1168
|
+
var init_hypenapp = __esm(() => {
|
|
1169
|
+
activeInstances = new WeakMap;
|
|
1170
|
+
hypenAppHandler = {
|
|
1171
|
+
create() {
|
|
1172
|
+
const el = document.createElement("div");
|
|
1173
|
+
el.dataset.hypenType = "hypenapp";
|
|
1174
|
+
el.style.display = "contents";
|
|
1175
|
+
return el;
|
|
1176
|
+
},
|
|
1177
|
+
applyProps(element, props) {
|
|
1178
|
+
const url = props["0"] || props.url;
|
|
1179
|
+
if (!url || typeof url !== "string") {
|
|
1180
|
+
console.error("[HypenApp] URL is required");
|
|
1181
|
+
element.innerHTML = '<div style="color: red;">HypenApp: URL required</div>';
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
const existing = activeInstances.get(element);
|
|
1185
|
+
if (existing) {
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
const engine = new RemoteEngine(url, {
|
|
1189
|
+
autoReconnect: props.autoReconnect ?? true,
|
|
1190
|
+
reconnectInterval: props.reconnectInterval ?? 3000,
|
|
1191
|
+
maxReconnectAttempts: props.maxReconnectAttempts ?? 10
|
|
1192
|
+
});
|
|
1193
|
+
const nodes = new Map;
|
|
1194
|
+
let rootId = null;
|
|
1195
|
+
activeInstances.set(element, { engine, nodes });
|
|
1196
|
+
engine.onPatches((patches) => {
|
|
1197
|
+
applyPatches(element, nodes, patches, engine, (id) => {
|
|
1198
|
+
if (!rootId)
|
|
1199
|
+
rootId = id;
|
|
1200
|
+
});
|
|
1201
|
+
});
|
|
1202
|
+
element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
|
|
1203
|
+
engine.connect().then(() => {
|
|
1204
|
+
element.innerHTML = "";
|
|
1205
|
+
console.log(`[HypenApp] Connected to ${url}`);
|
|
1206
|
+
}).catch((error) => {
|
|
1207
|
+
element.innerHTML = `<div style="color: red;">HypenApp: Connection failed - ${error.message}</div>`;
|
|
1208
|
+
console.error("[HypenApp] Connection failed:", error);
|
|
1209
|
+
});
|
|
1210
|
+
engine.onDisconnect(() => {
|
|
1211
|
+
console.log("[HypenApp] Disconnected");
|
|
1212
|
+
});
|
|
1213
|
+
engine.onError((error) => {
|
|
1214
|
+
console.error("[HypenApp] Error:", error);
|
|
1215
|
+
});
|
|
1216
|
+
const observer = new MutationObserver((mutations) => {
|
|
1217
|
+
for (const mutation of mutations) {
|
|
1218
|
+
for (const removedNode of mutation.removedNodes) {
|
|
1219
|
+
if (removedNode === element || removedNode.contains?.(element)) {
|
|
1220
|
+
engine.disconnect();
|
|
1221
|
+
activeInstances.delete(element);
|
|
1222
|
+
observer.disconnect();
|
|
1223
|
+
console.log("[HypenApp] Cleaned up");
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
});
|
|
1229
|
+
if (element.parentNode) {
|
|
1230
|
+
observer.observe(element.parentNode, { childList: true, subtree: true });
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
});
|
|
1235
|
+
|
|
976
1236
|
// src/dom/applicators/padding.ts
|
|
977
1237
|
var exports_padding = {};
|
|
978
1238
|
__export(exports_padding, {
|
|
@@ -1116,43 +1376,108 @@ var exports_size = {};
|
|
|
1116
1376
|
__export(exports_size, {
|
|
1117
1377
|
sizeHandlers: () => sizeHandlers
|
|
1118
1378
|
});
|
|
1379
|
+
function parseSizeValue(value) {
|
|
1380
|
+
if (value === null || value === undefined)
|
|
1381
|
+
return null;
|
|
1382
|
+
if (typeof value === "number") {
|
|
1383
|
+
return `${value}px`;
|
|
1384
|
+
}
|
|
1385
|
+
const str = String(value).trim().toLowerCase();
|
|
1386
|
+
switch (str) {
|
|
1387
|
+
case "fill":
|
|
1388
|
+
case "match_parent":
|
|
1389
|
+
return "100%";
|
|
1390
|
+
case "wrap":
|
|
1391
|
+
case "wrap_content":
|
|
1392
|
+
case "auto":
|
|
1393
|
+
return "auto";
|
|
1394
|
+
case "infinity":
|
|
1395
|
+
case "inf":
|
|
1396
|
+
case "max":
|
|
1397
|
+
return "100%";
|
|
1398
|
+
}
|
|
1399
|
+
const match = str.match(/^(-?[\d.]+)\s*(px|dp|pt|%|vw|vh|vmin|vmax|em|rem)?$/);
|
|
1400
|
+
if (!match) {
|
|
1401
|
+
return str;
|
|
1402
|
+
}
|
|
1403
|
+
const num = parseFloat(match[1]);
|
|
1404
|
+
const unit = match[2] || "px";
|
|
1405
|
+
switch (unit) {
|
|
1406
|
+
case "px":
|
|
1407
|
+
return `${num}px`;
|
|
1408
|
+
case "dp":
|
|
1409
|
+
case "pt":
|
|
1410
|
+
return `${num}px`;
|
|
1411
|
+
case "%":
|
|
1412
|
+
return `${num}%`;
|
|
1413
|
+
case "vw":
|
|
1414
|
+
return `${num}vw`;
|
|
1415
|
+
case "vh":
|
|
1416
|
+
return `${num}vh`;
|
|
1417
|
+
case "vmin":
|
|
1418
|
+
return `${num}vmin`;
|
|
1419
|
+
case "vmax":
|
|
1420
|
+
return `${num}vmax`;
|
|
1421
|
+
case "em":
|
|
1422
|
+
return `${num}em`;
|
|
1423
|
+
case "rem":
|
|
1424
|
+
return `${num}rem`;
|
|
1425
|
+
default:
|
|
1426
|
+
return `${num}px`;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1119
1429
|
var sizeHandlers;
|
|
1120
1430
|
var init_size = __esm(() => {
|
|
1121
1431
|
sizeHandlers = {
|
|
1122
1432
|
width: (el, value) => {
|
|
1123
|
-
|
|
1433
|
+
const size = parseSizeValue(value);
|
|
1434
|
+
if (size)
|
|
1435
|
+
el.style.width = size;
|
|
1124
1436
|
},
|
|
1125
1437
|
height: (el, value) => {
|
|
1126
|
-
|
|
1438
|
+
const size = parseSizeValue(value);
|
|
1439
|
+
if (size)
|
|
1440
|
+
el.style.height = size;
|
|
1127
1441
|
},
|
|
1128
1442
|
minWidth: (el, value) => {
|
|
1129
|
-
|
|
1443
|
+
const size = parseSizeValue(value);
|
|
1444
|
+
if (size)
|
|
1445
|
+
el.style.minWidth = size;
|
|
1130
1446
|
},
|
|
1131
1447
|
minHeight: (el, value) => {
|
|
1132
|
-
|
|
1448
|
+
const size = parseSizeValue(value);
|
|
1449
|
+
if (size)
|
|
1450
|
+
el.style.minHeight = size;
|
|
1133
1451
|
},
|
|
1134
1452
|
maxWidth: (el, value) => {
|
|
1135
|
-
|
|
1453
|
+
const size = parseSizeValue(value);
|
|
1454
|
+
if (size)
|
|
1455
|
+
el.style.maxWidth = size;
|
|
1136
1456
|
},
|
|
1137
1457
|
maxHeight: (el, value) => {
|
|
1138
|
-
|
|
1458
|
+
const size = parseSizeValue(value);
|
|
1459
|
+
if (size)
|
|
1460
|
+
el.style.maxHeight = size;
|
|
1139
1461
|
},
|
|
1140
1462
|
size: (el, value) => {
|
|
1141
|
-
if (typeof value === "
|
|
1142
|
-
el.style.width = `${value}px`;
|
|
1143
|
-
el.style.height = `${value}px`;
|
|
1144
|
-
} else if (typeof value === "object" && value !== null) {
|
|
1463
|
+
if (typeof value === "object" && value !== null) {
|
|
1145
1464
|
const obj = value;
|
|
1146
1465
|
if (obj.width !== undefined) {
|
|
1147
|
-
|
|
1466
|
+
const w = parseSizeValue(obj.width);
|
|
1467
|
+
if (w)
|
|
1468
|
+
el.style.width = w;
|
|
1148
1469
|
}
|
|
1149
1470
|
if (obj.height !== undefined) {
|
|
1150
|
-
|
|
1471
|
+
const h = parseSizeValue(obj.height);
|
|
1472
|
+
if (h)
|
|
1473
|
+
el.style.height = h;
|
|
1151
1474
|
}
|
|
1152
1475
|
} else {
|
|
1153
|
-
const size =
|
|
1154
|
-
|
|
1155
|
-
|
|
1476
|
+
const size = parseSizeValue(value);
|
|
1477
|
+
if (size) {
|
|
1478
|
+
el.style.width = size;
|
|
1479
|
+
el.style.height = size;
|
|
1480
|
+
}
|
|
1156
1481
|
}
|
|
1157
1482
|
},
|
|
1158
1483
|
fillMaxWidth: (el, value) => {
|
|
@@ -1180,10 +1505,64 @@ var init_size = __esm(() => {
|
|
|
1180
1505
|
// src/dom/applicators/font.ts
|
|
1181
1506
|
var exports_font = {};
|
|
1182
1507
|
__export(exports_font, {
|
|
1183
|
-
fontHandlers: () => fontHandlers
|
|
1508
|
+
fontHandlers: () => fontHandlers,
|
|
1509
|
+
GoogleFonts: () => GoogleFonts
|
|
1184
1510
|
});
|
|
1185
|
-
|
|
1511
|
+
function isSystemFont(fontName) {
|
|
1512
|
+
const normalized = fontName.toLowerCase().trim();
|
|
1513
|
+
return systemFontKeywords.has(normalized) || normalized.startsWith("-") || normalized.startsWith("ui-");
|
|
1514
|
+
}
|
|
1515
|
+
function loadGoogleFont(fontName) {
|
|
1516
|
+
const normalized = fontName.trim();
|
|
1517
|
+
if (loadedGoogleFonts.has(normalized) || isSystemFont(normalized)) {
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
loadedGoogleFonts.add(normalized);
|
|
1521
|
+
const link = document.createElement("link");
|
|
1522
|
+
link.rel = "stylesheet";
|
|
1523
|
+
link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(normalized)}:wght@100;200;300;400;500;600;700;800;900&display=swap`;
|
|
1524
|
+
document.head.appendChild(link);
|
|
1525
|
+
}
|
|
1526
|
+
function processFontFamily(value) {
|
|
1527
|
+
const fonts = value.split(",").map((f) => f.trim().replace(/["']/g, ""));
|
|
1528
|
+
for (const font of fonts) {
|
|
1529
|
+
if (!isSystemFont(font)) {
|
|
1530
|
+
loadGoogleFont(font);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
return fonts.map((f) => {
|
|
1534
|
+
if (f.includes(" ") && !f.startsWith('"') && !f.startsWith("'")) {
|
|
1535
|
+
return `"${f}"`;
|
|
1536
|
+
}
|
|
1537
|
+
return f;
|
|
1538
|
+
}).join(", ");
|
|
1539
|
+
}
|
|
1540
|
+
var loadedGoogleFonts, systemFontKeywords, fontHandlers, GoogleFonts;
|
|
1186
1541
|
var init_font = __esm(() => {
|
|
1542
|
+
loadedGoogleFonts = new Set;
|
|
1543
|
+
systemFontKeywords = new Set([
|
|
1544
|
+
"default",
|
|
1545
|
+
"system",
|
|
1546
|
+
"system-ui",
|
|
1547
|
+
"inherit",
|
|
1548
|
+
"initial",
|
|
1549
|
+
"unset",
|
|
1550
|
+
"serif",
|
|
1551
|
+
"sans-serif",
|
|
1552
|
+
"monospace",
|
|
1553
|
+
"cursive",
|
|
1554
|
+
"fantasy",
|
|
1555
|
+
"-apple-system",
|
|
1556
|
+
"BlinkMacSystemFont",
|
|
1557
|
+
"Segoe UI",
|
|
1558
|
+
"Arial",
|
|
1559
|
+
"Helvetica",
|
|
1560
|
+
"Times New Roman",
|
|
1561
|
+
"Georgia",
|
|
1562
|
+
"Courier New",
|
|
1563
|
+
"Verdana",
|
|
1564
|
+
"Tahoma"
|
|
1565
|
+
]);
|
|
1187
1566
|
fontHandlers = {
|
|
1188
1567
|
fontSize: (el, value) => {
|
|
1189
1568
|
el.style.fontSize = typeof value === "number" ? `${value}px` : String(value);
|
|
@@ -1192,15 +1571,49 @@ var init_font = __esm(() => {
|
|
|
1192
1571
|
el.style.fontWeight = String(value);
|
|
1193
1572
|
},
|
|
1194
1573
|
fontFamily: (el, value) => {
|
|
1195
|
-
|
|
1574
|
+
const fontValue = String(value);
|
|
1575
|
+
el.style.fontFamily = processFontFamily(fontValue);
|
|
1196
1576
|
},
|
|
1197
1577
|
textAlign: (el, value) => {
|
|
1198
1578
|
el.style.textAlign = String(value);
|
|
1199
1579
|
},
|
|
1200
1580
|
lineHeight: (el, value) => {
|
|
1201
1581
|
el.style.lineHeight = String(value);
|
|
1582
|
+
},
|
|
1583
|
+
fontStyle: (el, value) => {
|
|
1584
|
+
el.style.fontStyle = String(value);
|
|
1585
|
+
},
|
|
1586
|
+
textTransform: (el, value) => {
|
|
1587
|
+
el.style.textTransform = String(value);
|
|
1202
1588
|
}
|
|
1203
1589
|
};
|
|
1590
|
+
GoogleFonts = {
|
|
1591
|
+
preload: loadGoogleFont,
|
|
1592
|
+
isLoaded: (fontName) => loadedGoogleFonts.has(fontName.trim()),
|
|
1593
|
+
getLoadedFonts: () => Array.from(loadedGoogleFonts),
|
|
1594
|
+
popular: [
|
|
1595
|
+
"Roboto",
|
|
1596
|
+
"Open Sans",
|
|
1597
|
+
"Lato",
|
|
1598
|
+
"Montserrat",
|
|
1599
|
+
"Poppins",
|
|
1600
|
+
"Inter",
|
|
1601
|
+
"Nunito",
|
|
1602
|
+
"Playfair Display",
|
|
1603
|
+
"Merriweather",
|
|
1604
|
+
"Source Code Pro",
|
|
1605
|
+
"Fira Code",
|
|
1606
|
+
"JetBrains Mono",
|
|
1607
|
+
"Raleway",
|
|
1608
|
+
"Ubuntu",
|
|
1609
|
+
"Oswald",
|
|
1610
|
+
"Quicksand",
|
|
1611
|
+
"Work Sans",
|
|
1612
|
+
"Rubik",
|
|
1613
|
+
"Karla",
|
|
1614
|
+
"DM Sans"
|
|
1615
|
+
]
|
|
1616
|
+
};
|
|
1204
1617
|
});
|
|
1205
1618
|
|
|
1206
1619
|
// src/dom/applicators/layout.ts
|
|
@@ -1208,11 +1621,39 @@ var exports_layout = {};
|
|
|
1208
1621
|
__export(exports_layout, {
|
|
1209
1622
|
layoutHandlers: () => layoutHandlers
|
|
1210
1623
|
});
|
|
1624
|
+
function mapAlignmentValue(value) {
|
|
1625
|
+
const v = String(value).toLowerCase();
|
|
1626
|
+
switch (v) {
|
|
1627
|
+
case "top":
|
|
1628
|
+
case "start":
|
|
1629
|
+
case "leading":
|
|
1630
|
+
case "left":
|
|
1631
|
+
return "flex-start";
|
|
1632
|
+
case "bottom":
|
|
1633
|
+
case "end":
|
|
1634
|
+
case "trailing":
|
|
1635
|
+
case "right":
|
|
1636
|
+
return "flex-end";
|
|
1637
|
+
case "center":
|
|
1638
|
+
return "center";
|
|
1639
|
+
case "spacebetween":
|
|
1640
|
+
case "space-between":
|
|
1641
|
+
return "space-between";
|
|
1642
|
+
case "spacearound":
|
|
1643
|
+
case "space-around":
|
|
1644
|
+
return "space-around";
|
|
1645
|
+
case "spaceevenly":
|
|
1646
|
+
case "space-evenly":
|
|
1647
|
+
return "space-evenly";
|
|
1648
|
+
default:
|
|
1649
|
+
return v;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1211
1652
|
var layoutHandlers;
|
|
1212
1653
|
var init_layout = __esm(() => {
|
|
1213
1654
|
layoutHandlers = {
|
|
1214
1655
|
verticalAlignment: (el, value) => {
|
|
1215
|
-
const val = String(value);
|
|
1656
|
+
const val = mapAlignmentValue(String(value));
|
|
1216
1657
|
const flexDirection = getComputedStyle(el).flexDirection;
|
|
1217
1658
|
if (flexDirection === "column" || flexDirection === "column-reverse") {
|
|
1218
1659
|
el.style.justifyContent = val;
|
|
@@ -1221,7 +1662,7 @@ var init_layout = __esm(() => {
|
|
|
1221
1662
|
}
|
|
1222
1663
|
},
|
|
1223
1664
|
horizontalAlignment: (el, value) => {
|
|
1224
|
-
const val = String(value);
|
|
1665
|
+
const val = mapAlignmentValue(String(value));
|
|
1225
1666
|
const flexDirection = getComputedStyle(el).flexDirection;
|
|
1226
1667
|
if (flexDirection === "column" || flexDirection === "column-reverse") {
|
|
1227
1668
|
el.style.alignItems = val;
|
|
@@ -1230,10 +1671,10 @@ var init_layout = __esm(() => {
|
|
|
1230
1671
|
}
|
|
1231
1672
|
},
|
|
1232
1673
|
horizontalAlign: (el, value) => {
|
|
1233
|
-
el.style.justifyContent = String(value);
|
|
1674
|
+
el.style.justifyContent = mapAlignmentValue(String(value));
|
|
1234
1675
|
},
|
|
1235
1676
|
verticalAlign: (el, value) => {
|
|
1236
|
-
el.style.alignItems = String(value);
|
|
1677
|
+
el.style.alignItems = mapAlignmentValue(String(value));
|
|
1237
1678
|
},
|
|
1238
1679
|
gap: (el, value) => {
|
|
1239
1680
|
el.style.gap = typeof value === "number" ? `${value}px` : String(value);
|
|
@@ -1276,11 +1717,105 @@ var init_layout = __esm(() => {
|
|
|
1276
1717
|
};
|
|
1277
1718
|
});
|
|
1278
1719
|
|
|
1720
|
+
// src/dom/element-data.ts
|
|
1721
|
+
import { getElementDisposables } from "@hypen/core";
|
|
1722
|
+
function getHypenData(element) {
|
|
1723
|
+
let data = elementDataMap.get(element);
|
|
1724
|
+
if (!data) {
|
|
1725
|
+
data = {};
|
|
1726
|
+
elementDataMap.set(element, data);
|
|
1727
|
+
}
|
|
1728
|
+
return data;
|
|
1729
|
+
}
|
|
1730
|
+
function hasHypenData(element) {
|
|
1731
|
+
return elementDataMap.has(element);
|
|
1732
|
+
}
|
|
1733
|
+
function clearHypenData(element) {
|
|
1734
|
+
elementDataMap.delete(element);
|
|
1735
|
+
}
|
|
1736
|
+
function getEngine(element) {
|
|
1737
|
+
return getHypenData(element).engine;
|
|
1738
|
+
}
|
|
1739
|
+
function setEngine(element, engine) {
|
|
1740
|
+
getHypenData(element).engine = engine;
|
|
1741
|
+
}
|
|
1742
|
+
function findEngine(element) {
|
|
1743
|
+
let current = element;
|
|
1744
|
+
while (current) {
|
|
1745
|
+
const engine = getEngine(current);
|
|
1746
|
+
if (engine)
|
|
1747
|
+
return engine;
|
|
1748
|
+
current = current.parentElement;
|
|
1749
|
+
}
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
function getRegisteredEvents(element) {
|
|
1753
|
+
const data = getHypenData(element);
|
|
1754
|
+
if (!data.registeredEvents) {
|
|
1755
|
+
data.registeredEvents = new Set;
|
|
1756
|
+
}
|
|
1757
|
+
return data.registeredEvents;
|
|
1758
|
+
}
|
|
1759
|
+
function isEventRegistered(element, eventKey) {
|
|
1760
|
+
return getRegisteredEvents(element).has(eventKey);
|
|
1761
|
+
}
|
|
1762
|
+
function registerEvent(element, eventKey) {
|
|
1763
|
+
getRegisteredEvents(element).add(eventKey);
|
|
1764
|
+
}
|
|
1765
|
+
function unregisterEvent(element, eventKey) {
|
|
1766
|
+
getRegisteredEvents(element).delete(eventKey);
|
|
1767
|
+
}
|
|
1768
|
+
function getKeyTarget(element) {
|
|
1769
|
+
return getHypenData(element).keyTarget;
|
|
1770
|
+
}
|
|
1771
|
+
function setKeyTarget(element, key) {
|
|
1772
|
+
getHypenData(element).keyTarget = key;
|
|
1773
|
+
}
|
|
1774
|
+
function getMeta(element, key) {
|
|
1775
|
+
return getHypenData(element).meta?.[key];
|
|
1776
|
+
}
|
|
1777
|
+
function setMeta(element, key, value) {
|
|
1778
|
+
const data = getHypenData(element);
|
|
1779
|
+
if (!data.meta) {
|
|
1780
|
+
data.meta = {};
|
|
1781
|
+
}
|
|
1782
|
+
data.meta[key] = value;
|
|
1783
|
+
}
|
|
1784
|
+
function disposeHypenElement(element) {
|
|
1785
|
+
try {
|
|
1786
|
+
const disposables = getElementDisposables(element);
|
|
1787
|
+
disposables.dispose();
|
|
1788
|
+
} catch {}
|
|
1789
|
+
clearHypenData(element);
|
|
1790
|
+
}
|
|
1791
|
+
function getLegacyEngine(element) {
|
|
1792
|
+
const engine = getEngine(element);
|
|
1793
|
+
if (engine)
|
|
1794
|
+
return engine;
|
|
1795
|
+
return element[HYPEN_ENGINE_SYMBOL] ?? element.__hypenEngine;
|
|
1796
|
+
}
|
|
1797
|
+
function setLegacyEngine(element, engine) {
|
|
1798
|
+
setEngine(element, engine);
|
|
1799
|
+
element.__hypenEngine = engine;
|
|
1800
|
+
}
|
|
1801
|
+
var elementDataMap, HYPEN_ENGINE_SYMBOL, REGISTERED_EVENTS_SYMBOL, KEY_TARGET_SYMBOL;
|
|
1802
|
+
var init_element_data = __esm(() => {
|
|
1803
|
+
elementDataMap = new WeakMap;
|
|
1804
|
+
HYPEN_ENGINE_SYMBOL = Symbol.for("hypen.engine");
|
|
1805
|
+
REGISTERED_EVENTS_SYMBOL = Symbol.for("hypen.registeredEvents");
|
|
1806
|
+
KEY_TARGET_SYMBOL = Symbol.for("hypen.keyTarget");
|
|
1807
|
+
});
|
|
1808
|
+
|
|
1279
1809
|
// src/dom/applicators/events.ts
|
|
1280
1810
|
var exports_events = {};
|
|
1281
1811
|
__export(exports_events, {
|
|
1282
1812
|
eventHandlers: () => eventHandlers
|
|
1283
1813
|
});
|
|
1814
|
+
import {
|
|
1815
|
+
getElementDisposables as getElementDisposables2,
|
|
1816
|
+
disposableListener,
|
|
1817
|
+
disposableTimeout
|
|
1818
|
+
} from "@hypen/core";
|
|
1284
1819
|
function toPlainObject(value) {
|
|
1285
1820
|
if (value instanceof Map) {
|
|
1286
1821
|
const obj = {};
|
|
@@ -1326,7 +1861,13 @@ function extractActionDetails(value) {
|
|
|
1326
1861
|
}
|
|
1327
1862
|
for (const [key, val] of Object.entries(plain)) {
|
|
1328
1863
|
if (key !== "0") {
|
|
1329
|
-
|
|
1864
|
+
if (/^\d+$/.test(key) && val && typeof val === "object" && !Array.isArray(val)) {
|
|
1865
|
+
for (const [innerKey, innerVal] of Object.entries(val)) {
|
|
1866
|
+
payload[innerKey] = innerVal;
|
|
1867
|
+
}
|
|
1868
|
+
} else {
|
|
1869
|
+
payload[key] = val;
|
|
1870
|
+
}
|
|
1330
1871
|
}
|
|
1331
1872
|
}
|
|
1332
1873
|
}
|
|
@@ -1364,420 +1905,203 @@ function extractEventData(event, element) {
|
|
|
1364
1905
|
}
|
|
1365
1906
|
return data;
|
|
1366
1907
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
console.
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : extractEventData(event, element);
|
|
1384
|
-
console.log(`[EventApplicator] onClick payload:`, payload);
|
|
1385
|
-
const engine = element.__hypenEngine;
|
|
1386
|
-
if (engine) {
|
|
1387
|
-
engine.dispatchAction(actionName, payload);
|
|
1388
|
-
} else {
|
|
1389
|
-
console.warn(`[EventApplicator] No engine attached to element for onClick`);
|
|
1390
|
-
}
|
|
1391
|
-
};
|
|
1392
|
-
element.__hypenClickListener = listener;
|
|
1393
|
-
element.addEventListener("click", listener);
|
|
1394
|
-
console.log(`[EventApplicator] onClick handler attached for action: ${actionName}`);
|
|
1395
|
-
},
|
|
1396
|
-
onPress: (element, value) => {
|
|
1397
|
-
eventHandlers.onClick(element, value);
|
|
1398
|
-
},
|
|
1399
|
-
onChange: (element, value) => {
|
|
1400
|
-
const { actionName } = extractActionDetails(value);
|
|
1401
|
-
if (!actionName) {
|
|
1402
|
-
console.warn(`[EventApplicator] onChange value must be an action reference starting with @, got:`, value);
|
|
1403
|
-
return;
|
|
1404
|
-
}
|
|
1405
|
-
const existingListener = element.__hypenChangeListener;
|
|
1406
|
-
if (existingListener) {
|
|
1407
|
-
element.removeEventListener("change", existingListener);
|
|
1408
|
-
}
|
|
1409
|
-
const listener = (event) => {
|
|
1410
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onChange fired, dispatching action: ${actionName}`);
|
|
1411
|
-
const payload = extractEventData(event, element);
|
|
1412
|
-
const engine = element.__hypenEngine;
|
|
1413
|
-
if (engine) {
|
|
1414
|
-
engine.dispatchAction(actionName, payload);
|
|
1415
|
-
} else {
|
|
1416
|
-
console.warn(`[EventApplicator] No engine attached to element for onChange`);
|
|
1417
|
-
}
|
|
1418
|
-
};
|
|
1419
|
-
element.__hypenChangeListener = listener;
|
|
1420
|
-
element.addEventListener("change", listener);
|
|
1421
|
-
console.log(`[EventApplicator] onChange handler attached for action: ${actionName}`);
|
|
1422
|
-
},
|
|
1423
|
-
onSubmit: (element, value) => {
|
|
1424
|
-
const { actionName } = extractActionDetails(value);
|
|
1425
|
-
if (!actionName) {
|
|
1426
|
-
console.warn(`[EventApplicator] onSubmit value must be an action reference starting with @, got:`, value);
|
|
1908
|
+
function createEventHandler(eventType, options = {}) {
|
|
1909
|
+
return (element, value) => {
|
|
1910
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1911
|
+
if (!actionName) {
|
|
1912
|
+
console.warn(`[EventApplicator] ${eventType} requires an action reference starting with @, got:`, value);
|
|
1913
|
+
return;
|
|
1914
|
+
}
|
|
1915
|
+
const disposables = getElementDisposables2(element);
|
|
1916
|
+
const eventKey = `${eventType}:${actionName}`;
|
|
1917
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
1918
|
+
return;
|
|
1919
|
+
}
|
|
1920
|
+
registerEvent(element, eventKey);
|
|
1921
|
+
let throttleTimer = null;
|
|
1922
|
+
const listener = (event) => {
|
|
1923
|
+
if (options.throttleMs && throttleTimer) {
|
|
1427
1924
|
return;
|
|
1428
1925
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1926
|
+
if (options.throttleMs) {
|
|
1927
|
+
throttleTimer = disposableTimeout(() => {
|
|
1928
|
+
throttleTimer = null;
|
|
1929
|
+
}, options.throttleMs);
|
|
1432
1930
|
}
|
|
1433
|
-
|
|
1434
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onSubmit fired, dispatching action: ${actionName}`);
|
|
1931
|
+
if (options.preventDefault) {
|
|
1435
1932
|
event.preventDefault();
|
|
1436
|
-
const payload = extractEventData(event, element);
|
|
1437
|
-
const engine = element.__hypenEngine;
|
|
1438
|
-
if (engine) {
|
|
1439
|
-
engine.dispatchAction(actionName, payload);
|
|
1440
|
-
} else {
|
|
1441
|
-
console.warn(`[EventApplicator] No engine attached to element for onSubmit`);
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
element.__hypenSubmitListener = listener;
|
|
1445
|
-
element.addEventListener("submit", listener);
|
|
1446
|
-
console.log(`[EventApplicator] onSubmit handler attached for action: ${actionName}`);
|
|
1447
|
-
},
|
|
1448
|
-
onInput: (element, value) => {
|
|
1449
|
-
console.log(`[EventApplicator] onInput called with value:`, value);
|
|
1450
|
-
const { actionName } = extractActionDetails(value);
|
|
1451
|
-
if (!actionName) {
|
|
1452
|
-
console.warn(`[EventApplicator] onInput value must be an action reference starting with @, got:`, value);
|
|
1453
|
-
return;
|
|
1454
|
-
}
|
|
1455
|
-
const existingListener = element.__hypenInputListener;
|
|
1456
|
-
if (existingListener) {
|
|
1457
|
-
element.removeEventListener("input", existingListener);
|
|
1458
|
-
}
|
|
1459
|
-
const listener = (event) => {
|
|
1460
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onInput fired, dispatching action: ${actionName}`);
|
|
1461
|
-
const target = event.target;
|
|
1462
|
-
const payload = {
|
|
1463
|
-
type: event.type,
|
|
1464
|
-
timestamp: Date.now(),
|
|
1465
|
-
value: target.value,
|
|
1466
|
-
input: target.value
|
|
1467
|
-
};
|
|
1468
|
-
console.log(`[EventApplicator] onInput payload:`, payload);
|
|
1469
|
-
const engine = element.__hypenEngine;
|
|
1470
|
-
if (engine) {
|
|
1471
|
-
engine.dispatchAction(actionName, payload);
|
|
1472
|
-
} else {
|
|
1473
|
-
console.warn(`[EventApplicator] No engine attached to element for onInput`);
|
|
1474
|
-
}
|
|
1475
|
-
};
|
|
1476
|
-
element.__hypenInputListener = listener;
|
|
1477
|
-
element.addEventListener("input", listener);
|
|
1478
|
-
console.log(`[EventApplicator] onInput handler attached for action: ${actionName}`);
|
|
1479
|
-
},
|
|
1480
|
-
onKey: (element, value) => {
|
|
1481
|
-
console.log(`[EventApplicator] onKey called with value:`, value);
|
|
1482
|
-
const { actionName } = extractActionDetails(value);
|
|
1483
|
-
if (actionName) {
|
|
1484
|
-
const existingListener = element.__hypenKeyListener;
|
|
1485
|
-
if (existingListener) {
|
|
1486
|
-
element.removeEventListener("keydown", existingListener);
|
|
1487
|
-
}
|
|
1488
|
-
const listener = (event) => {
|
|
1489
|
-
if (event.key === "Enter") {
|
|
1490
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (Enter), dispatching action: ${actionName}`);
|
|
1491
|
-
event.preventDefault();
|
|
1492
|
-
const target = event.target;
|
|
1493
|
-
const payload = {
|
|
1494
|
-
type: event.type,
|
|
1495
|
-
timestamp: Date.now(),
|
|
1496
|
-
key: event.key,
|
|
1497
|
-
code: event.code,
|
|
1498
|
-
value: target.value,
|
|
1499
|
-
input: target.value,
|
|
1500
|
-
ctrlKey: event.ctrlKey,
|
|
1501
|
-
shiftKey: event.shiftKey,
|
|
1502
|
-
altKey: event.altKey,
|
|
1503
|
-
metaKey: event.metaKey
|
|
1504
|
-
};
|
|
1505
|
-
const engine = element.__hypenEngine;
|
|
1506
|
-
if (engine) {
|
|
1507
|
-
engine.dispatchAction(actionName, payload);
|
|
1508
|
-
} else {
|
|
1509
|
-
console.warn(`[EventApplicator] No engine attached to element for onKey`);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
};
|
|
1513
|
-
element.__hypenKeyListener = listener;
|
|
1514
|
-
element.addEventListener("keydown", listener);
|
|
1515
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} (triggers on Enter)`);
|
|
1516
|
-
} else {
|
|
1517
|
-
console.warn(`[EventApplicator] onKey value must be an action reference starting with @, got: ${value}`);
|
|
1518
|
-
}
|
|
1519
|
-
},
|
|
1520
|
-
"onKey.key": (element, keyValue) => {
|
|
1521
|
-
console.log(`[EventApplicator] onKey.key called with value:`, keyValue);
|
|
1522
|
-
element.__hypenKeyTarget = keyValue;
|
|
1523
|
-
},
|
|
1524
|
-
"onKey.action": (element, value) => {
|
|
1525
|
-
console.log(`[EventApplicator] onKey.action called with value:`, value);
|
|
1526
|
-
const { actionName } = extractActionDetails(value);
|
|
1527
|
-
if (actionName) {
|
|
1528
|
-
const targetKey = element.__hypenKeyTarget || "Enter";
|
|
1529
|
-
const existingListener = element.__hypenKeyListener;
|
|
1530
|
-
if (existingListener) {
|
|
1531
|
-
element.removeEventListener("keydown", existingListener);
|
|
1532
|
-
}
|
|
1533
|
-
const listener = (event) => {
|
|
1534
|
-
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
1535
|
-
if (event.key === keyToMatch) {
|
|
1536
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onKey fired (${keyToMatch}), dispatching action: ${actionName}`);
|
|
1537
|
-
event.preventDefault();
|
|
1538
|
-
const target = event.target;
|
|
1539
|
-
const payload = {
|
|
1540
|
-
type: event.type,
|
|
1541
|
-
timestamp: Date.now(),
|
|
1542
|
-
key: event.key,
|
|
1543
|
-
code: event.code,
|
|
1544
|
-
value: target.value,
|
|
1545
|
-
input: target.value,
|
|
1546
|
-
ctrlKey: event.ctrlKey,
|
|
1547
|
-
shiftKey: event.shiftKey,
|
|
1548
|
-
altKey: event.altKey,
|
|
1549
|
-
metaKey: event.metaKey
|
|
1550
|
-
};
|
|
1551
|
-
const engine = element.__hypenEngine;
|
|
1552
|
-
if (engine) {
|
|
1553
|
-
engine.dispatchAction(actionName, payload);
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
};
|
|
1557
|
-
element.__hypenKeyListener = listener;
|
|
1558
|
-
element.addEventListener("keydown", listener);
|
|
1559
|
-
console.log(`[EventApplicator] onKey handler attached for action: ${actionName} on key: ${targetKey}`);
|
|
1560
|
-
}
|
|
1561
|
-
},
|
|
1562
|
-
onScroll: (element, value) => {
|
|
1563
|
-
console.log(`[EventApplicator] onScroll called with value:`, value);
|
|
1564
|
-
const { actionName } = extractActionDetails(value);
|
|
1565
|
-
if (actionName) {
|
|
1566
|
-
const existingListener = element.__hypenScrollListener;
|
|
1567
|
-
if (existingListener) {
|
|
1568
|
-
element.removeEventListener("scroll", existingListener);
|
|
1569
|
-
}
|
|
1570
|
-
let throttleTimer = null;
|
|
1571
|
-
const listener = (event) => {
|
|
1572
|
-
if (throttleTimer)
|
|
1573
|
-
return;
|
|
1574
|
-
throttleTimer = setTimeout(() => {
|
|
1575
|
-
throttleTimer = null;
|
|
1576
|
-
}, 100);
|
|
1577
|
-
const target = event.target;
|
|
1578
|
-
const scrollTop = target.scrollTop;
|
|
1579
|
-
const scrollHeight = target.scrollHeight;
|
|
1580
|
-
const clientHeight = target.clientHeight;
|
|
1581
|
-
const scrollPercentage = scrollTop / (scrollHeight - clientHeight) * 100;
|
|
1582
|
-
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
1583
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onScroll fired, scrollTop: ${scrollTop}, nearBottom: ${nearBottom}`);
|
|
1584
|
-
const payload = {
|
|
1585
|
-
type: "scroll",
|
|
1586
|
-
timestamp: Date.now(),
|
|
1587
|
-
scrollTop,
|
|
1588
|
-
scrollLeft: target.scrollLeft,
|
|
1589
|
-
scrollHeight,
|
|
1590
|
-
scrollWidth: target.scrollWidth,
|
|
1591
|
-
clientHeight,
|
|
1592
|
-
clientWidth: target.clientWidth,
|
|
1593
|
-
scrollPercentage: Math.round(scrollPercentage),
|
|
1594
|
-
nearBottom,
|
|
1595
|
-
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
1596
|
-
atTop: scrollTop === 0
|
|
1597
|
-
};
|
|
1598
|
-
const engine = element.__hypenEngine;
|
|
1599
|
-
if (engine) {
|
|
1600
|
-
engine.dispatchAction(actionName, payload);
|
|
1601
|
-
} else {
|
|
1602
|
-
console.warn(`[EventApplicator] No engine attached to element for onScroll`);
|
|
1603
|
-
}
|
|
1604
|
-
};
|
|
1605
|
-
element.__hypenScrollListener = listener;
|
|
1606
|
-
element.addEventListener("scroll", listener, { passive: true });
|
|
1607
|
-
console.log(`[EventApplicator] onScroll handler attached for action: ${actionName}`);
|
|
1608
|
-
} else {
|
|
1609
|
-
console.warn(`[EventApplicator] onScroll value must be an action reference starting with @, got: ${value}`);
|
|
1610
1933
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
if (!actionName) {
|
|
1616
|
-
console.warn(`[EventApplicator] onLongClick value must be an action reference, got:`, value);
|
|
1617
|
-
return;
|
|
1934
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : options.extractPayload ? options.extractPayload(event, element) : extractEventData(event, element);
|
|
1935
|
+
const engine = getEngine(element);
|
|
1936
|
+
if (engine) {
|
|
1937
|
+
engine.dispatchAction(actionName, payload);
|
|
1618
1938
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
}
|
|
1628
|
-
let longClickTimer = null;
|
|
1629
|
-
const LONG_CLICK_THRESHOLD = 500;
|
|
1630
|
-
const downListener = (event) => {
|
|
1631
|
-
longClickTimer = setTimeout(() => {
|
|
1632
|
-
console.log(`\uD83D\uDD25 [EventApplicator] onLongClick fired, dispatching action: ${actionName}`);
|
|
1633
|
-
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
1634
|
-
type: "longclick",
|
|
1635
|
-
timestamp: Date.now(),
|
|
1636
|
-
clientX: event.clientX,
|
|
1637
|
-
clientY: event.clientY
|
|
1638
|
-
};
|
|
1639
|
-
const engine = element.__hypenEngine;
|
|
1640
|
-
if (engine) {
|
|
1641
|
-
engine.dispatchAction(actionName, payload);
|
|
1642
|
-
} else {
|
|
1643
|
-
console.warn(`[EventApplicator] No engine attached to element for onLongClick`);
|
|
1644
|
-
}
|
|
1645
|
-
longClickTimer = null;
|
|
1646
|
-
}, LONG_CLICK_THRESHOLD);
|
|
1647
|
-
};
|
|
1648
|
-
const upListener = () => {
|
|
1649
|
-
if (longClickTimer) {
|
|
1650
|
-
clearTimeout(longClickTimer);
|
|
1651
|
-
longClickTimer = null;
|
|
1652
|
-
}
|
|
1653
|
-
};
|
|
1654
|
-
element.__hypenLongClickDownListener = downListener;
|
|
1655
|
-
element.__hypenLongClickUpListener = upListener;
|
|
1656
|
-
element.addEventListener("pointerdown", downListener);
|
|
1657
|
-
element.addEventListener("pointerup", upListener);
|
|
1658
|
-
element.addEventListener("pointerleave", upListener);
|
|
1659
|
-
console.log(`[EventApplicator] onLongClick handler attached for action: ${actionName}`);
|
|
1660
|
-
},
|
|
1661
|
-
onFocus: (element, value) => {
|
|
1662
|
-
console.log(`[EventApplicator] onFocus called with value:`, value);
|
|
1663
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1664
|
-
if (!actionName) {
|
|
1665
|
-
console.warn(`[EventApplicator] onFocus value must be an action reference, got:`, value);
|
|
1666
|
-
return;
|
|
1667
|
-
}
|
|
1668
|
-
const existingListener = element.__hypenFocusListener;
|
|
1669
|
-
if (existingListener) {
|
|
1670
|
-
element.removeEventListener("focus", existingListener);
|
|
1939
|
+
};
|
|
1940
|
+
disposables.add(disposableListener(element, eventType, listener, {
|
|
1941
|
+
passive: options.passive
|
|
1942
|
+
}));
|
|
1943
|
+
disposables.addCallback(() => {
|
|
1944
|
+
unregisterEvent(element, eventKey);
|
|
1945
|
+
if (throttleTimer) {
|
|
1946
|
+
throttleTimer.dispose();
|
|
1671
1947
|
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1694
|
-
if (!actionName) {
|
|
1695
|
-
console.warn(`[EventApplicator] onBlur value must be an action reference, got:`, value);
|
|
1948
|
+
});
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
function createKeyHandler(defaultKey = "Enter") {
|
|
1952
|
+
return (element, value) => {
|
|
1953
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1954
|
+
if (!actionName) {
|
|
1955
|
+
console.warn(`[EventApplicator] onKey requires an action reference starting with @, got:`, value);
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
const disposables = getElementDisposables2(element);
|
|
1959
|
+
const eventKey = `keydown:${actionName}:${defaultKey}`;
|
|
1960
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
registerEvent(element, eventKey);
|
|
1964
|
+
const targetKey = getKeyTarget(element) || defaultKey;
|
|
1965
|
+
const keyToMatch = targetKey.toLowerCase() === "return" ? "Enter" : targetKey;
|
|
1966
|
+
const listener = (event) => {
|
|
1967
|
+
const keyEvent = event;
|
|
1968
|
+
if (keyEvent.key !== keyToMatch) {
|
|
1696
1969
|
return;
|
|
1697
1970
|
}
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
if (engine) {
|
|
1712
|
-
engine.dispatchAction(actionName, payload);
|
|
1713
|
-
} else {
|
|
1714
|
-
console.warn(`[EventApplicator] No engine attached to element for onBlur`);
|
|
1715
|
-
}
|
|
1971
|
+
event.preventDefault();
|
|
1972
|
+
const target = event.target;
|
|
1973
|
+
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
1974
|
+
type: event.type,
|
|
1975
|
+
timestamp: Date.now(),
|
|
1976
|
+
key: keyEvent.key,
|
|
1977
|
+
code: keyEvent.code,
|
|
1978
|
+
value: target.value,
|
|
1979
|
+
input: target.value,
|
|
1980
|
+
ctrlKey: keyEvent.ctrlKey,
|
|
1981
|
+
shiftKey: keyEvent.shiftKey,
|
|
1982
|
+
altKey: keyEvent.altKey,
|
|
1983
|
+
metaKey: keyEvent.metaKey
|
|
1716
1984
|
};
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
},
|
|
1721
|
-
onMouseEnter: (element, value) => {
|
|
1722
|
-
console.log(`[EventApplicator] onMouseEnter called with value:`, value);
|
|
1723
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1724
|
-
if (!actionName) {
|
|
1725
|
-
console.warn(`[EventApplicator] onMouseEnter value must be an action reference, got:`, value);
|
|
1726
|
-
return;
|
|
1985
|
+
const engine = getEngine(element);
|
|
1986
|
+
if (engine) {
|
|
1987
|
+
engine.dispatchAction(actionName, payload);
|
|
1727
1988
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1989
|
+
};
|
|
1990
|
+
disposables.add(disposableListener(element, "keydown", listener));
|
|
1991
|
+
disposables.addCallback(() => {
|
|
1992
|
+
unregisterEvent(element, eventKey);
|
|
1993
|
+
});
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
function createLongClickHandler(thresholdMs = 500) {
|
|
1997
|
+
return (element, value) => {
|
|
1998
|
+
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1999
|
+
if (!actionName) {
|
|
2000
|
+
console.warn(`[EventApplicator] onLongClick requires an action reference starting with @, got:`, value);
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
const disposables = getElementDisposables2(element);
|
|
2004
|
+
const eventKey = `longclick:${actionName}`;
|
|
2005
|
+
if (getRegisteredEvents(element).has(eventKey)) {
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
registerEvent(element, eventKey);
|
|
2009
|
+
let longClickTimer = null;
|
|
2010
|
+
const downListener = (event) => {
|
|
2011
|
+
const pointerEvent = event;
|
|
2012
|
+
longClickTimer = disposableTimeout(() => {
|
|
1734
2013
|
const payload = Object.keys(customPayload).length > 0 ? { ...customPayload } : {
|
|
1735
|
-
type: "
|
|
2014
|
+
type: "longclick",
|
|
1736
2015
|
timestamp: Date.now(),
|
|
1737
|
-
clientX:
|
|
1738
|
-
clientY:
|
|
2016
|
+
clientX: pointerEvent.clientX,
|
|
2017
|
+
clientY: pointerEvent.clientY
|
|
1739
2018
|
};
|
|
1740
|
-
const engine = element
|
|
2019
|
+
const engine = getEngine(element);
|
|
1741
2020
|
if (engine) {
|
|
1742
2021
|
engine.dispatchAction(actionName, payload);
|
|
1743
|
-
} else {
|
|
1744
|
-
console.warn(`[EventApplicator] No engine attached to element for onMouseEnter`);
|
|
1745
2022
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
const { actionName, payload: customPayload } = extractActionDetails(value);
|
|
1754
|
-
if (!actionName) {
|
|
1755
|
-
console.warn(`[EventApplicator] onMouseLeave value must be an action reference, got:`, value);
|
|
1756
|
-
return;
|
|
1757
|
-
}
|
|
1758
|
-
const existingListener = element.__hypenMouseLeaveListener;
|
|
1759
|
-
if (existingListener) {
|
|
1760
|
-
element.removeEventListener("mouseleave", existingListener);
|
|
2023
|
+
longClickTimer = null;
|
|
2024
|
+
}, thresholdMs);
|
|
2025
|
+
};
|
|
2026
|
+
const cancelListener = () => {
|
|
2027
|
+
if (longClickTimer) {
|
|
2028
|
+
longClickTimer.dispose();
|
|
2029
|
+
longClickTimer = null;
|
|
1761
2030
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2031
|
+
};
|
|
2032
|
+
disposables.add(disposableListener(element, "pointerdown", downListener));
|
|
2033
|
+
disposables.add(disposableListener(element, "pointerup", cancelListener));
|
|
2034
|
+
disposables.add(disposableListener(element, "pointerleave", cancelListener));
|
|
2035
|
+
disposables.addCallback(() => {
|
|
2036
|
+
unregisterEvent(element, eventKey);
|
|
2037
|
+
cancelListener();
|
|
2038
|
+
});
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
var inputPayload = (event, element) => {
|
|
2042
|
+
const target = element;
|
|
2043
|
+
return {
|
|
2044
|
+
type: event.type,
|
|
2045
|
+
timestamp: Date.now(),
|
|
2046
|
+
value: target.value,
|
|
2047
|
+
input: target.value
|
|
2048
|
+
};
|
|
2049
|
+
}, scrollPayload = (_event, element) => {
|
|
2050
|
+
const scrollTop = element.scrollTop;
|
|
2051
|
+
const scrollHeight = element.scrollHeight;
|
|
2052
|
+
const clientHeight = element.clientHeight;
|
|
2053
|
+
const scrollPercentage = scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) * 100 : 0;
|
|
2054
|
+
const nearBottom = scrollHeight - scrollTop - clientHeight < 100 || scrollPercentage > 90;
|
|
2055
|
+
return {
|
|
2056
|
+
type: "scroll",
|
|
2057
|
+
timestamp: Date.now(),
|
|
2058
|
+
scrollTop,
|
|
2059
|
+
scrollLeft: element.scrollLeft,
|
|
2060
|
+
scrollHeight,
|
|
2061
|
+
scrollWidth: element.scrollWidth,
|
|
2062
|
+
clientHeight,
|
|
2063
|
+
clientWidth: element.clientWidth,
|
|
2064
|
+
scrollPercentage: Math.round(scrollPercentage),
|
|
2065
|
+
nearBottom,
|
|
2066
|
+
atBottom: scrollHeight - scrollTop === clientHeight,
|
|
2067
|
+
atTop: scrollTop === 0
|
|
2068
|
+
};
|
|
2069
|
+
}, focusPayload = (event, element) => ({
|
|
2070
|
+
type: event.type,
|
|
2071
|
+
timestamp: Date.now(),
|
|
2072
|
+
value: element.value ?? undefined
|
|
2073
|
+
}), mousePayload = (event, _element) => {
|
|
2074
|
+
const mouseEvent = event;
|
|
2075
|
+
return {
|
|
2076
|
+
type: event.type,
|
|
2077
|
+
timestamp: Date.now(),
|
|
2078
|
+
clientX: mouseEvent.clientX,
|
|
2079
|
+
clientY: mouseEvent.clientY
|
|
2080
|
+
};
|
|
2081
|
+
}, eventHandlers;
|
|
2082
|
+
var init_events = __esm(() => {
|
|
2083
|
+
init_element_data();
|
|
2084
|
+
eventHandlers = {
|
|
2085
|
+
onClick: createEventHandler("click"),
|
|
2086
|
+
onPress: createEventHandler("click"),
|
|
2087
|
+
onChange: createEventHandler("change"),
|
|
2088
|
+
onSubmit: createEventHandler("submit", { preventDefault: true }),
|
|
2089
|
+
onInput: createEventHandler("input", { extractPayload: inputPayload }),
|
|
2090
|
+
onKey: createKeyHandler("Enter"),
|
|
2091
|
+
"onKey.key": (element, value) => {
|
|
2092
|
+
setKeyTarget(element, String(value));
|
|
2093
|
+
},
|
|
2094
|
+
"onKey.action": createKeyHandler("Enter"),
|
|
2095
|
+
onScroll: createEventHandler("scroll", {
|
|
2096
|
+
throttleMs: 100,
|
|
2097
|
+
passive: true,
|
|
2098
|
+
extractPayload: scrollPayload
|
|
2099
|
+
}),
|
|
2100
|
+
onLongClick: createLongClickHandler(500),
|
|
2101
|
+
onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
|
|
2102
|
+
onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
|
|
2103
|
+
onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
|
|
2104
|
+
onMouseLeave: createEventHandler("mouseleave", { extractPayload: mousePayload })
|
|
1781
2105
|
};
|
|
1782
2106
|
});
|
|
1783
2107
|
|
|
@@ -1943,7 +2267,43 @@ var effectsHandlers;
|
|
|
1943
2267
|
var init_effects = __esm(() => {
|
|
1944
2268
|
effectsHandlers = {
|
|
1945
2269
|
boxShadow: (el, value) => {
|
|
1946
|
-
|
|
2270
|
+
if (typeof value === "string") {
|
|
2271
|
+
el.style.boxShadow = value;
|
|
2272
|
+
} else if (typeof value === "object" && value !== null) {
|
|
2273
|
+
const obj = value;
|
|
2274
|
+
const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
|
|
2275
|
+
const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
|
|
2276
|
+
const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "0px";
|
|
2277
|
+
const spread = typeof obj.spread === "number" ? `${obj.spread}px` : obj.spread ?? "0px";
|
|
2278
|
+
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
2279
|
+
const inset = obj.inset ? "inset " : "";
|
|
2280
|
+
el.style.boxShadow = `${inset}${x} ${y} ${blur} ${spread} ${color}`;
|
|
2281
|
+
} else if (typeof value === "number") {
|
|
2282
|
+
el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
|
|
2283
|
+
}
|
|
2284
|
+
},
|
|
2285
|
+
shadow: (el, value) => {
|
|
2286
|
+
if (typeof value === "object" && value !== null) {
|
|
2287
|
+
const obj = value;
|
|
2288
|
+
const x = typeof obj.x === "number" ? `${obj.x}px` : obj.x ?? obj.offsetX ?? "0px";
|
|
2289
|
+
const y = typeof obj.y === "number" ? `${obj.y}px` : obj.y ?? obj.offsetY ?? "0px";
|
|
2290
|
+
const blur = typeof obj.blur === "number" ? `${obj.blur}px` : obj.blur ?? obj.radius ?? "4px";
|
|
2291
|
+
const color = obj.color ?? "rgba(0,0,0,0.2)";
|
|
2292
|
+
el.style.boxShadow = `${x} ${y} ${blur} ${color}`;
|
|
2293
|
+
} else if (typeof value === "number") {
|
|
2294
|
+
el.style.boxShadow = `0 ${value}px ${value * 2}px rgba(0,0,0,0.2)`;
|
|
2295
|
+
} else {
|
|
2296
|
+
el.style.boxShadow = String(value);
|
|
2297
|
+
}
|
|
2298
|
+
},
|
|
2299
|
+
elevation: (el, value) => {
|
|
2300
|
+
const level = typeof value === "number" ? value : parseInt(String(value), 10);
|
|
2301
|
+
if (!isNaN(level) && level >= 0) {
|
|
2302
|
+
const y = level * 0.5;
|
|
2303
|
+
const blur = level * 1.5;
|
|
2304
|
+
const opacity = Math.min(0.1 + level * 0.02, 0.4);
|
|
2305
|
+
el.style.boxShadow = `0 ${y}px ${blur}px rgba(0,0,0,${opacity})`;
|
|
2306
|
+
}
|
|
1947
2307
|
},
|
|
1948
2308
|
textShadow: (el, value) => {
|
|
1949
2309
|
el.style.textShadow = String(value);
|
|
@@ -2313,6 +2673,7 @@ class ComponentRegistry {
|
|
|
2313
2673
|
const { paragraphHandler: paragraphHandler2 } = (init_paragraph(), __toCommonJS(exports_paragraph));
|
|
2314
2674
|
const { routerHandler: routerHandler2 } = (init_router(), __toCommonJS(exports_router));
|
|
2315
2675
|
const { routeHandler: routeHandler2 } = (init_route(), __toCommonJS(exports_route));
|
|
2676
|
+
const { hypenAppHandler: hypenAppHandler2 } = (init_hypenapp(), __toCommonJS(exports_hypenapp));
|
|
2316
2677
|
this.register("column", columnHandler2);
|
|
2317
2678
|
this.register("row", rowHandler2);
|
|
2318
2679
|
this.register("text", textHandler2);
|
|
@@ -2344,10 +2705,33 @@ class ComponentRegistry {
|
|
|
2344
2705
|
this.register("paragraph", paragraphHandler2);
|
|
2345
2706
|
this.register("router", routerHandler2);
|
|
2346
2707
|
this.register("route", routeHandler2);
|
|
2708
|
+
this.register("hypenapp", hypenAppHandler2);
|
|
2347
2709
|
}
|
|
2348
2710
|
}
|
|
2349
2711
|
|
|
2350
2712
|
// src/dom/applicators/index.ts
|
|
2713
|
+
var BREAKPOINTS = {
|
|
2714
|
+
sm: "640px",
|
|
2715
|
+
md: "768px",
|
|
2716
|
+
lg: "1024px",
|
|
2717
|
+
xl: "1280px",
|
|
2718
|
+
"2xl": "1536px"
|
|
2719
|
+
};
|
|
2720
|
+
var variantStyleSheet = null;
|
|
2721
|
+
var insertedRules = new Set;
|
|
2722
|
+
function getVariantStyleSheet() {
|
|
2723
|
+
if (!variantStyleSheet) {
|
|
2724
|
+
const style = document.createElement("style");
|
|
2725
|
+
style.id = "hypen-variants";
|
|
2726
|
+
document.head.appendChild(style);
|
|
2727
|
+
variantStyleSheet = style.sheet;
|
|
2728
|
+
}
|
|
2729
|
+
return variantStyleSheet;
|
|
2730
|
+
}
|
|
2731
|
+
function hashValue(value) {
|
|
2732
|
+
return String(value).replace(/[^a-zA-Z0-9]/g, "").slice(0, 8);
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2351
2735
|
class ApplicatorRegistry {
|
|
2352
2736
|
handlers = new Map;
|
|
2353
2737
|
elementState = new WeakMap;
|
|
@@ -2495,12 +2879,55 @@ class ApplicatorRegistry {
|
|
|
2495
2879
|
}
|
|
2496
2880
|
}
|
|
2497
2881
|
setStyleProperty(element, name, value) {
|
|
2498
|
-
const
|
|
2882
|
+
const atIndex = name.indexOf("@");
|
|
2883
|
+
const colonIndex = name.indexOf(":");
|
|
2884
|
+
if (atIndex !== -1) {
|
|
2885
|
+
const prop = name.slice(0, atIndex);
|
|
2886
|
+
const breakpoint = name.slice(atIndex + 1);
|
|
2887
|
+
const minWidth = BREAKPOINTS[breakpoint];
|
|
2888
|
+
if (minWidth) {
|
|
2889
|
+
const cssName2 = this.toKebabCase(prop);
|
|
2890
|
+
const cssValue = this.formatCssValue(cssName2, value);
|
|
2891
|
+
const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${breakpoint}-${hashValue(value)}`;
|
|
2892
|
+
const ruleKey = `${className}:${cssValue}`;
|
|
2893
|
+
if (!insertedRules.has(ruleKey)) {
|
|
2894
|
+
const sheet = getVariantStyleSheet();
|
|
2895
|
+
sheet.insertRule(`@media (min-width: ${minWidth}) { .${className} { ${cssName2}: ${cssValue}; } }`, sheet.cssRules.length);
|
|
2896
|
+
insertedRules.add(ruleKey);
|
|
2897
|
+
}
|
|
2898
|
+
element.classList.add(className);
|
|
2899
|
+
}
|
|
2900
|
+
return;
|
|
2901
|
+
}
|
|
2902
|
+
if (colonIndex !== -1) {
|
|
2903
|
+
const prop = name.slice(0, colonIndex);
|
|
2904
|
+
const state = name.slice(colonIndex + 1);
|
|
2905
|
+
const validStates = ["hover", "focus", "active", "disabled", "focus-visible", "focus-within"];
|
|
2906
|
+
if (validStates.includes(state)) {
|
|
2907
|
+
const cssName2 = this.toKebabCase(prop);
|
|
2908
|
+
const cssValue = this.formatCssValue(cssName2, value);
|
|
2909
|
+
const className = `hypen-${cssName2.replace(/[^a-zA-Z0-9-]/g, "")}-${state}-${hashValue(value)}`;
|
|
2910
|
+
const ruleKey = `${className}:${cssValue}`;
|
|
2911
|
+
if (!insertedRules.has(ruleKey)) {
|
|
2912
|
+
const sheet = getVariantStyleSheet();
|
|
2913
|
+
sheet.insertRule(`.${className}:${state} { ${cssName2}: ${cssValue}; }`, sheet.cssRules.length);
|
|
2914
|
+
insertedRules.add(ruleKey);
|
|
2915
|
+
}
|
|
2916
|
+
element.classList.add(className);
|
|
2917
|
+
}
|
|
2918
|
+
return;
|
|
2919
|
+
}
|
|
2920
|
+
const cssName = this.toKebabCase(name);
|
|
2921
|
+
element.style.setProperty(cssName, this.formatCssValue(cssName, value));
|
|
2922
|
+
}
|
|
2923
|
+
toKebabCase(name) {
|
|
2924
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
2925
|
+
}
|
|
2926
|
+
formatCssValue(cssName, value) {
|
|
2499
2927
|
if (typeof value === "number" && this.needsUnit(cssName)) {
|
|
2500
|
-
|
|
2501
|
-
} else {
|
|
2502
|
-
element.style.setProperty(cssName, String(value));
|
|
2928
|
+
return `${value}px`;
|
|
2503
2929
|
}
|
|
2930
|
+
return String(value);
|
|
2504
2931
|
}
|
|
2505
2932
|
needsUnit(prop) {
|
|
2506
2933
|
const unitless = [
|
|
@@ -2871,13 +3298,13 @@ class DOMRenderer {
|
|
|
2871
3298
|
}
|
|
2872
3299
|
onCreate(id, elementType, props) {
|
|
2873
3300
|
const propsObj = props instanceof Map ? Object.fromEntries(props) : props;
|
|
2874
|
-
|
|
3301
|
+
let element = this.components.createElement(elementType, propsObj);
|
|
2875
3302
|
if (!element) {
|
|
2876
3303
|
const fallback = document.createElement("div");
|
|
2877
|
-
fallback.dataset.hypenType = elementType;
|
|
2878
|
-
fallback.
|
|
2879
|
-
|
|
2880
|
-
|
|
3304
|
+
fallback.dataset.hypenType = elementType.toLowerCase();
|
|
3305
|
+
fallback.style.display = "contents";
|
|
3306
|
+
element = fallback;
|
|
3307
|
+
console.log(`[Renderer] Unknown component "${elementType}" - using transparent container`);
|
|
2881
3308
|
}
|
|
2882
3309
|
element.dataset.hypenType = elementType.toLowerCase();
|
|
2883
3310
|
element.dataset.hypenId = id;
|
|
@@ -3107,4 +3534,4 @@ export {
|
|
|
3107
3534
|
ApplicatorRegistry
|
|
3108
3535
|
};
|
|
3109
3536
|
|
|
3110
|
-
//# debugId=
|
|
3537
|
+
//# debugId=8AAA0D290328E56B64756E2164756E21
|