@hypen-space/web 0.3.9 → 0.3.10

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 (174) hide show
  1. package/dist/{src/canvas → canvas}/index.js +10 -6
  2. package/dist/{src/canvas → canvas}/index.js.map +4 -4
  3. package/dist/{src/canvas → canvas}/layout.js +4 -2
  4. package/dist/{src/canvas → canvas}/layout.js.map +3 -3
  5. package/dist/{src/canvas → canvas}/paint.js +4 -2
  6. package/dist/{src/canvas → canvas}/paint.js.map +3 -3
  7. package/dist/{src/canvas → canvas}/renderer.js +10 -6
  8. package/dist/{src/canvas → canvas}/renderer.js.map +4 -4
  9. package/dist/{src/canvas → canvas}/text.js +4 -2
  10. package/dist/{src/canvas → canvas}/text.js.map +3 -3
  11. package/dist/{src/dom → dom}/applicators/advanced-layout.js +16 -3
  12. package/dist/dom/applicators/advanced-layout.js.map +11 -0
  13. package/dist/{src/dom → dom}/applicators/events.js +6 -4
  14. package/dist/dom/applicators/events.js.map +11 -0
  15. package/dist/{src/dom → dom}/applicators/index.js +153 -24
  16. package/dist/dom/applicators/index.js.map +26 -0
  17. package/dist/{src/dom → dom}/applicators/layout.js +16 -3
  18. package/dist/dom/applicators/layout.js.map +10 -0
  19. package/dist/dom/applicators/margin.js +104 -0
  20. package/dist/dom/applicators/margin.js.map +10 -0
  21. package/dist/dom/applicators/padding.js +104 -0
  22. package/dist/dom/applicators/padding.js.map +10 -0
  23. package/dist/{src/dom → dom}/applicators/size.js +11 -3
  24. package/dist/{src/dom → dom}/applicators/size.js.map +3 -3
  25. package/dist/dom/components/button.js.map +10 -0
  26. package/dist/{src/dom → dom}/components/center.js +4 -1
  27. package/dist/dom/components/center.js.map +10 -0
  28. package/dist/dom/components/column.js.map +10 -0
  29. package/dist/{src/dom → dom}/components/container.js +1 -4
  30. package/dist/{src/dom → dom}/components/container.js.map +3 -3
  31. package/dist/{src/dom → dom}/components/grid.js +18 -2
  32. package/dist/dom/components/grid.js.map +10 -0
  33. package/dist/{src/dom → dom}/components/hypenapp.js +15 -13
  34. package/dist/dom/components/hypenapp.js.map +10 -0
  35. package/dist/{src/dom → dom}/components/index.js +64 -20
  36. package/dist/dom/components/index.js.map +41 -0
  37. package/dist/{src/dom → dom}/components/route.js +5 -3
  38. package/dist/dom/components/route.js.map +10 -0
  39. package/dist/{src/dom → dom}/components/row.js +18 -2
  40. package/dist/dom/components/row.js.map +10 -0
  41. package/dist/{src/dom → dom}/components/stack.js +5 -1
  42. package/dist/dom/components/stack.js.map +10 -0
  43. package/dist/{src/dom → dom}/components/text.js +5 -1
  44. package/dist/dom/components/text.js.map +10 -0
  45. package/dist/{src/dom → dom}/debug.js +5 -3
  46. package/dist/dom/debug.js.map +10 -0
  47. package/dist/{src/dom → dom}/events.js +15 -12
  48. package/dist/dom/events.js.map +10 -0
  49. package/dist/{src/dom/renderer.js → dom/index.js} +345 -55
  50. package/dist/dom/index.js.map +62 -0
  51. package/dist/{src/dom/index.js → dom/renderer.js} +233 -164
  52. package/dist/dom/renderer.js.map +61 -0
  53. package/dist/{src/hypen.js → hypen.js} +265 -118
  54. package/dist/hypen.js.map +62 -0
  55. package/dist/{src/index.js → index.js} +288 -134
  56. package/dist/index.js.map +72 -0
  57. package/package.json +22 -22
  58. package/src/canvas/renderer.ts +7 -4
  59. package/src/canvas/text.ts +4 -1
  60. package/src/dom/applicators/events.ts +6 -12
  61. package/src/dom/applicators/layout.ts +4 -0
  62. package/src/dom/applicators/size.ts +7 -2
  63. package/src/dom/components/center.ts +9 -0
  64. package/src/dom/components/column.ts +0 -4
  65. package/src/dom/components/grid.ts +22 -0
  66. package/src/dom/components/hypenapp.ts +14 -11
  67. package/src/dom/components/route.ts +4 -1
  68. package/src/dom/components/row.ts +20 -0
  69. package/src/dom/debug.ts +6 -2
  70. package/src/dom/events.ts +16 -12
  71. package/src/dom/renderer.ts +12 -9
  72. package/src/hypen.ts +32 -73
  73. package/dist/src/dom/applicators/advanced-layout.js.map +0 -11
  74. package/dist/src/dom/applicators/events.js.map +0 -11
  75. package/dist/src/dom/applicators/index.js.map +0 -26
  76. package/dist/src/dom/applicators/layout.js.map +0 -10
  77. package/dist/src/dom/applicators/margin.js +0 -51
  78. package/dist/src/dom/applicators/margin.js.map +0 -10
  79. package/dist/src/dom/applicators/padding.js +0 -51
  80. package/dist/src/dom/applicators/padding.js.map +0 -10
  81. package/dist/src/dom/components/button.js.map +0 -10
  82. package/dist/src/dom/components/center.js.map +0 -10
  83. package/dist/src/dom/components/column.js.map +0 -10
  84. package/dist/src/dom/components/grid.js.map +0 -10
  85. package/dist/src/dom/components/hypenapp.js.map +0 -10
  86. package/dist/src/dom/components/index.js.map +0 -41
  87. package/dist/src/dom/components/route.js.map +0 -10
  88. package/dist/src/dom/components/row.js.map +0 -10
  89. package/dist/src/dom/components/stack.js.map +0 -10
  90. package/dist/src/dom/components/text.js.map +0 -10
  91. package/dist/src/dom/debug.js.map +0 -10
  92. package/dist/src/dom/events.js.map +0 -10
  93. package/dist/src/dom/index.js.map +0 -62
  94. package/dist/src/dom/renderer.js.map +0 -61
  95. package/dist/src/hypen.js.map +0 -62
  96. package/dist/src/index.js.map +0 -72
  97. /package/dist/{src/canvas → canvas}/accessibility.js +0 -0
  98. /package/dist/{src/canvas → canvas}/accessibility.js.map +0 -0
  99. /package/dist/{src/canvas → canvas}/events.js +0 -0
  100. /package/dist/{src/canvas → canvas}/events.js.map +0 -0
  101. /package/dist/{src/canvas → canvas}/input.js +0 -0
  102. /package/dist/{src/canvas → canvas}/input.js.map +0 -0
  103. /package/dist/{src/canvas → canvas}/types.js +0 -0
  104. /package/dist/{src/canvas → canvas}/types.js.map +0 -0
  105. /package/dist/{src/canvas → canvas}/utils.js +0 -0
  106. /package/dist/{src/canvas → canvas}/utils.js.map +0 -0
  107. /package/dist/{src/dom → dom}/applicators/background.js +0 -0
  108. /package/dist/{src/dom → dom}/applicators/background.js.map +0 -0
  109. /package/dist/{src/dom → dom}/applicators/border.js +0 -0
  110. /package/dist/{src/dom → dom}/applicators/border.js.map +0 -0
  111. /package/dist/{src/dom → dom}/applicators/color.js +0 -0
  112. /package/dist/{src/dom → dom}/applicators/color.js.map +0 -0
  113. /package/dist/{src/dom → dom}/applicators/display.js +0 -0
  114. /package/dist/{src/dom → dom}/applicators/display.js.map +0 -0
  115. /package/dist/{src/dom → dom}/applicators/effects.js +0 -0
  116. /package/dist/{src/dom → dom}/applicators/effects.js.map +0 -0
  117. /package/dist/{src/dom → dom}/applicators/font.js +0 -0
  118. /package/dist/{src/dom → dom}/applicators/font.js.map +0 -0
  119. /package/dist/{src/dom → dom}/applicators/transform.js +0 -0
  120. /package/dist/{src/dom → dom}/applicators/transform.js.map +0 -0
  121. /package/dist/{src/dom → dom}/applicators/transition.js +0 -0
  122. /package/dist/{src/dom → dom}/applicators/transition.js.map +0 -0
  123. /package/dist/{src/dom → dom}/applicators/types.js +0 -0
  124. /package/dist/{src/dom → dom}/applicators/types.js.map +0 -0
  125. /package/dist/{src/dom → dom}/applicators/typography.js +0 -0
  126. /package/dist/{src/dom → dom}/applicators/typography.js.map +0 -0
  127. /package/dist/{src/dom → dom}/canvas/index.js +0 -0
  128. /package/dist/{src/dom → dom}/canvas/index.js.map +0 -0
  129. /package/dist/{src/dom → dom}/components/audio.js +0 -0
  130. /package/dist/{src/dom → dom}/components/audio.js.map +0 -0
  131. /package/dist/{src/dom → dom}/components/avatar.js +0 -0
  132. /package/dist/{src/dom → dom}/components/avatar.js.map +0 -0
  133. /package/dist/{src/dom → dom}/components/badge.js +0 -0
  134. /package/dist/{src/dom → dom}/components/badge.js.map +0 -0
  135. /package/dist/{src/dom → dom}/components/button.js +0 -0
  136. /package/dist/{src/dom → dom}/components/card.js +0 -0
  137. /package/dist/{src/dom → dom}/components/card.js.map +0 -0
  138. /package/dist/{src/dom → dom}/components/checkbox.js +0 -0
  139. /package/dist/{src/dom → dom}/components/checkbox.js.map +0 -0
  140. /package/dist/{src/dom → dom}/components/column.js +0 -0
  141. /package/dist/{src/dom → dom}/components/divider.js +0 -0
  142. /package/dist/{src/dom → dom}/components/divider.js.map +0 -0
  143. /package/dist/{src/dom → dom}/components/heading.js +0 -0
  144. /package/dist/{src/dom → dom}/components/heading.js.map +0 -0
  145. /package/dist/{src/dom → dom}/components/image.js +0 -0
  146. /package/dist/{src/dom → dom}/components/image.js.map +0 -0
  147. /package/dist/{src/dom → dom}/components/input.js +0 -0
  148. /package/dist/{src/dom → dom}/components/input.js.map +0 -0
  149. /package/dist/{src/dom → dom}/components/link.js +0 -0
  150. /package/dist/{src/dom → dom}/components/link.js.map +0 -0
  151. /package/dist/{src/dom → dom}/components/list.js +0 -0
  152. /package/dist/{src/dom → dom}/components/list.js.map +0 -0
  153. /package/dist/{src/dom → dom}/components/paragraph.js +0 -0
  154. /package/dist/{src/dom → dom}/components/paragraph.js.map +0 -0
  155. /package/dist/{src/dom → dom}/components/progressbar.js +0 -0
  156. /package/dist/{src/dom → dom}/components/progressbar.js.map +0 -0
  157. /package/dist/{src/dom → dom}/components/router.js +0 -0
  158. /package/dist/{src/dom → dom}/components/router.js.map +0 -0
  159. /package/dist/{src/dom → dom}/components/select.js +0 -0
  160. /package/dist/{src/dom → dom}/components/select.js.map +0 -0
  161. /package/dist/{src/dom → dom}/components/slider.js +0 -0
  162. /package/dist/{src/dom → dom}/components/slider.js.map +0 -0
  163. /package/dist/{src/dom → dom}/components/spacer.js +0 -0
  164. /package/dist/{src/dom → dom}/components/spacer.js.map +0 -0
  165. /package/dist/{src/dom → dom}/components/spinner.js +0 -0
  166. /package/dist/{src/dom → dom}/components/spinner.js.map +0 -0
  167. /package/dist/{src/dom → dom}/components/switch.js +0 -0
  168. /package/dist/{src/dom → dom}/components/switch.js.map +0 -0
  169. /package/dist/{src/dom → dom}/components/textarea.js +0 -0
  170. /package/dist/{src/dom → dom}/components/textarea.js.map +0 -0
  171. /package/dist/{src/dom → dom}/components/video.js +0 -0
  172. /package/dist/{src/dom → dom}/components/video.js.map +0 -0
  173. /package/dist/{src/dom → dom}/element-data.js +0 -0
  174. /package/dist/{src/dom → dom}/element-data.js.map +0 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/applicators/padding.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Padding Applicators\n */\n\nimport type { ApplicatorHandler } from \"./types.js\";\n\n// Helper to extract numeric value from applicator value\nconst getNumericValue = (value: any): number | null => {\n if (typeof value === \"number\") return value;\n if (typeof value === \"object\" && value[\"0\"] !== undefined) return Number(value[\"0\"]);\n if (typeof value === \"string\") return parseFloat(value);\n return null;\n};\n\nexport const paddingHandler: ApplicatorHandler = (el, value) => {\n if (typeof value === \"number\") {\n el.style.padding = `${value}px`;\n } else if (typeof value === \"object\") {\n // Handle {0: value} format from .padding(value)\n if (value[\"0\"] !== undefined && Object.keys(value).length === 1) {\n el.style.padding = `${value[\"0\"]}px`;\n } else {\n if (value.left !== undefined) el.style.paddingLeft = `${value.left}px`;\n if (value.right !== undefined) el.style.paddingRight = `${value.right}px`;\n if (value.top !== undefined) el.style.paddingTop = `${value.top}px`;\n if (value.bottom !== undefined) el.style.paddingBottom = `${value.bottom}px`;\n }\n } else {\n el.style.padding = String(value);\n }\n};\n\n// Directional padding handlers for .paddingTop(8), .paddingBottom(8), etc.\nexport const paddingTopHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) el.style.paddingTop = `${v}px`;\n};\n\nexport const paddingBottomHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) el.style.paddingBottom = `${v}px`;\n};\n\nexport const paddingLeftHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) el.style.paddingLeft = `${v}px`;\n};\n\nexport const paddingRightHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) el.style.paddingRight = `${v}px`;\n};\n\nexport const paddingHorizontalHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) {\n el.style.paddingLeft = `${v}px`;\n el.style.paddingRight = `${v}px`;\n }\n};\n\nexport const paddingVerticalHandler: ApplicatorHandler = (el, value) => {\n const v = getNumericValue(value);\n if (v !== null) {\n el.style.paddingTop = `${v}px`;\n el.style.paddingBottom = `${v}px`;\n }\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,IAAM,kBAAkB,CAAC,UAA8B;AAAA,EACrD,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO;AAAA,EACtC,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS;AAAA,IAAW,OAAO,OAAO,MAAM,IAAI;AAAA,EACnF,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,WAAW,KAAK;AAAA,EACtD,OAAO;AAAA;AAGF,IAAM,iBAAoC,CAAC,IAAI,UAAU;AAAA,EAC9D,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,GAAG,MAAM,UAAU,GAAG;AAAA,EACxB,EAAO,SAAI,OAAO,UAAU,UAAU;AAAA,IAEpC,IAAI,MAAM,SAAS,aAAa,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AAAA,MAC/D,GAAG,MAAM,UAAU,GAAG,MAAM;AAAA,IAC9B,EAAO;AAAA,MACL,IAAI,MAAM,SAAS;AAAA,QAAW,GAAG,MAAM,cAAc,GAAG,MAAM;AAAA,MAC9D,IAAI,MAAM,UAAU;AAAA,QAAW,GAAG,MAAM,eAAe,GAAG,MAAM;AAAA,MAChE,IAAI,MAAM,QAAQ;AAAA,QAAW,GAAG,MAAM,aAAa,GAAG,MAAM;AAAA,MAC5D,IAAI,MAAM,WAAW;AAAA,QAAW,GAAG,MAAM,gBAAgB,GAAG,MAAM;AAAA;AAAA,EAEtE,EAAO;AAAA,IACL,GAAG,MAAM,UAAU,OAAO,KAAK;AAAA;AAAA;AAK5B,IAAM,oBAAuC,CAAC,IAAI,UAAU;AAAA,EACjE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM;AAAA,IAAM,GAAG,MAAM,aAAa,GAAG;AAAA;AAGpC,IAAM,uBAA0C,CAAC,IAAI,UAAU;AAAA,EACpE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM;AAAA,IAAM,GAAG,MAAM,gBAAgB,GAAG;AAAA;AAGvC,IAAM,qBAAwC,CAAC,IAAI,UAAU;AAAA,EAClE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM;AAAA,IAAM,GAAG,MAAM,cAAc,GAAG;AAAA;AAGrC,IAAM,sBAAyC,CAAC,IAAI,UAAU;AAAA,EACnE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM;AAAA,IAAM,GAAG,MAAM,eAAe,GAAG;AAAA;AAGtC,IAAM,2BAA8C,CAAC,IAAI,UAAU;AAAA,EACxE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM,MAAM;AAAA,IACd,GAAG,MAAM,cAAc,GAAG;AAAA,IAC1B,GAAG,MAAM,eAAe,GAAG;AAAA,EAC7B;AAAA;AAGK,IAAM,yBAA4C,CAAC,IAAI,UAAU;AAAA,EACtE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC/B,IAAI,MAAM,MAAM;AAAA,IACd,GAAG,MAAM,aAAa,GAAG;AAAA,IACzB,GAAG,MAAM,gBAAgB,GAAG;AAAA,EAC9B;AAAA;",
8
+ "debugId": "E0841354428C4B5C64756E2164756E21",
9
+ "names": []
10
+ }
@@ -134,8 +134,14 @@ var sizeHandlers = {
134
134
  if (value === false)
135
135
  return;
136
136
  const fraction = typeof value === "number" ? value : 1;
137
- el.style.width = `${fraction * 100}%`;
138
- el.style.alignSelf = "stretch";
137
+ if (fraction === 1) {
138
+ el.style.alignSelf = "stretch";
139
+ el.style.width = "100%";
140
+ el.style.minWidth = "0";
141
+ } else {
142
+ el.style.width = `${fraction * 100}%`;
143
+ }
144
+ el.style.justifySelf = "stretch";
139
145
  },
140
146
  fillMaxHeight: (el, value) => {
141
147
  if (value === false)
@@ -149,10 +155,12 @@ var sizeHandlers = {
149
155
  const fraction = typeof value === "number" ? value : 1;
150
156
  el.style.width = `${fraction * 100}%`;
151
157
  el.style.height = `${fraction * 100}%`;
158
+ el.style.alignSelf = "stretch";
159
+ el.style.minWidth = "0";
152
160
  }
153
161
  };
154
162
  export {
155
163
  sizeHandlers
156
164
  };
157
165
 
158
- //# debugId=DBF2E14C2DC020D964756E2164756E21
166
+ //# debugId=1F734C4E0559486864756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/dom/applicators/size.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Size Applicators\n *\n * Cross-platform sizing value support:\n * - Numbers: treated as px (platform default)\n * - \"100px\": absolute pixels (1px = 1px everywhere)\n * - \"100dp\" / \"100pt\": density-independent (1dp ≈ 1pt, scaled by device)\n * - \"50%\": percentage of parent\n * - \"50vw\" / \"50vh\": viewport width/height\n * - \"fill\" / \"100%\": fill available space\n * - \"wrap\" / \"auto\": fit content\n */\n\nimport type { ApplicatorHandler } from \"./types.js\";\n\n/**\n * Parse a size value and return CSS-compatible string.\n * Ensures cross-platform compatibility with Android/iOS.\n */\nfunction parseSizeValue(value: any): string | null {\n if (value === null || value === undefined) return null;\n\n // Numbers default to px\n if (typeof value === \"number\") {\n return `${value}px`;\n }\n\n const str = String(value).trim().toLowerCase();\n\n // Keywords\n switch (str) {\n case \"fill\":\n case \"match_parent\":\n return \"100%\";\n case \"wrap\":\n case \"wrap_content\":\n case \"auto\":\n return \"auto\";\n case \"infinity\":\n case \"inf\":\n case \"max\":\n return \"100%\";\n }\n\n // Parse value with unit\n const match = str.match(/^(-?[\\d.]+)\\s*(px|dp|pt|%|vw|vh|vmin|vmax|em|rem)?$/);\n if (!match) {\n // Pass through other CSS values as-is (e.g., \"calc(...)\", \"fit-content\")\n return str;\n }\n\n const num = parseFloat(match[1]);\n const unit = match[2] || \"px\";\n\n switch (unit) {\n case \"px\":\n // Absolute pixels - use as-is\n return `${num}px`;\n case \"dp\":\n case \"pt\":\n // Density-independent points\n // On web, 1dp/1pt ≈ 1px at standard density (96dpi)\n // CSS already handles this via px, so we just use px\n // For true density independence, we'd need to query devicePixelRatio\n // but CSS px is already defined as 1/96th of an inch\n return `${num}px`;\n case \"%\":\n return `${num}%`;\n case \"vw\":\n return `${num}vw`;\n case \"vh\":\n return `${num}vh`;\n case \"vmin\":\n return `${num}vmin`;\n case \"vmax\":\n return `${num}vmax`;\n case \"em\":\n return `${num}em`;\n case \"rem\":\n return `${num}rem`;\n default:\n return `${num}px`;\n }\n}\n\nexport const sizeHandlers: Record<string, ApplicatorHandler> = {\n width: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.width = size;\n },\n\n height: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.height = size;\n },\n\n minWidth: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.minWidth = size;\n },\n\n minHeight: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.minHeight = size;\n },\n\n maxWidth: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.maxWidth = size;\n },\n\n maxHeight: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.maxHeight = size;\n },\n\n // Combined size applicator - sets both width and height\n size: (el, value) => {\n if (typeof value === \"object\" && value !== null) {\n const obj = value as Record<string, any>;\n if (obj.width !== undefined) {\n const w = parseSizeValue(obj.width);\n if (w) el.style.width = w;\n }\n if (obj.height !== undefined) {\n const h = parseSizeValue(obj.height);\n if (h) el.style.height = h;\n }\n } else {\n const size = parseSizeValue(value);\n if (size) {\n el.style.width = size;\n el.style.height = size;\n }\n }\n },\n\n // Fill max width - shorthand for width: 100%\n fillMaxWidth: (el, value) => {\n if (value === false) return;\n // Value can be a fraction (0-1) or boolean\n const fraction = typeof value === \"number\" ? value : 1;\n el.style.width = `${fraction * 100}%`;\n // Also set alignSelf to stretch so this works inside flex containers\n // with alignItems: flex-start (like Column/Row defaults)\n el.style.alignSelf = \"stretch\";\n },\n\n // Fill max height - shorthand for height: 100%\n fillMaxHeight: (el, value) => {\n if (value === false) return;\n // Value can be a fraction (0-1) or boolean\n const fraction = typeof value === \"number\" ? value : 1;\n el.style.height = `${fraction * 100}%`;\n },\n\n // Fill max size - shorthand for width: 100% and height: 100%\n fillMaxSize: (el, value) => {\n if (value === false) return;\n // Value can be a fraction (0-1) or boolean\n const fraction = typeof value === \"number\" ? value : 1;\n el.style.width = `${fraction * 100}%`;\n el.style.height = `${fraction * 100}%`;\n },\n};\n"
5
+ "/**\n * Size Applicators\n *\n * Cross-platform sizing value support:\n * - Numbers: treated as px (platform default)\n * - \"100px\": absolute pixels (1px = 1px everywhere)\n * - \"100dp\" / \"100pt\": density-independent (1dp ≈ 1pt, scaled by device)\n * - \"50%\": percentage of parent\n * - \"50vw\" / \"50vh\": viewport width/height\n * - \"fill\" / \"100%\": fill available space\n * - \"wrap\" / \"auto\": fit content\n */\n\nimport type { ApplicatorHandler } from \"./types.js\";\n\n/**\n * Parse a size value and return CSS-compatible string.\n * Ensures cross-platform compatibility with Android/iOS.\n */\nfunction parseSizeValue(value: any): string | null {\n if (value === null || value === undefined) return null;\n\n // Numbers default to px\n if (typeof value === \"number\") {\n return `${value}px`;\n }\n\n const str = String(value).trim().toLowerCase();\n\n // Keywords\n switch (str) {\n case \"fill\":\n case \"match_parent\":\n return \"100%\";\n case \"wrap\":\n case \"wrap_content\":\n case \"auto\":\n return \"auto\";\n case \"infinity\":\n case \"inf\":\n case \"max\":\n return \"100%\";\n }\n\n // Parse value with unit\n const match = str.match(/^(-?[\\d.]+)\\s*(px|dp|pt|%|vw|vh|vmin|vmax|em|rem)?$/);\n if (!match) {\n // Pass through other CSS values as-is (e.g., \"calc(...)\", \"fit-content\")\n return str;\n }\n\n const num = parseFloat(match[1]);\n const unit = match[2] || \"px\";\n\n switch (unit) {\n case \"px\":\n // Absolute pixels - use as-is\n return `${num}px`;\n case \"dp\":\n case \"pt\":\n // Density-independent points\n // On web, 1dp/1pt ≈ 1px at standard density (96dpi)\n // CSS already handles this via px, so we just use px\n // For true density independence, we'd need to query devicePixelRatio\n // but CSS px is already defined as 1/96th of an inch\n return `${num}px`;\n case \"%\":\n return `${num}%`;\n case \"vw\":\n return `${num}vw`;\n case \"vh\":\n return `${num}vh`;\n case \"vmin\":\n return `${num}vmin`;\n case \"vmax\":\n return `${num}vmax`;\n case \"em\":\n return `${num}em`;\n case \"rem\":\n return `${num}rem`;\n default:\n return `${num}px`;\n }\n}\n\nexport const sizeHandlers: Record<string, ApplicatorHandler> = {\n width: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.width = size;\n },\n\n height: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.height = size;\n },\n\n minWidth: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.minWidth = size;\n },\n\n minHeight: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.minHeight = size;\n },\n\n maxWidth: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.maxWidth = size;\n },\n\n maxHeight: (el, value) => {\n const size = parseSizeValue(value);\n if (size) el.style.maxHeight = size;\n },\n\n // Combined size applicator - sets both width and height\n size: (el, value) => {\n if (typeof value === \"object\" && value !== null) {\n const obj = value as Record<string, any>;\n if (obj.width !== undefined) {\n const w = parseSizeValue(obj.width);\n if (w) el.style.width = w;\n }\n if (obj.height !== undefined) {\n const h = parseSizeValue(obj.height);\n if (h) el.style.height = h;\n }\n } else {\n const size = parseSizeValue(value);\n if (size) {\n el.style.width = size;\n el.style.height = size;\n }\n }\n },\n\n // Fill max width - stretch to fill parent width\n // Note: This only stretches within parent's current width.\n // For full-width behavior, parent Columns also need fillMaxWidth(true).\n fillMaxWidth: (el, value) => {\n if (value === false) return;\n const fraction = typeof value === \"number\" ? value : 1;\n if (fraction === 1) {\n // Use align-self stretch to fill cross-axis in flex containers\n el.style.alignSelf = \"stretch\";\n el.style.width = \"100%\";\n el.style.minWidth = \"0\"; // Prevent flex item from overflowing\n } else {\n // For fractional width, use percentage\n el.style.width = `${fraction * 100}%`;\n }\n // For grid containers (Stack)\n el.style.justifySelf = \"stretch\";\n },\n\n // Fill max height - shorthand for height: 100%\n fillMaxHeight: (el, value) => {\n if (value === false) return;\n // Value can be a fraction (0-1) or boolean\n const fraction = typeof value === \"number\" ? value : 1;\n el.style.height = `${fraction * 100}%`;\n },\n\n // Fill max size - shorthand for width: 100% and height: 100%\n fillMaxSize: (el, value) => {\n if (value === false) return;\n // Value can be a fraction (0-1) or boolean\n const fraction = typeof value === \"number\" ? value : 1;\n el.style.width = `${fraction * 100}%`;\n el.style.height = `${fraction * 100}%`;\n // Use align-self stretch to fill cross-axis in flex containers\n // This is needed because parent might have alignItems: flex-start (wrap behavior)\n el.style.alignSelf = \"stretch\";\n el.style.minWidth = \"0\"; // Prevent flex item from overflowing\n },\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "DBF2E14C2DC020D964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "1F734C4E0559486864756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/components/button.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Button Component\n *\n * Renders as a flex container. Children align to start by default (matching iOS).\n * Use .horizontalAlignment(\"center\") to center content.\n * Reset default HTML button styles for cross-platform consistency.\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\nexport const buttonHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"button\");\n // Reset default button styles for cross-platform consistency\n el.style.border = \"none\";\n el.style.background = \"none\";\n el.style.padding = \"0\";\n el.style.margin = \"0\";\n el.style.font = \"inherit\";\n el.style.color = \"inherit\";\n el.style.cursor = \"pointer\";\n // Make it a flex container - align to start by default (matching iOS)\n // Use .horizontalAlignment(\"center\") to center content\n el.style.display = \"flex\";\n el.style.flexDirection = \"column\";\n el.style.alignItems = \"flex-start\";\n el.dataset.hypenType = \"button\";\n return el;\n },\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUa;AAAA;AAAA,kBAAkC;AAAA,IAC7C,MAAM,GAAgB;AAAA,MACpB,MAAM,KAAK,SAAS,cAAc,QAAQ;AAAA,MAE1C,GAAG,MAAM,SAAS;AAAA,MAClB,GAAG,MAAM,aAAa;AAAA,MACtB,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,MAAM,SAAS;AAAA,MAClB,GAAG,MAAM,OAAO;AAAA,MAChB,GAAG,MAAM,QAAQ;AAAA,MACjB,GAAG,MAAM,SAAS;AAAA,MAGlB,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,MAAM,gBAAgB;AAAA,MACzB,GAAG,MAAM,aAAa;AAAA,MACtB,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,EAEX;AAAA;",
8
+ "debugId": "315C3A47E9E96BE664756E2164756E21",
9
+ "names": []
10
+ }
@@ -40,6 +40,9 @@ var init_center = __esm(() => {
40
40
  el.style.display = "flex";
41
41
  el.style.alignItems = "center";
42
42
  el.style.justifyContent = "center";
43
+ el.style.width = "100%";
44
+ el.style.height = "100%";
45
+ el.style.alignSelf = "stretch";
43
46
  el.dataset.hypenType = "center";
44
47
  return el;
45
48
  }
@@ -51,4 +54,4 @@ export {
51
54
  centerHandler
52
55
  };
53
56
 
54
- //# debugId=373FA3951950D07364756E2164756E21
57
+ //# debugId=B5A7E91C75BAAC2C64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/components/center.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Center Component - Centers content\n *\n * Center expands to fill available space by default (matching iOS/Android behavior).\n * This is because a Center that wraps to content can't meaningfully center anything.\n * The expansion is constrained by parent's layout rules.\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\nexport const centerHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"div\");\n el.style.display = \"flex\";\n el.style.alignItems = \"center\";\n el.style.justifyContent = \"center\";\n // Center expands to fill available space by default\n // This matches iOS which has .frame(maxWidth: .infinity, maxHeight: .infinity)\n el.style.width = \"100%\";\n el.style.height = \"100%\";\n el.style.alignSelf = \"stretch\"; // Needed for flex containers with alignItems: flex-start\n el.dataset.hypenType = \"center\";\n return el;\n },\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUa;AAAA;AAAA,kBAAkC;AAAA,IAC7C,MAAM,GAAgB;AAAA,MACpB,MAAM,KAAK,SAAS,cAAc,KAAK;AAAA,MACvC,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,MAAM,aAAa;AAAA,MACtB,GAAG,MAAM,iBAAiB;AAAA,MAG1B,GAAG,MAAM,QAAQ;AAAA,MACjB,GAAG,MAAM,SAAS;AAAA,MAClB,GAAG,MAAM,YAAY;AAAA,MACrB,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,EAEX;AAAA;",
8
+ "debugId": "B5A7E91C75BAAC2C64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/components/column.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Column Component - Vertical Stack\n *\n * Children wrap to content by default (matching Android/iOS behavior).\n * Use .fillMaxWidth() on children or .horizontalAlignment(\"stretch\") to stretch.\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\nexport const columnHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"div\");\n el.style.display = \"flex\";\n el.style.flexDirection = \"column\";\n // Wrap children to content by default (match iOS/Android behavior)\n el.style.alignItems = \"flex-start\";\n el.dataset.hypenType = \"column\";\n return el;\n },\n};\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASa;AAAA;AAAA,kBAAkC;AAAA,IAC7C,MAAM,GAAgB;AAAA,MACpB,MAAM,KAAK,SAAS,cAAc,KAAK;AAAA,MACvC,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,MAAM,gBAAgB;AAAA,MAEzB,GAAG,MAAM,aAAa;AAAA,MACtB,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,EAEX;AAAA;",
8
+ "debugId": "1577A6018C457F2F64756E2164756E21",
9
+ "names": []
10
+ }
@@ -37,9 +37,6 @@ var init_container = __esm(() => {
37
37
  containerHandler = {
38
38
  create() {
39
39
  const el = document.createElement("div");
40
- el.style.display = "flex";
41
- el.style.flexDirection = "column";
42
- el.style.alignItems = "stretch";
43
40
  el.dataset.hypenType = "container";
44
41
  return el;
45
42
  }
@@ -51,4 +48,4 @@ export {
51
48
  containerHandler
52
49
  };
53
50
 
54
- //# debugId=D2BCF2656633C87064756E2164756E21
51
+ //# debugId=5C3788DCC1E812AD64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/dom/components/container.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Container/Box Component\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\nexport const containerHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"div\");\n el.style.display = \"flex\";\n el.style.flexDirection = \"column\";\n el.style.alignItems = \"stretch\";\n el.dataset.hypenType = \"container\";\n return el;\n },\n};\n"
5
+ "/**\n * Container/Box Component\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\nexport const containerHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"div\");\n // Simple block container - wraps to content by default\n // Use .fillMaxWidth(true) to stretch\n el.dataset.hypenType = \"container\";\n return el;\n },\n};\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMa;AAAA;AAAA,qBAAqC;AAAA,IAChD,MAAM,GAAgB;AAAA,MACpB,MAAM,KAAK,SAAS,cAAc,KAAK;AAAA,MACvC,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,MAAM,gBAAgB;AAAA,MACzB,GAAG,MAAM,aAAa;AAAA,MACtB,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,EAEX;AAAA;",
8
- "debugId": "D2BCF2656633C87064756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMa;AAAA;AAAA,qBAAqC;AAAA,IAChD,MAAM,GAAgB;AAAA,MACpB,MAAM,KAAK,SAAS,cAAc,KAAK;AAAA,MAGvC,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,EAEX;AAAA;",
8
+ "debugId": "5C3788DCC1E812AD64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -32,10 +32,26 @@ var exports_grid = {};
32
32
  __export(exports_grid, {
33
33
  gridHandler: () => gridHandler
34
34
  });
35
- var gridHandler;
35
+ function ensureGridStyles() {
36
+ if (gridStylesInjected)
37
+ return;
38
+ gridStylesInjected = true;
39
+ const style = document.createElement("style");
40
+ style.id = "hypen-grid-styles";
41
+ style.textContent = `
42
+ /* Grid children stretch to fill cells by default (matches Android behavior) */
43
+ [data-hypen-type="grid"] > * {
44
+ justify-self: stretch;
45
+ align-self: stretch;
46
+ }
47
+ `;
48
+ document.head.appendChild(style);
49
+ }
50
+ var gridStylesInjected = false, gridHandler;
36
51
  var init_grid = __esm(() => {
37
52
  gridHandler = {
38
53
  create() {
54
+ ensureGridStyles();
39
55
  const el = document.createElement("div");
40
56
  el.style.display = "grid";
41
57
  el.dataset.hypenType = "grid";
@@ -63,4 +79,4 @@ export {
63
79
  gridHandler
64
80
  };
65
81
 
66
- //# debugId=D40001AB02746ECF64756E2164756E21
82
+ //# debugId=4525383A29F60B7164756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/components/grid.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Grid Component - CSS Grid Layout\n *\n * Grid items stretch to fill their cells by default (matching Android/iOS behavior).\n */\n\nimport type { ComponentHandler } from \"./index.js\";\n\n// Inject global styles for grid children\nlet gridStylesInjected = false;\nfunction ensureGridStyles(): void {\n if (gridStylesInjected) return;\n gridStylesInjected = true;\n\n const style = document.createElement(\"style\");\n style.id = \"hypen-grid-styles\";\n style.textContent = `\n /* Grid children stretch to fill cells by default (matches Android behavior) */\n [data-hypen-type=\"grid\"] > * {\n justify-self: stretch;\n align-self: stretch;\n }\n `;\n document.head.appendChild(style);\n}\n\nexport const gridHandler: ComponentHandler = {\n create(): HTMLElement {\n ensureGridStyles();\n\n const el = document.createElement(\"div\");\n el.style.display = \"grid\";\n el.dataset.hypenType = \"grid\";\n return el;\n },\n\n applyProps(el: HTMLElement, props: Record<string, any>): void {\n // Columns\n if (props.columns !== undefined) {\n const columns = typeof props.columns === \"number\"\n ? `repeat(${props.columns}, 1fr)`\n : String(props.columns);\n el.style.gridTemplateColumns = columns;\n }\n\n // Rows\n if (props.rows !== undefined) {\n const rows = typeof props.rows === \"number\"\n ? `repeat(${props.rows}, 1fr)`\n : String(props.rows);\n el.style.gridTemplateRows = rows;\n }\n\n // Gap\n if (props.gap !== undefined) {\n const gap = typeof props.gap === \"number\" ? `${props.gap}px` : String(props.gap);\n el.style.gap = gap;\n }\n },\n};\n\n\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,SAAS,gBAAgB,GAAS;AAAA,EAChC,IAAI;AAAA,IAAoB;AAAA,EACxB,qBAAqB;AAAA,EAErB,MAAM,QAAQ,SAAS,cAAc,OAAO;AAAA,EAC5C,MAAM,KAAK;AAAA,EACX,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,SAAS,KAAK,YAAY,KAAK;AAAA;AAAA,IAd7B,qBAAqB,OAiBZ;AAAA;AAAA,gBAAgC;AAAA,IAC3C,MAAM,GAAgB;AAAA,MACpB,iBAAiB;AAAA,MAEjB,MAAM,KAAK,SAAS,cAAc,KAAK;AAAA,MACvC,GAAG,MAAM,UAAU;AAAA,MACnB,GAAG,QAAQ,YAAY;AAAA,MACvB,OAAO;AAAA;AAAA,IAGT,UAAU,CAAC,IAAiB,OAAkC;AAAA,MAE5D,IAAI,MAAM,YAAY,WAAW;AAAA,QAC/B,MAAM,UAAU,OAAO,MAAM,YAAY,WACrC,UAAU,MAAM,kBAChB,OAAO,MAAM,OAAO;AAAA,QACxB,GAAG,MAAM,sBAAsB;AAAA,MACjC;AAAA,MAGA,IAAI,MAAM,SAAS,WAAW;AAAA,QAC5B,MAAM,OAAO,OAAO,MAAM,SAAS,WAC/B,UAAU,MAAM,eAChB,OAAO,MAAM,IAAI;AAAA,QACrB,GAAG,MAAM,mBAAmB;AAAA,MAC9B;AAAA,MAGA,IAAI,MAAM,QAAQ,WAAW;AAAA,QAC3B,MAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,GAAG,MAAM,UAAU,OAAO,MAAM,GAAG;AAAA,QAC/E,GAAG,MAAM,MAAM;AAAA,MACjB;AAAA;AAAA,EAEJ;AAAA;",
8
+ "debugId": "4525383A29F60B7164756E2164756E21",
9
+ "names": []
10
+ }
@@ -34,11 +34,12 @@ __export(exports_hypenapp, {
34
34
  disconnectHypenApp: () => disconnectHypenApp
35
35
  });
36
36
  import { RemoteEngine } from "@hypen-space/core/remote/client";
37
+ import { frameworkLoggers } from "@hypen-space/core";
37
38
  function applyPatches(container, nodes, patches, engine, onRoot) {
38
39
  for (const patch of patches) {
39
40
  switch (patch.type) {
40
41
  case "create": {
41
- const el = createElement(patch.element_type, patch.props || {});
42
+ const el = createElement(patch.elementType, patch.props || {});
42
43
  el.dataset.hypenId = patch.id;
43
44
  el.__hypenEngine = engine;
44
45
  nodes.set(patch.id, el);
@@ -59,10 +60,10 @@ function applyPatches(container, nodes, patches, engine, onRoot) {
59
60
  break;
60
61
  }
61
62
  case "insert": {
62
- const parentId = patch.parent_id;
63
+ const parentId = patch.parentId;
63
64
  const parent = parentId === "root" ? container : nodes.get(parentId);
64
65
  const child = nodes.get(patch.id);
65
- const beforeId = patch.before_id;
66
+ const beforeId = patch.beforeId;
66
67
  if (parent && child) {
67
68
  if (parentId === "root") {
68
69
  onRoot(patch.id);
@@ -81,10 +82,10 @@ function applyPatches(container, nodes, patches, engine, onRoot) {
81
82
  break;
82
83
  }
83
84
  case "move": {
84
- const parentId = patch.parent_id;
85
+ const parentId = patch.parentId;
85
86
  const parent = parentId === "root" ? container : nodes.get(parentId);
86
87
  const child = nodes.get(patch.id);
87
- const beforeId = patch.before_id;
88
+ const beforeId = patch.beforeId;
88
89
  if (parent && child) {
89
90
  if (beforeId) {
90
91
  const before = nodes.get(beforeId);
@@ -218,8 +219,9 @@ function disconnectHypenApp(element) {
218
219
  activeInstances.delete(element);
219
220
  }
220
221
  }
221
- var activeInstances, hypenAppHandler;
222
+ var log, activeInstances, hypenAppHandler;
222
223
  var init_hypenapp = __esm(() => {
224
+ log = frameworkLoggers.remote;
223
225
  activeInstances = new WeakMap;
224
226
  hypenAppHandler = {
225
227
  create() {
@@ -231,7 +233,7 @@ var init_hypenapp = __esm(() => {
231
233
  applyProps(element, props) {
232
234
  const url = props["0"] || props.url;
233
235
  if (!url || typeof url !== "string") {
234
- console.error("[HypenApp] URL is required");
236
+ log.error("HypenApp: URL is required");
235
237
  element.innerHTML = '<div style="color: red;">HypenApp: URL required</div>';
236
238
  return;
237
239
  }
@@ -256,16 +258,16 @@ var init_hypenapp = __esm(() => {
256
258
  element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
257
259
  engine.connect().then(() => {
258
260
  element.innerHTML = "";
259
- console.log(`[HypenApp] Connected to ${url}`);
261
+ log.debug(`HypenApp connected to ${url}`);
260
262
  }).catch((error) => {
261
263
  element.innerHTML = `<div style="color: red;">HypenApp: Connection failed - ${error.message}</div>`;
262
- console.error("[HypenApp] Connection failed:", error);
264
+ log.error("HypenApp connection failed:", error);
263
265
  });
264
266
  engine.onDisconnect(() => {
265
- console.log("[HypenApp] Disconnected");
267
+ log.debug("HypenApp disconnected");
266
268
  });
267
269
  engine.onError((error) => {
268
- console.error("[HypenApp] Error:", error);
270
+ log.error("HypenApp error:", error);
269
271
  });
270
272
  const observer = new MutationObserver((mutations) => {
271
273
  for (const mutation of mutations) {
@@ -274,7 +276,7 @@ var init_hypenapp = __esm(() => {
274
276
  engine.disconnect();
275
277
  activeInstances.delete(element);
276
278
  observer.disconnect();
277
- console.log("[HypenApp] Cleaned up");
279
+ log.debug("HypenApp cleaned up");
278
280
  return;
279
281
  }
280
282
  }
@@ -293,4 +295,4 @@ export {
293
295
  disconnectHypenApp
294
296
  };
295
297
 
296
- //# debugId=FF8625BC3E34C63E64756E2164756E21
298
+ //# debugId=7ED34EBF06ECAF2F64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/dom/components/hypenapp.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * HypenApp Component\n *\n * Embeds a remote Hypen app via WebSocket\n *\n * Usage in Hypen DSL:\n * ```hypen\n * HypenApp(\"ws://localhost:3000\")\n *\n * // Or with named prop:\n * HypenApp(url: \"ws://localhost:3000\")\n * ```\n */\n\nimport type { ComponentHandler } from \"./index.js\";\nimport { RemoteEngine } from \"@hypen-space/core/remote/client\";\nimport type { Patch } from \"@hypen-space/core/remote\";\nimport { frameworkLoggers } from \"@hypen-space/core\";\n\nconst log = frameworkLoggers.remote;\n\n// Store active HypenApp instances for cleanup\nconst activeInstances = new WeakMap<\n HTMLElement,\n {\n engine: RemoteEngine;\n nodes: Map<string, HTMLElement>;\n }\n>();\n\nexport const hypenAppHandler: ComponentHandler = {\n create(): HTMLElement {\n const el = document.createElement(\"div\");\n el.dataset.hypenType = \"hypenapp\";\n el.style.display = \"contents\"; // Don't affect layout\n return el;\n },\n\n applyProps(element: HTMLElement, props: Record<string, any>): void {\n // Get URL from props (can be positional \"0\" or named \"url\")\n const url = props[\"0\"] || props.url;\n\n if (!url || typeof url !== \"string\") {\n log.error(\"HypenApp: URL is required\");\n element.innerHTML = '<div style=\"color: red;\">HypenApp: URL required</div>';\n return;\n }\n\n // Check if already connected\n const existing = activeInstances.get(element);\n if (existing) {\n // Already connected, don't reconnect\n return;\n }\n\n // Create the remote engine\n const engine = new RemoteEngine(url, {\n autoReconnect: props.autoReconnect ?? true,\n reconnectInterval: props.reconnectInterval ?? 3000,\n maxReconnectAttempts: props.maxReconnectAttempts ?? 10,\n });\n\n // Map to track created nodes\n const nodes = new Map<string, HTMLElement>();\n let rootId: string | null = null;\n\n // Store instance for cleanup\n activeInstances.set(element, { engine, nodes });\n\n // Set up patch handling\n engine.onPatches((patches) => {\n applyPatches(element, nodes, patches, engine, (id) => {\n if (!rootId) rootId = id;\n });\n });\n\n // Show loading state\n element.innerHTML = '<div class=\"hypen-app-loading\">Connecting...</div>';\n\n // Connect\n engine\n .connect()\n .then(() => {\n // Clear loading state - patches will populate content\n element.innerHTML = \"\";\n log.debug(`HypenApp connected to ${url}`);\n })\n .catch((error) => {\n element.innerHTML = `<div style=\"color: red;\">HypenApp: Connection failed - ${error.message}</div>`;\n log.error(\"HypenApp connection failed:\", error);\n });\n\n // Handle disconnection\n engine.onDisconnect(() => {\n log.debug(\"HypenApp disconnected\");\n });\n\n engine.onError((error) => {\n log.error(\"HypenApp error:\", error);\n });\n\n // Cleanup on element removal\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const removedNode of mutation.removedNodes) {\n if (removedNode === element || (removedNode as Element).contains?.(element)) {\n engine.disconnect();\n activeInstances.delete(element);\n observer.disconnect();\n log.debug(\"HypenApp cleaned up\");\n return;\n }\n }\n }\n });\n\n // Observe parent for removal\n if (element.parentNode) {\n observer.observe(element.parentNode, { childList: true, subtree: true });\n }\n },\n};\n\n/**\n * Minimal patch application for HypenApp container\n */\nfunction applyPatches(\n container: HTMLElement,\n nodes: Map<string, HTMLElement>,\n patches: Patch[],\n engine: RemoteEngine,\n onRoot: (id: string) => void\n): void {\n for (const patch of patches) {\n switch (patch.type) {\n case \"create\": {\n const el = createElement(patch.elementType!, patch.props || {});\n el.dataset.hypenId = patch.id!;\n (el as any).__hypenEngine = engine;\n nodes.set(patch.id!, el);\n break;\n }\n\n case \"setProp\": {\n const el = nodes.get(patch.id!);\n if (el) {\n applyProp(el, patch.name!, patch.value);\n }\n break;\n }\n\n case \"setText\": {\n const el = nodes.get(patch.id!);\n if (el) {\n el.textContent = patch.text!;\n }\n break;\n }\n\n case \"insert\": {\n const parentId = patch.parentId;\n const parent = parentId === \"root\" ? container : nodes.get(parentId);\n const child = nodes.get(patch.id!);\n const beforeId = patch.beforeId;\n\n if (parent && child) {\n if (parentId === \"root\") {\n onRoot(patch.id!);\n }\n\n if (beforeId) {\n const before = nodes.get(beforeId);\n if (before && before.parentNode === parent) {\n parent.insertBefore(child, before);\n } else if (!parent.contains(child)) {\n parent.appendChild(child);\n }\n } else if (!parent.contains(child)) {\n parent.appendChild(child);\n }\n }\n break;\n }\n\n case \"move\": {\n const parentId = patch.parentId;\n const parent = parentId === \"root\" ? container : nodes.get(parentId);\n const child = nodes.get(patch.id!);\n const beforeId = patch.beforeId;\n\n if (parent && child) {\n if (beforeId) {\n const before = nodes.get(beforeId);\n if (before && before.parentNode === parent) {\n parent.insertBefore(child, before);\n }\n } else {\n parent.appendChild(child);\n }\n }\n break;\n }\n\n case \"remove\": {\n const el = nodes.get(patch.id!);\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n nodes.delete(patch.id!);\n break;\n }\n }\n }\n}\n\n/**\n * Create element by type\n */\nfunction createElement(type: string, props: Record<string, any>): HTMLElement {\n const normalizedType = type.toLowerCase();\n\n // Map Hypen types to HTML elements\n const tagMap: Record<string, string> = {\n column: \"div\",\n row: \"div\",\n text: \"span\",\n button: \"button\",\n input: \"input\",\n image: \"img\",\n container: \"div\",\n box: \"div\",\n center: \"div\",\n list: \"div\",\n spacer: \"div\",\n stack: \"div\",\n divider: \"hr\",\n grid: \"div\",\n card: \"div\",\n heading: \"h2\",\n link: \"a\",\n textarea: \"textarea\",\n checkbox: \"input\",\n select: \"select\",\n slider: \"input\",\n switch: \"input\",\n spinner: \"div\",\n badge: \"span\",\n avatar: \"img\",\n progressbar: \"div\",\n video: \"video\",\n audio: \"audio\",\n };\n\n const tag = tagMap[normalizedType] || \"div\";\n const el = document.createElement(tag);\n el.dataset.hypenType = normalizedType;\n\n // Apply basic styles\n if (normalizedType === \"column\") {\n el.style.display = \"flex\";\n el.style.flexDirection = \"column\";\n } else if (normalizedType === \"row\") {\n el.style.display = \"flex\";\n el.style.flexDirection = \"row\";\n } else if (normalizedType === \"center\") {\n el.style.display = \"flex\";\n el.style.alignItems = \"center\";\n el.style.justifyContent = \"center\";\n } else if (normalizedType === \"text\") {\n // Text content from props\n if (props[\"0\"]) {\n el.textContent = String(props[\"0\"]);\n }\n } else if (normalizedType === \"button\") {\n el.style.cursor = \"pointer\";\n } else if (normalizedType === \"checkbox\" || normalizedType === \"switch\") {\n (el as HTMLInputElement).type = \"checkbox\";\n } else if (normalizedType === \"slider\") {\n (el as HTMLInputElement).type = \"range\";\n }\n\n return el;\n}\n\n/**\n * Apply a prop to an element\n */\nfunction applyProp(el: HTMLElement, name: string, value: any): void {\n // Text content\n if (name === \"0\" || name === \"text\") {\n el.textContent = String(value);\n return;\n }\n\n // Style props\n const styleProps: Record<string, string> = {\n padding: \"padding\",\n margin: \"margin\",\n backgroundColor: \"backgroundColor\",\n background: \"background\",\n color: \"color\",\n fontSize: \"fontSize\",\n fontWeight: \"fontWeight\",\n width: \"width\",\n height: \"height\",\n minWidth: \"minWidth\",\n minHeight: \"minHeight\",\n maxWidth: \"maxWidth\",\n maxHeight: \"maxHeight\",\n borderRadius: \"borderRadius\",\n border: \"border\",\n gap: \"gap\",\n flex: \"flex\",\n alignItems: \"alignItems\",\n justifyContent: \"justifyContent\",\n opacity: \"opacity\",\n overflow: \"overflow\",\n };\n\n if (styleProps[name]) {\n const cssValue = typeof value === \"number\" ? `${value}px` : String(value);\n (el.style as any)[styleProps[name]] = cssValue;\n return;\n }\n\n // Event handlers\n if (name === \"onClick\" || name === \"onclick\") {\n el.onclick = () => {\n const engine = (el as any).__hypenEngine as RemoteEngine;\n if (engine && typeof value === \"string\" && value.startsWith(\"@actions.\")) {\n const action = value.replace(\"@actions.\", \"\");\n engine.dispatchAction(action);\n }\n };\n return;\n }\n\n // Other attributes\n el.setAttribute(name, String(value));\n}\n\n/**\n * Disconnect a HypenApp instance\n */\nexport function disconnectHypenApp(element: HTMLElement): void {\n const instance = activeInstances.get(element);\n if (instance) {\n instance.engine.disconnect();\n activeInstances.delete(element);\n }\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "7ED34EBF06ECAF2F64756E2164756E21",
9
+ "names": []
10
+ }
@@ -51,10 +51,26 @@ var exports_row = {};
51
51
  __export(exports_row, {
52
52
  rowHandler: () => rowHandler
53
53
  });
54
- var rowHandler;
54
+ function ensureRowStyles() {
55
+ if (rowStylesInjected)
56
+ return;
57
+ rowStylesInjected = true;
58
+ const style = document.createElement("style");
59
+ style.id = "hypen-row-styles";
60
+ style.textContent = `
61
+ /* Row expands to fill width when it has children with flex/weight */
62
+ /* This matches iOS/Android behavior where weighted children cause parent to expand */
63
+ [data-hypen-type="row"]:has(> [data-hypen-flex]) {
64
+ width: 100%;
65
+ }
66
+ `;
67
+ document.head.appendChild(style);
68
+ }
69
+ var rowStylesInjected = false, rowHandler;
55
70
  var init_row = __esm(() => {
56
71
  rowHandler = {
57
72
  create() {
73
+ ensureRowStyles();
58
74
  const el = document.createElement("div");
59
75
  el.style.display = "flex";
60
76
  el.style.flexDirection = "row";
@@ -76,6 +92,10 @@ var init_text = __esm(() => {
76
92
  create() {
77
93
  const el = document.createElement("span");
78
94
  el.style.display = "inline-block";
95
+ el.style.lineHeight = "1";
96
+ el.style.verticalAlign = "top";
97
+ el.style.margin = "0";
98
+ el.style.padding = "0";
79
99
  el.dataset.hypenType = "text";
80
100
  return el;
81
101
  },
@@ -151,9 +171,6 @@ var init_container = __esm(() => {
151
171
  containerHandler = {
152
172
  create() {
153
173
  const el = document.createElement("div");
154
- el.style.display = "flex";
155
- el.style.flexDirection = "column";
156
- el.style.alignItems = "stretch";
157
174
  el.dataset.hypenType = "container";
158
175
  return el;
159
176
  }
@@ -173,6 +190,9 @@ var init_center = __esm(() => {
173
190
  el.style.display = "flex";
174
191
  el.style.alignItems = "center";
175
192
  el.style.justifyContent = "center";
193
+ el.style.width = "100%";
194
+ el.style.height = "100%";
195
+ el.style.alignSelf = "stretch";
176
196
  el.dataset.hypenType = "center";
177
197
  return el;
178
198
  }
@@ -423,12 +443,16 @@ function ensureStackStyles() {
423
443
  position: relative;
424
444
  display: grid;
425
445
  grid-template-areas: "stack";
446
+ /* Default alignment: top-left (matching iOS/Android ZStack default) */
447
+ justify-items: start;
448
+ align-items: start;
426
449
  /* Ensure Stack participates properly in flex layouts (Row/Column) */
427
450
  min-width: 0;
428
451
  min-height: 0;
429
452
  }
430
453
  [data-hypen-type="stack"] > * {
431
454
  grid-area: stack;
455
+ /* Don't set justify-self/align-self here - let parent's justify-items/align-items control */
432
456
  }
433
457
  `;
434
458
  document.head.appendChild(style);
@@ -482,10 +506,26 @@ var exports_grid = {};
482
506
  __export(exports_grid, {
483
507
  gridHandler: () => gridHandler
484
508
  });
485
- var gridHandler;
509
+ function ensureGridStyles() {
510
+ if (gridStylesInjected)
511
+ return;
512
+ gridStylesInjected = true;
513
+ const style = document.createElement("style");
514
+ style.id = "hypen-grid-styles";
515
+ style.textContent = `
516
+ /* Grid children stretch to fill cells by default (matches Android behavior) */
517
+ [data-hypen-type="grid"] > * {
518
+ justify-self: stretch;
519
+ align-self: stretch;
520
+ }
521
+ `;
522
+ document.head.appendChild(style);
523
+ }
524
+ var gridStylesInjected = false, gridHandler;
486
525
  var init_grid = __esm(() => {
487
526
  gridHandler = {
488
527
  create() {
528
+ ensureGridStyles();
489
529
  const el = document.createElement("div");
490
530
  el.style.display = "grid";
491
531
  el.dataset.hypenType = "grid";
@@ -971,8 +1011,10 @@ var exports_route = {};
971
1011
  __export(exports_route, {
972
1012
  routeHandler: () => routeHandler
973
1013
  });
974
- var routeHandler;
1014
+ import { frameworkLoggers } from "@hypen-space/core";
1015
+ var log, routeHandler;
975
1016
  var init_route = __esm(() => {
1017
+ log = frameworkLoggers.router;
976
1018
  routeHandler = {
977
1019
  create() {
978
1020
  const el = document.createElement("div");
@@ -992,7 +1034,7 @@ var init_route = __esm(() => {
992
1034
  if (componentName) {
993
1035
  el.dataset.routeComponent = String(componentName);
994
1036
  }
995
- console.log(`\uD83D\uDEE3️ Route created: path="${path}", lazy=${isLazy}, component="${el.dataset.routeComponent || "none"}"`);
1037
+ log.debug(`Route created: path="${path}", lazy=${isLazy}, component="${el.dataset.routeComponent || "none"}"`);
996
1038
  }
997
1039
  };
998
1040
  });
@@ -1004,11 +1046,12 @@ __export(exports_hypenapp, {
1004
1046
  disconnectHypenApp: () => disconnectHypenApp
1005
1047
  });
1006
1048
  import { RemoteEngine } from "@hypen-space/core/remote/client";
1049
+ import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core";
1007
1050
  function applyPatches(container, nodes, patches, engine, onRoot) {
1008
1051
  for (const patch of patches) {
1009
1052
  switch (patch.type) {
1010
1053
  case "create": {
1011
- const el = createElement(patch.element_type, patch.props || {});
1054
+ const el = createElement(patch.elementType, patch.props || {});
1012
1055
  el.dataset.hypenId = patch.id;
1013
1056
  el.__hypenEngine = engine;
1014
1057
  nodes.set(patch.id, el);
@@ -1029,10 +1072,10 @@ function applyPatches(container, nodes, patches, engine, onRoot) {
1029
1072
  break;
1030
1073
  }
1031
1074
  case "insert": {
1032
- const parentId = patch.parent_id;
1075
+ const parentId = patch.parentId;
1033
1076
  const parent = parentId === "root" ? container : nodes.get(parentId);
1034
1077
  const child = nodes.get(patch.id);
1035
- const beforeId = patch.before_id;
1078
+ const beforeId = patch.beforeId;
1036
1079
  if (parent && child) {
1037
1080
  if (parentId === "root") {
1038
1081
  onRoot(patch.id);
@@ -1051,10 +1094,10 @@ function applyPatches(container, nodes, patches, engine, onRoot) {
1051
1094
  break;
1052
1095
  }
1053
1096
  case "move": {
1054
- const parentId = patch.parent_id;
1097
+ const parentId = patch.parentId;
1055
1098
  const parent = parentId === "root" ? container : nodes.get(parentId);
1056
1099
  const child = nodes.get(patch.id);
1057
- const beforeId = patch.before_id;
1100
+ const beforeId = patch.beforeId;
1058
1101
  if (parent && child) {
1059
1102
  if (beforeId) {
1060
1103
  const before = nodes.get(beforeId);
@@ -1188,8 +1231,9 @@ function disconnectHypenApp(element) {
1188
1231
  activeInstances.delete(element);
1189
1232
  }
1190
1233
  }
1191
- var activeInstances, hypenAppHandler;
1234
+ var log2, activeInstances, hypenAppHandler;
1192
1235
  var init_hypenapp = __esm(() => {
1236
+ log2 = frameworkLoggers2.remote;
1193
1237
  activeInstances = new WeakMap;
1194
1238
  hypenAppHandler = {
1195
1239
  create() {
@@ -1201,7 +1245,7 @@ var init_hypenapp = __esm(() => {
1201
1245
  applyProps(element, props) {
1202
1246
  const url = props["0"] || props.url;
1203
1247
  if (!url || typeof url !== "string") {
1204
- console.error("[HypenApp] URL is required");
1248
+ log2.error("HypenApp: URL is required");
1205
1249
  element.innerHTML = '<div style="color: red;">HypenApp: URL required</div>';
1206
1250
  return;
1207
1251
  }
@@ -1226,16 +1270,16 @@ var init_hypenapp = __esm(() => {
1226
1270
  element.innerHTML = '<div class="hypen-app-loading">Connecting...</div>';
1227
1271
  engine.connect().then(() => {
1228
1272
  element.innerHTML = "";
1229
- console.log(`[HypenApp] Connected to ${url}`);
1273
+ log2.debug(`HypenApp connected to ${url}`);
1230
1274
  }).catch((error) => {
1231
1275
  element.innerHTML = `<div style="color: red;">HypenApp: Connection failed - ${error.message}</div>`;
1232
- console.error("[HypenApp] Connection failed:", error);
1276
+ log2.error("HypenApp connection failed:", error);
1233
1277
  });
1234
1278
  engine.onDisconnect(() => {
1235
- console.log("[HypenApp] Disconnected");
1279
+ log2.debug("HypenApp disconnected");
1236
1280
  });
1237
1281
  engine.onError((error) => {
1238
- console.error("[HypenApp] Error:", error);
1282
+ log2.error("HypenApp error:", error);
1239
1283
  });
1240
1284
  const observer = new MutationObserver((mutations) => {
1241
1285
  for (const mutation of mutations) {
@@ -1244,7 +1288,7 @@ var init_hypenapp = __esm(() => {
1244
1288
  engine.disconnect();
1245
1289
  activeInstances.delete(element);
1246
1290
  observer.disconnect();
1247
- console.log("[HypenApp] Cleaned up");
1291
+ log2.debug("HypenApp cleaned up");
1248
1292
  return;
1249
1293
  }
1250
1294
  }
@@ -1349,4 +1393,4 @@ export {
1349
1393
  ComponentRegistry
1350
1394
  };
1351
1395
 
1352
- //# debugId=6F6BE7749C39DB8964756E2164756E21
1396
+ //# debugId=E20FF45ABB595CA864756E2164756E21