@number10/jsx-core 5.0.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.
Files changed (340) hide show
  1. package/LICENSE +667 -0
  2. package/README.md +38 -0
  3. package/dist/animation/animated-signal.cjs +19 -0
  4. package/dist/animation/animated-signal.cjs.map +1 -0
  5. package/dist/animation/animated-signal.d.ts +35 -0
  6. package/dist/animation/animated-signal.d.ts.map +1 -0
  7. package/dist/animation/animated-signal.js +19 -0
  8. package/dist/animation/animated-signal.js.map +1 -0
  9. package/dist/animation/create-spring.cjs +80 -0
  10. package/dist/animation/create-spring.cjs.map +1 -0
  11. package/dist/animation/create-spring.d.ts +56 -0
  12. package/dist/animation/create-spring.d.ts.map +1 -0
  13. package/dist/animation/create-spring.js +80 -0
  14. package/dist/animation/create-spring.js.map +1 -0
  15. package/dist/animation/easing.cjs +76 -0
  16. package/dist/animation/easing.cjs.map +1 -0
  17. package/dist/animation/easing.d.ts +45 -0
  18. package/dist/animation/easing.d.ts.map +1 -0
  19. package/dist/animation/easing.js +76 -0
  20. package/dist/animation/easing.js.map +1 -0
  21. package/dist/animation/effect-definitions.cjs +441 -0
  22. package/dist/animation/effect-definitions.cjs.map +1 -0
  23. package/dist/animation/effect-definitions.d.ts +60 -0
  24. package/dist/animation/effect-definitions.d.ts.map +1 -0
  25. package/dist/animation/effect-definitions.js +441 -0
  26. package/dist/animation/effect-definitions.js.map +1 -0
  27. package/dist/animation/effect-engine.cjs +189 -0
  28. package/dist/animation/effect-engine.cjs.map +1 -0
  29. package/dist/animation/effect-engine.d.ts +70 -0
  30. package/dist/animation/effect-engine.d.ts.map +1 -0
  31. package/dist/animation/effect-engine.js +189 -0
  32. package/dist/animation/effect-engine.js.map +1 -0
  33. package/dist/animation/index.d.ts +24 -0
  34. package/dist/animation/index.d.ts.map +1 -0
  35. package/dist/animation/spring-physics.cjs +94 -0
  36. package/dist/animation/spring-physics.cjs.map +1 -0
  37. package/dist/animation/spring-physics.d.ts +145 -0
  38. package/dist/animation/spring-physics.d.ts.map +1 -0
  39. package/dist/animation/spring-physics.js +94 -0
  40. package/dist/animation/spring-physics.js.map +1 -0
  41. package/dist/animation/tween.cjs +67 -0
  42. package/dist/animation/tween.cjs.map +1 -0
  43. package/dist/animation/tween.d.ts +60 -0
  44. package/dist/animation/tween.d.ts.map +1 -0
  45. package/dist/animation/tween.js +67 -0
  46. package/dist/animation/tween.js.map +1 -0
  47. package/dist/animation/types.d.ts +31 -0
  48. package/dist/animation/types.d.ts.map +1 -0
  49. package/dist/animation/useSpring.cjs +152 -0
  50. package/dist/animation/useSpring.cjs.map +1 -0
  51. package/dist/animation/useSpring.d.ts +55 -0
  52. package/dist/animation/useSpring.d.ts.map +1 -0
  53. package/dist/animation/useSpring.js +149 -0
  54. package/dist/animation/useSpring.js.map +1 -0
  55. package/dist/animation/useTween.cjs +208 -0
  56. package/dist/animation/useTween.cjs.map +1 -0
  57. package/dist/animation/useTween.d.ts +116 -0
  58. package/dist/animation/useTween.d.ts.map +1 -0
  59. package/dist/animation/useTween.js +208 -0
  60. package/dist/animation/useTween.js.map +1 -0
  61. package/dist/border-geometry.cjs +447 -0
  62. package/dist/border-geometry.cjs.map +1 -0
  63. package/dist/border-geometry.d.ts +114 -0
  64. package/dist/border-geometry.d.ts.map +1 -0
  65. package/dist/border-geometry.js +447 -0
  66. package/dist/border-geometry.js.map +1 -0
  67. package/dist/colors/color-presets.cjs +236 -0
  68. package/dist/colors/color-presets.cjs.map +1 -0
  69. package/dist/colors/color-presets.d.ts +89 -0
  70. package/dist/colors/color-presets.d.ts.map +1 -0
  71. package/dist/colors/color-presets.js +236 -0
  72. package/dist/colors/color-presets.js.map +1 -0
  73. package/dist/colors/color-theme-helpers.cjs +32 -0
  74. package/dist/colors/color-theme-helpers.cjs.map +1 -0
  75. package/dist/colors/color-theme-helpers.d.ts +65 -0
  76. package/dist/colors/color-theme-helpers.d.ts.map +1 -0
  77. package/dist/colors/color-theme-helpers.js +32 -0
  78. package/dist/colors/color-theme-helpers.js.map +1 -0
  79. package/dist/colors/color-types.cjs +38 -0
  80. package/dist/colors/color-types.cjs.map +1 -0
  81. package/dist/colors/color-types.d.ts +112 -0
  82. package/dist/colors/color-types.d.ts.map +1 -0
  83. package/dist/colors/color-types.js +38 -0
  84. package/dist/colors/color-types.js.map +1 -0
  85. package/dist/colors/color-utils.cjs +197 -0
  86. package/dist/colors/color-utils.cjs.map +1 -0
  87. package/dist/colors/color-utils.d.ts +216 -0
  88. package/dist/colors/color-utils.d.ts.map +1 -0
  89. package/dist/colors/color-utils.js +197 -0
  90. package/dist/colors/color-utils.js.map +1 -0
  91. package/dist/colors/contrast-contracts.cjs +265 -0
  92. package/dist/colors/contrast-contracts.cjs.map +1 -0
  93. package/dist/colors/contrast-contracts.d.ts +289 -0
  94. package/dist/colors/contrast-contracts.d.ts.map +1 -0
  95. package/dist/colors/contrast-contracts.js +265 -0
  96. package/dist/colors/contrast-contracts.js.map +1 -0
  97. package/dist/colors/index.cjs +55 -0
  98. package/dist/colors/index.cjs.map +1 -0
  99. package/dist/colors/index.d.ts +16 -0
  100. package/dist/colors/index.d.ts.map +1 -0
  101. package/dist/colors/index.js +55 -0
  102. package/dist/colors/index.js.map +1 -0
  103. package/dist/core-props.cjs +66 -0
  104. package/dist/core-props.cjs.map +1 -0
  105. package/dist/core-props.d.ts +395 -0
  106. package/dist/core-props.d.ts.map +1 -0
  107. package/dist/core-props.js +66 -0
  108. package/dist/core-props.js.map +1 -0
  109. package/dist/design-tokens/design-token-presets.cjs +91 -0
  110. package/dist/design-tokens/design-token-presets.cjs.map +1 -0
  111. package/dist/design-tokens/design-token-presets.d.ts +34 -0
  112. package/dist/design-tokens/design-token-presets.d.ts.map +1 -0
  113. package/dist/design-tokens/design-token-presets.js +91 -0
  114. package/dist/design-tokens/design-token-presets.js.map +1 -0
  115. package/dist/design-tokens/design-token-types.d.ts +97 -0
  116. package/dist/design-tokens/design-token-types.d.ts.map +1 -0
  117. package/dist/design-tokens/index.cjs +10 -0
  118. package/dist/design-tokens/index.cjs.map +1 -0
  119. package/dist/design-tokens/index.d.ts +9 -0
  120. package/dist/design-tokens/index.d.ts.map +1 -0
  121. package/dist/design-tokens/index.js +10 -0
  122. package/dist/design-tokens/index.js.map +1 -0
  123. package/dist/dev-config.cjs +296 -0
  124. package/dist/dev-config.cjs.map +1 -0
  125. package/dist/dev-config.d.ts +238 -0
  126. package/dist/dev-config.d.ts.map +1 -0
  127. package/dist/dev-config.js +296 -0
  128. package/dist/dev-config.js.map +1 -0
  129. package/dist/effects.cjs +69 -0
  130. package/dist/effects.cjs.map +1 -0
  131. package/dist/effects.d.ts +152 -0
  132. package/dist/effects.d.ts.map +1 -0
  133. package/dist/effects.js +69 -0
  134. package/dist/effects.js.map +1 -0
  135. package/dist/global-registry.cjs +25 -0
  136. package/dist/global-registry.cjs.map +1 -0
  137. package/dist/global-registry.d.ts +19 -0
  138. package/dist/global-registry.d.ts.map +1 -0
  139. package/dist/global-registry.js +25 -0
  140. package/dist/global-registry.js.map +1 -0
  141. package/dist/hooks.cjs +378 -0
  142. package/dist/hooks.cjs.map +1 -0
  143. package/dist/hooks.d.ts +322 -0
  144. package/dist/hooks.d.ts.map +1 -0
  145. package/dist/hooks.js +378 -0
  146. package/dist/hooks.js.map +1 -0
  147. package/dist/host-adapter.d.ts +414 -0
  148. package/dist/host-adapter.d.ts.map +1 -0
  149. package/dist/index.cjs +229 -0
  150. package/dist/index.cjs.map +1 -0
  151. package/dist/index.d.ts +32 -0
  152. package/dist/index.d.ts.map +1 -0
  153. package/dist/index.js +226 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/jsx-dev-runtime.cjs +10 -0
  156. package/dist/jsx-dev-runtime.cjs.map +1 -0
  157. package/dist/jsx-dev-runtime.d.ts +5 -0
  158. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  159. package/dist/jsx-dev-runtime.js +11 -0
  160. package/dist/jsx-dev-runtime.js.map +1 -0
  161. package/dist/jsx-runtime.cjs +44 -0
  162. package/dist/jsx-runtime.cjs.map +1 -0
  163. package/dist/jsx-runtime.d.ts +24 -0
  164. package/dist/jsx-runtime.d.ts.map +1 -0
  165. package/dist/jsx-runtime.js +44 -0
  166. package/dist/jsx-runtime.js.map +1 -0
  167. package/dist/jsx-types.d.ts +25 -0
  168. package/dist/jsx-types.d.ts.map +1 -0
  169. package/dist/layout/appliers/container-applier.cjs +20 -0
  170. package/dist/layout/appliers/container-applier.cjs.map +1 -0
  171. package/dist/layout/appliers/container-applier.d.ts +9 -0
  172. package/dist/layout/appliers/container-applier.d.ts.map +1 -0
  173. package/dist/layout/appliers/container-applier.js +20 -0
  174. package/dist/layout/appliers/container-applier.js.map +1 -0
  175. package/dist/layout/appliers/position-applier.cjs +31 -0
  176. package/dist/layout/appliers/position-applier.cjs.map +1 -0
  177. package/dist/layout/appliers/position-applier.d.ts +8 -0
  178. package/dist/layout/appliers/position-applier.d.ts.map +1 -0
  179. package/dist/layout/appliers/position-applier.js +31 -0
  180. package/dist/layout/appliers/position-applier.js.map +1 -0
  181. package/dist/layout/layout-engine-test-utils.d.ts +26 -0
  182. package/dist/layout/layout-engine-test-utils.d.ts.map +1 -0
  183. package/dist/layout/layout-engine.cjs +628 -0
  184. package/dist/layout/layout-engine.cjs.map +1 -0
  185. package/dist/layout/layout-engine.d.ts +140 -0
  186. package/dist/layout/layout-engine.d.ts.map +1 -0
  187. package/dist/layout/layout-engine.js +628 -0
  188. package/dist/layout/layout-engine.js.map +1 -0
  189. package/dist/layout/strategies/base-strategy.cjs +31 -0
  190. package/dist/layout/strategies/base-strategy.cjs.map +1 -0
  191. package/dist/layout/strategies/base-strategy.d.ts +59 -0
  192. package/dist/layout/strategies/base-strategy.d.ts.map +1 -0
  193. package/dist/layout/strategies/base-strategy.js +31 -0
  194. package/dist/layout/strategies/base-strategy.js.map +1 -0
  195. package/dist/layout/strategies/column-layout.cjs +145 -0
  196. package/dist/layout/strategies/column-layout.cjs.map +1 -0
  197. package/dist/layout/strategies/column-layout.d.ts +38 -0
  198. package/dist/layout/strategies/column-layout.d.ts.map +1 -0
  199. package/dist/layout/strategies/column-layout.js +145 -0
  200. package/dist/layout/strategies/column-layout.js.map +1 -0
  201. package/dist/layout/strategies/row-layout.cjs +145 -0
  202. package/dist/layout/strategies/row-layout.cjs.map +1 -0
  203. package/dist/layout/strategies/row-layout.d.ts +38 -0
  204. package/dist/layout/strategies/row-layout.d.ts.map +1 -0
  205. package/dist/layout/strategies/row-layout.js +145 -0
  206. package/dist/layout/strategies/row-layout.js.map +1 -0
  207. package/dist/layout/strategies/stack-layout.cjs +94 -0
  208. package/dist/layout/strategies/stack-layout.cjs.map +1 -0
  209. package/dist/layout/strategies/stack-layout.d.ts +30 -0
  210. package/dist/layout/strategies/stack-layout.d.ts.map +1 -0
  211. package/dist/layout/strategies/stack-layout.js +94 -0
  212. package/dist/layout/strategies/stack-layout.js.map +1 -0
  213. package/dist/layout/types.d.ts +134 -0
  214. package/dist/layout/types.d.ts.map +1 -0
  215. package/dist/layout/utils/child-utils.cjs +129 -0
  216. package/dist/layout/utils/child-utils.cjs.map +1 -0
  217. package/dist/layout/utils/child-utils.d.ts +54 -0
  218. package/dist/layout/utils/child-utils.d.ts.map +1 -0
  219. package/dist/layout/utils/child-utils.js +129 -0
  220. package/dist/layout/utils/child-utils.js.map +1 -0
  221. package/dist/layout/utils/dimension-calculator.cjs +109 -0
  222. package/dist/layout/utils/dimension-calculator.cjs.map +1 -0
  223. package/dist/layout/utils/dimension-calculator.d.ts +59 -0
  224. package/dist/layout/utils/dimension-calculator.d.ts.map +1 -0
  225. package/dist/layout/utils/dimension-calculator.js +109 -0
  226. package/dist/layout/utils/dimension-calculator.js.map +1 -0
  227. package/dist/layout/utils/flex-distributor.cjs +173 -0
  228. package/dist/layout/utils/flex-distributor.cjs.map +1 -0
  229. package/dist/layout/utils/flex-distributor.d.ts +18 -0
  230. package/dist/layout/utils/flex-distributor.d.ts.map +1 -0
  231. package/dist/layout/utils/flex-distributor.js +173 -0
  232. package/dist/layout/utils/flex-distributor.js.map +1 -0
  233. package/dist/layout/utils/size-resolver.cjs +280 -0
  234. package/dist/layout/utils/size-resolver.cjs.map +1 -0
  235. package/dist/layout/utils/size-resolver.d.ts +84 -0
  236. package/dist/layout/utils/size-resolver.d.ts.map +1 -0
  237. package/dist/layout/utils/size-resolver.js +280 -0
  238. package/dist/layout/utils/size-resolver.js.map +1 -0
  239. package/dist/layout/utils/spacing-calculator.cjs +50 -0
  240. package/dist/layout/utils/spacing-calculator.cjs.map +1 -0
  241. package/dist/layout/utils/spacing-calculator.d.ts +27 -0
  242. package/dist/layout/utils/spacing-calculator.d.ts.map +1 -0
  243. package/dist/layout/utils/spacing-calculator.js +50 -0
  244. package/dist/layout/utils/spacing-calculator.js.map +1 -0
  245. package/dist/memo.cjs +18 -0
  246. package/dist/memo.cjs.map +1 -0
  247. package/dist/memo.d.ts +29 -0
  248. package/dist/memo.d.ts.map +1 -0
  249. package/dist/memo.js +18 -0
  250. package/dist/memo.js.map +1 -0
  251. package/dist/nineslice-contract.cjs +60 -0
  252. package/dist/nineslice-contract.cjs.map +1 -0
  253. package/dist/nineslice-contract.d.ts +107 -0
  254. package/dist/nineslice-contract.d.ts.map +1 -0
  255. package/dist/nineslice-contract.js +60 -0
  256. package/dist/nineslice-contract.js.map +1 -0
  257. package/dist/placeholder.cjs +12 -0
  258. package/dist/placeholder.cjs.map +1 -0
  259. package/dist/placeholder.d.ts +44 -0
  260. package/dist/placeholder.d.ts.map +1 -0
  261. package/dist/placeholder.js +12 -0
  262. package/dist/placeholder.js.map +1 -0
  263. package/dist/portal.cjs +89 -0
  264. package/dist/portal.cjs.map +1 -0
  265. package/dist/portal.d.ts +62 -0
  266. package/dist/portal.d.ts.map +1 -0
  267. package/dist/portal.js +89 -0
  268. package/dist/portal.js.map +1 -0
  269. package/dist/primitive-contracts.cjs +12 -0
  270. package/dist/primitive-contracts.cjs.map +1 -0
  271. package/dist/primitive-contracts.d.ts +186 -0
  272. package/dist/primitive-contracts.d.ts.map +1 -0
  273. package/dist/primitive-contracts.js +12 -0
  274. package/dist/primitive-contracts.js.map +1 -0
  275. package/dist/theme.cjs +332 -0
  276. package/dist/theme.cjs.map +1 -0
  277. package/dist/theme.d.ts +204 -0
  278. package/dist/theme.d.ts.map +1 -0
  279. package/dist/theme.js +332 -0
  280. package/dist/theme.js.map +1 -0
  281. package/dist/types.d.ts +86 -0
  282. package/dist/types.d.ts.map +1 -0
  283. package/dist/vdom/create-runtime.cjs +79 -0
  284. package/dist/vdom/create-runtime.cjs.map +1 -0
  285. package/dist/vdom/create-runtime.d.ts +7 -0
  286. package/dist/vdom/create-runtime.d.ts.map +1 -0
  287. package/dist/vdom/create-runtime.js +79 -0
  288. package/dist/vdom/create-runtime.js.map +1 -0
  289. package/dist/vdom/index.cjs +8 -0
  290. package/dist/vdom/index.cjs.map +1 -0
  291. package/dist/vdom/index.d.ts +4 -0
  292. package/dist/vdom/index.d.ts.map +1 -0
  293. package/dist/vdom/index.js +8 -0
  294. package/dist/vdom/index.js.map +1 -0
  295. package/dist/vdom/mount.cjs +161 -0
  296. package/dist/vdom/mount.cjs.map +1 -0
  297. package/dist/vdom/mount.d.ts +6 -0
  298. package/dist/vdom/mount.d.ts.map +1 -0
  299. package/dist/vdom/mount.js +161 -0
  300. package/dist/vdom/mount.js.map +1 -0
  301. package/dist/vdom/patch.cjs +163 -0
  302. package/dist/vdom/patch.cjs.map +1 -0
  303. package/dist/vdom/patch.d.ts +3 -0
  304. package/dist/vdom/patch.d.ts.map +1 -0
  305. package/dist/vdom/patch.js +163 -0
  306. package/dist/vdom/patch.js.map +1 -0
  307. package/dist/vdom/registry.cjs +85 -0
  308. package/dist/vdom/registry.cjs.map +1 -0
  309. package/dist/vdom/registry.d.ts +28 -0
  310. package/dist/vdom/registry.d.ts.map +1 -0
  311. package/dist/vdom/registry.js +85 -0
  312. package/dist/vdom/registry.js.map +1 -0
  313. package/dist/vdom/runtime-helpers.cjs +23 -0
  314. package/dist/vdom/runtime-helpers.cjs.map +1 -0
  315. package/dist/vdom/runtime-helpers.d.ts +8 -0
  316. package/dist/vdom/runtime-helpers.d.ts.map +1 -0
  317. package/dist/vdom/runtime-helpers.js +23 -0
  318. package/dist/vdom/runtime-helpers.js.map +1 -0
  319. package/dist/vdom/surface.cjs +107 -0
  320. package/dist/vdom/surface.cjs.map +1 -0
  321. package/dist/vdom/surface.d.ts +9 -0
  322. package/dist/vdom/surface.d.ts.map +1 -0
  323. package/dist/vdom/surface.js +107 -0
  324. package/dist/vdom/surface.js.map +1 -0
  325. package/dist/vdom/types.d.ts +104 -0
  326. package/dist/vdom/types.d.ts.map +1 -0
  327. package/dist/vdom/utils.cjs +146 -0
  328. package/dist/vdom/utils.cjs.map +1 -0
  329. package/dist/vdom/utils.d.ts +24 -0
  330. package/dist/vdom/utils.d.ts.map +1 -0
  331. package/dist/vdom/utils.js +146 -0
  332. package/dist/vdom/utils.js.map +1 -0
  333. package/dist/vdom.d.ts +4 -0
  334. package/dist/vdom.d.ts.map +1 -0
  335. package/dist/vector-draw-context.d.ts +63 -0
  336. package/dist/vector-draw-context.d.ts.map +1 -0
  337. package/package.json +161 -0
  338. package/vdom/index.cjs +1 -0
  339. package/vdom/index.d.ts +1 -0
  340. package/vdom/index.js +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"column-layout.js","sources":["../../../src/layout/strategies/column-layout.ts"],"sourcesContent":["/**\n * Column layout strategy (vertical stacking)\n * Like SwiftUI's VStack\n */\nimport type { LayoutChild, LayoutContext, LayoutLine, Position } from '../types'\nimport type { ContentMetrics } from '../utils/dimension-calculator'\nimport { parseSize, resolveSize } from '../utils/size-resolver'\nimport { calculateAlignItems } from '../utils/spacing-calculator'\nimport { BaseLayoutStrategy } from './base-strategy'\n\n/**\n * Column layout strategy - stacks children vertically\n */\nexport class ColumnLayoutStrategy extends BaseLayoutStrategy {\n /**\n * Calculate content dimensions for column layout\n * For flex children, uses a minimum default size to avoid chicken-egg sizing issues\n * @param children - Array of layout children\n * @param context - Layout context\n * @returns Content metrics\n */\n calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics {\n const FLEX_CHILD_MIN_SIZE = 100 // Minimum size for flex children in content calculation\n let maxWidth = 0\n let totalMainSize = 0\n\n for (const child of children) {\n const total = this.getTotalChildSize(child)\n maxWidth = Math.max(maxWidth, total.width)\n\n // Check if this child participates in flexbox (flex, flexShrink, or flexBasis)\n const props = child.child.__layoutProps\n const isFlexItem =\n (props?.flex !== undefined && props.flex > 0) ||\n props?.flexShrink !== undefined ||\n props?.flexBasis !== undefined\n // If flex child already has a resolved size (> 10), use it; otherwise use minimum\n const childHeight = isFlexItem && child.size.height <= 10 ? FLEX_CHILD_MIN_SIZE : total.height\n\n totalMainSize += childHeight\n }\n\n return {\n maxWidth,\n maxHeight: 0, // Not used for column\n totalMainSize,\n }\n }\n\n /**\n * Position a child in column layout\n * @param child - Layout child\n * @param _index - Child index (unused for column layout)\n * @param context - Layout context\n * @param currentMain - Current Y position\n * @returns Position and next main axis value\n */\n positionChild(\n child: LayoutChild,\n _index: number,\n context: LayoutContext,\n currentMain: number\n ): { position: Position; nextMain: number } {\n const margin = this.getMarginValues(child)\n const isHeadless = child.child.__layoutProps?.headless\n\n let x: number\n let y: number\n let nextMain: number\n\n if (isHeadless) {\n // Headless: calculate position directly using alignItems/justifyContent on full parent size\n const parentWidth = context.parentSize?.width ?? context.contentArea.width\n const parentHeight = context.parentSize?.height ?? context.contentArea.height\n\n // justifyContent on main axis (vertical) - manual calculation\n const justify = context.containerProps.justifyContent ?? 'start'\n let mainAxisOffset = 0\n if (justify === 'center') {\n mainAxisOffset = (parentHeight - child.size.height) / 2\n } else if (justify === 'end') {\n mainAxisOffset = parentHeight - child.size.height\n }\n // start and space-* variants use 0 for single item\n y = mainAxisOffset\n\n // alignItems on cross axis (horizontal)\n const crossAxisOffset = calculateAlignItems(\n context.containerProps.alignItems,\n parentWidth,\n child.size.width,\n 0,\n 0\n )\n x = crossAxisOffset\n\n // Don't advance currentMain for headless (they don't participate in flow)\n nextMain = currentMain\n } else {\n // Normal: use container padding and contentArea\n currentMain += margin.top\n y = context.padding.top + currentMain\n\n const alignOffset = calculateAlignItems(\n context.containerProps.alignItems,\n context.contentArea.width,\n child.size.width,\n margin.left,\n margin.right\n )\n x = context.padding.left + alignOffset\n\n nextMain = currentMain + child.size.height + margin.bottom\n }\n\n return {\n position: { x, y },\n nextMain,\n }\n }\n\n /**\n * Wrap children into lines based on available height\n * Used when flexWrap is 'wrap' or 'wrap-reverse'\n * @param children - Layout children to wrap\n * @param availableHeight - Available height for each line\n * @param gap - Gap between children\n * @returns Array of layout lines\n */\n wrapChildren(children: LayoutChild[], availableHeight: number, gap: number): LayoutLine[] {\n const lines: LayoutLine[] = []\n let currentLine: LayoutChild[] = []\n let currentLineHeight = 0\n let currentLineWidth = 0\n\n for (const child of children) {\n // Skip headless children in wrapping calculation\n if (child.child.__layoutProps?.headless) {\n continue\n }\n\n const margin = this.getMarginValues(child)\n const props = child.child.__layoutProps\n\n // For flex items with no size, use flexBasis or minHeight as hint for wrapping\n let effectiveHeight = child.size.height\n if (effectiveHeight <= 0 && props) {\n if (props.flexBasis !== undefined && typeof props.flexBasis === 'number') {\n effectiveHeight = props.flexBasis\n } else if (props.minHeight !== undefined) {\n // Resolve minHeight SizeValue to number\n const parsed = parseSize(props.minHeight)\n effectiveHeight = resolveSize(parsed, availableHeight, 100, undefined)\n } else if (props.flex && props.flex > 0) {\n // Use a reasonable default for flex items with no size hint\n effectiveHeight = 100\n }\n }\n\n const childHeight = effectiveHeight + margin.top + margin.bottom\n const childWidth = child.size.width + margin.left + margin.right\n\n const gapSpace = currentLine.length > 0 ? gap : 0\n const requiredSpace = currentLineHeight + childHeight + gapSpace\n\n // Check if we need to wrap to a new line (column)\n if (requiredSpace > availableHeight && currentLine.length > 0) {\n // Save current line\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineHeight,\n crossAxisSize: currentLineWidth,\n })\n\n // Start new line\n currentLine = [child]\n currentLineHeight = childHeight\n currentLineWidth = childWidth\n } else {\n // Add to current line\n currentLine.push(child)\n currentLineHeight = requiredSpace\n currentLineWidth = Math.max(currentLineWidth, childWidth)\n }\n }\n\n // Add remaining line\n if (currentLine.length > 0) {\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineHeight,\n crossAxisSize: currentLineWidth,\n })\n }\n\n return lines\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const sizeResolver = require("../utils/size-resolver.cjs");
4
+ const spacingCalculator = require("../utils/spacing-calculator.cjs");
5
+ const baseStrategy = require("./base-strategy.cjs");
6
+ class RowLayoutStrategy extends baseStrategy.BaseLayoutStrategy {
7
+ /**
8
+ * Calculate content dimensions for row layout
9
+ * For flex children, uses a minimum default size to avoid chicken-egg sizing issues
10
+ * @param children - Array of layout children
11
+ * @param context - Layout context
12
+ * @returns Content metrics
13
+ */
14
+ calculateMetrics(children, _context) {
15
+ const FLEX_CHILD_MIN_SIZE = 100;
16
+ let maxHeight = 0;
17
+ let totalMainSize = 0;
18
+ for (const child of children) {
19
+ const total = this.getTotalChildSize(child);
20
+ maxHeight = Math.max(maxHeight, total.height);
21
+ const props = child.child.__layoutProps;
22
+ const isFlexItem = props?.flex !== void 0 && props.flex > 0 || props?.flexShrink !== void 0 || props?.flexBasis !== void 0;
23
+ const childWidth = isFlexItem && child.size.width <= 10 ? FLEX_CHILD_MIN_SIZE : total.width;
24
+ totalMainSize += childWidth;
25
+ }
26
+ return {
27
+ maxWidth: 0,
28
+ // Not used for row
29
+ maxHeight,
30
+ totalMainSize
31
+ };
32
+ }
33
+ /**
34
+ * Position a child in row layout
35
+ * @param child - Layout child
36
+ * @param _index - Child index (unused for row layout)
37
+ * @param context - Layout context
38
+ * @param currentMain - Current X position
39
+ * @returns Position and next main axis value
40
+ */
41
+ positionChild(child, _index, context, currentMain) {
42
+ const margin = this.getMarginValues(child);
43
+ const isHeadless = child.child.__layoutProps?.headless;
44
+ let x;
45
+ let y;
46
+ let nextMain;
47
+ if (isHeadless) {
48
+ const parentWidth = context.parentSize?.width ?? context.contentArea.width;
49
+ const parentHeight = context.parentSize?.height ?? context.contentArea.height;
50
+ const justify = context.containerProps.justifyContent ?? "start";
51
+ let mainAxisOffset = 0;
52
+ if (justify === "center") {
53
+ mainAxisOffset = (parentWidth - child.size.width) / 2;
54
+ } else if (justify === "end") {
55
+ mainAxisOffset = parentWidth - child.size.width;
56
+ }
57
+ x = mainAxisOffset;
58
+ const crossAxisOffset = spacingCalculator.calculateAlignItems(
59
+ context.containerProps.alignItems,
60
+ parentHeight,
61
+ child.size.height,
62
+ 0,
63
+ 0
64
+ );
65
+ y = crossAxisOffset;
66
+ nextMain = currentMain;
67
+ } else {
68
+ currentMain += margin.left;
69
+ x = context.padding.left + currentMain;
70
+ const alignOffset = spacingCalculator.calculateAlignItems(
71
+ context.containerProps.alignItems,
72
+ context.contentArea.height,
73
+ child.size.height,
74
+ margin.top,
75
+ margin.bottom
76
+ );
77
+ y = context.padding.top + alignOffset;
78
+ nextMain = currentMain + child.size.width + margin.right;
79
+ }
80
+ return {
81
+ position: { x, y },
82
+ nextMain
83
+ };
84
+ }
85
+ /**
86
+ * Wrap children into lines based on available width
87
+ * Used when flexWrap is 'wrap' or 'wrap-reverse'
88
+ * @param children - Layout children to wrap
89
+ * @param availableWidth - Available width for each line
90
+ * @param gap - Gap between children
91
+ * @returns Array of layout lines
92
+ */
93
+ wrapChildren(children, availableWidth, gap) {
94
+ const lines = [];
95
+ let currentLine = [];
96
+ let currentLineWidth = 0;
97
+ let currentLineHeight = 0;
98
+ for (const child of children) {
99
+ if (child.child.__layoutProps?.headless) {
100
+ continue;
101
+ }
102
+ const margin = this.getMarginValues(child);
103
+ const props = child.child.__layoutProps;
104
+ let effectiveWidth = child.size.width;
105
+ if (effectiveWidth <= 0 && props) {
106
+ if (props.flexBasis !== void 0 && typeof props.flexBasis === "number") {
107
+ effectiveWidth = props.flexBasis;
108
+ } else if (props.minWidth !== void 0) {
109
+ const parsed = sizeResolver.parseSize(props.minWidth);
110
+ effectiveWidth = sizeResolver.resolveSize(parsed, availableWidth, 100, void 0);
111
+ } else if (props.flex && props.flex > 0) {
112
+ effectiveWidth = 100;
113
+ }
114
+ }
115
+ const childWidth = effectiveWidth + margin.left + margin.right;
116
+ const childHeight = child.size.height + margin.top + margin.bottom;
117
+ const gapSpace = currentLine.length > 0 ? gap : 0;
118
+ const requiredSpace = currentLineWidth + childWidth + gapSpace;
119
+ if (requiredSpace > availableWidth && currentLine.length > 0) {
120
+ lines.push({
121
+ children: currentLine,
122
+ mainAxisSize: currentLineWidth,
123
+ crossAxisSize: currentLineHeight
124
+ });
125
+ currentLine = [child];
126
+ currentLineWidth = childWidth;
127
+ currentLineHeight = childHeight;
128
+ } else {
129
+ currentLine.push(child);
130
+ currentLineWidth = requiredSpace;
131
+ currentLineHeight = Math.max(currentLineHeight, childHeight);
132
+ }
133
+ }
134
+ if (currentLine.length > 0) {
135
+ lines.push({
136
+ children: currentLine,
137
+ mainAxisSize: currentLineWidth,
138
+ crossAxisSize: currentLineHeight
139
+ });
140
+ }
141
+ return lines;
142
+ }
143
+ }
144
+ exports.RowLayoutStrategy = RowLayoutStrategy;
145
+ //# sourceMappingURL=row-layout.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-layout.cjs","sources":["../../../src/layout/strategies/row-layout.ts"],"sourcesContent":["/**\n * Row layout strategy (horizontal stacking)\n * Like SwiftUI's HStack\n */\nimport type { LayoutChild, LayoutContext, LayoutLine, Position } from '../types'\nimport type { ContentMetrics } from '../utils/dimension-calculator'\nimport { parseSize, resolveSize } from '../utils/size-resolver'\nimport { calculateAlignItems } from '../utils/spacing-calculator'\nimport { BaseLayoutStrategy } from './base-strategy'\n\n/**\n * Row layout strategy - stacks children horizontally\n */\nexport class RowLayoutStrategy extends BaseLayoutStrategy {\n /**\n * Calculate content dimensions for row layout\n * For flex children, uses a minimum default size to avoid chicken-egg sizing issues\n * @param children - Array of layout children\n * @param context - Layout context\n * @returns Content metrics\n */\n calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics {\n const FLEX_CHILD_MIN_SIZE = 100 // Minimum size for flex children in content calculation\n let maxHeight = 0\n let totalMainSize = 0\n\n for (const child of children) {\n const total = this.getTotalChildSize(child)\n maxHeight = Math.max(maxHeight, total.height)\n\n // Check if this child participates in flexbox (flex, flexShrink, or flexBasis)\n const props = child.child.__layoutProps\n const isFlexItem =\n (props?.flex !== undefined && props.flex > 0) ||\n props?.flexShrink !== undefined ||\n props?.flexBasis !== undefined\n // If flex child already has a resolved size (> 10), use it; otherwise use minimum\n const childWidth = isFlexItem && child.size.width <= 10 ? FLEX_CHILD_MIN_SIZE : total.width\n\n totalMainSize += childWidth\n }\n\n return {\n maxWidth: 0, // Not used for row\n maxHeight,\n totalMainSize,\n }\n }\n\n /**\n * Position a child in row layout\n * @param child - Layout child\n * @param _index - Child index (unused for row layout)\n * @param context - Layout context\n * @param currentMain - Current X position\n * @returns Position and next main axis value\n */\n positionChild(\n child: LayoutChild,\n _index: number,\n context: LayoutContext,\n currentMain: number\n ): { position: Position; nextMain: number } {\n const margin = this.getMarginValues(child)\n const isHeadless = child.child.__layoutProps?.headless\n\n let x: number\n let y: number\n let nextMain: number\n\n if (isHeadless) {\n // Headless: calculate position directly using alignItems/justifyContent on full parent size\n const parentWidth = context.parentSize?.width ?? context.contentArea.width\n const parentHeight = context.parentSize?.height ?? context.contentArea.height\n\n // justifyContent on main axis (horizontal)\n const justify = context.containerProps.justifyContent ?? 'start'\n let mainAxisOffset = 0\n if (justify === 'center') {\n mainAxisOffset = (parentWidth - child.size.width) / 2\n } else if (justify === 'end') {\n mainAxisOffset = parentWidth - child.size.width\n }\n x = mainAxisOffset\n\n // alignItems on cross axis (vertical)\n const crossAxisOffset = calculateAlignItems(\n context.containerProps.alignItems,\n parentHeight,\n child.size.height,\n 0,\n 0\n )\n y = crossAxisOffset\n\n // Don't advance currentMain for headless\n nextMain = currentMain\n } else {\n // Normal: use container padding and contentArea\n currentMain += margin.left\n x = context.padding.left + currentMain\n\n const alignOffset = calculateAlignItems(\n context.containerProps.alignItems,\n context.contentArea.height,\n child.size.height,\n margin.top,\n margin.bottom\n )\n y = context.padding.top + alignOffset\n\n nextMain = currentMain + child.size.width + margin.right\n }\n\n return {\n position: { x, y },\n nextMain,\n }\n }\n\n /**\n * Wrap children into lines based on available width\n * Used when flexWrap is 'wrap' or 'wrap-reverse'\n * @param children - Layout children to wrap\n * @param availableWidth - Available width for each line\n * @param gap - Gap between children\n * @returns Array of layout lines\n */\n wrapChildren(children: LayoutChild[], availableWidth: number, gap: number): LayoutLine[] {\n const lines: LayoutLine[] = []\n let currentLine: LayoutChild[] = []\n let currentLineWidth = 0\n let currentLineHeight = 0\n\n for (const child of children) {\n // Skip headless children in wrapping calculation\n if (child.child.__layoutProps?.headless) {\n continue\n }\n\n const margin = this.getMarginValues(child)\n const props = child.child.__layoutProps\n\n // For flex items with no size, use flexBasis or minWidth as hint for wrapping\n let effectiveWidth = child.size.width\n if (effectiveWidth <= 0 && props) {\n if (props.flexBasis !== undefined && typeof props.flexBasis === 'number') {\n effectiveWidth = props.flexBasis\n } else if (props.minWidth !== undefined) {\n // Resolve minWidth SizeValue to number\n const parsed = parseSize(props.minWidth)\n effectiveWidth = resolveSize(parsed, availableWidth, 100, undefined)\n } else if (props.flex && props.flex > 0) {\n // Use a reasonable default for flex items with no size hint\n effectiveWidth = 100\n }\n }\n\n const childWidth = effectiveWidth + margin.left + margin.right\n const childHeight = child.size.height + margin.top + margin.bottom\n\n const gapSpace = currentLine.length > 0 ? gap : 0\n const requiredSpace = currentLineWidth + childWidth + gapSpace\n\n // Check if we need to wrap to a new line\n if (requiredSpace > availableWidth && currentLine.length > 0) {\n // Save current line\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineWidth,\n crossAxisSize: currentLineHeight,\n })\n\n // Start new line\n currentLine = [child]\n currentLineWidth = childWidth\n currentLineHeight = childHeight\n } else {\n // Add to current line\n currentLine.push(child)\n currentLineWidth = requiredSpace\n currentLineHeight = Math.max(currentLineHeight, childHeight)\n }\n }\n\n // Add remaining line\n if (currentLine.length > 0) {\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineWidth,\n crossAxisSize: currentLineHeight,\n })\n }\n\n return lines\n }\n}\n"],"names":["BaseLayoutStrategy","calculateAlignItems","parseSize","resolveSize"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { LayoutChild, LayoutContext, LayoutLine, Position } from '../types';
2
+ import { ContentMetrics } from '../utils/dimension-calculator';
3
+ import { BaseLayoutStrategy } from './base-strategy';
4
+ /**
5
+ * Row layout strategy - stacks children horizontally
6
+ */
7
+ export declare class RowLayoutStrategy extends BaseLayoutStrategy {
8
+ /**
9
+ * Calculate content dimensions for row layout
10
+ * For flex children, uses a minimum default size to avoid chicken-egg sizing issues
11
+ * @param children - Array of layout children
12
+ * @param context - Layout context
13
+ * @returns Content metrics
14
+ */
15
+ calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics;
16
+ /**
17
+ * Position a child in row layout
18
+ * @param child - Layout child
19
+ * @param _index - Child index (unused for row layout)
20
+ * @param context - Layout context
21
+ * @param currentMain - Current X position
22
+ * @returns Position and next main axis value
23
+ */
24
+ positionChild(child: LayoutChild, _index: number, context: LayoutContext, currentMain: number): {
25
+ position: Position;
26
+ nextMain: number;
27
+ };
28
+ /**
29
+ * Wrap children into lines based on available width
30
+ * Used when flexWrap is 'wrap' or 'wrap-reverse'
31
+ * @param children - Layout children to wrap
32
+ * @param availableWidth - Available width for each line
33
+ * @param gap - Gap between children
34
+ * @returns Array of layout lines
35
+ */
36
+ wrapChildren(children: LayoutChild[], availableWidth: number, gap: number): LayoutLine[];
37
+ }
38
+ //# sourceMappingURL=row-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-layout.d.ts","sourceRoot":"","sources":["../../../src/layout/strategies/row-layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAGnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB;IACvD;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,aAAa,GAAG,cAAc;IA4BlF;;;;;;;OAOG;IACH,aAAa,CACX,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,MAAM,GAClB;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IA0D3C;;;;;;;OAOG;IACH,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE;CAoEzF"}
@@ -0,0 +1,145 @@
1
+ import { parseSize, resolveSize } from "../utils/size-resolver.js";
2
+ import { calculateAlignItems } from "../utils/spacing-calculator.js";
3
+ import { BaseLayoutStrategy } from "./base-strategy.js";
4
+ class RowLayoutStrategy extends BaseLayoutStrategy {
5
+ /**
6
+ * Calculate content dimensions for row layout
7
+ * For flex children, uses a minimum default size to avoid chicken-egg sizing issues
8
+ * @param children - Array of layout children
9
+ * @param context - Layout context
10
+ * @returns Content metrics
11
+ */
12
+ calculateMetrics(children, _context) {
13
+ const FLEX_CHILD_MIN_SIZE = 100;
14
+ let maxHeight = 0;
15
+ let totalMainSize = 0;
16
+ for (const child of children) {
17
+ const total = this.getTotalChildSize(child);
18
+ maxHeight = Math.max(maxHeight, total.height);
19
+ const props = child.child.__layoutProps;
20
+ const isFlexItem = props?.flex !== void 0 && props.flex > 0 || props?.flexShrink !== void 0 || props?.flexBasis !== void 0;
21
+ const childWidth = isFlexItem && child.size.width <= 10 ? FLEX_CHILD_MIN_SIZE : total.width;
22
+ totalMainSize += childWidth;
23
+ }
24
+ return {
25
+ maxWidth: 0,
26
+ // Not used for row
27
+ maxHeight,
28
+ totalMainSize
29
+ };
30
+ }
31
+ /**
32
+ * Position a child in row layout
33
+ * @param child - Layout child
34
+ * @param _index - Child index (unused for row layout)
35
+ * @param context - Layout context
36
+ * @param currentMain - Current X position
37
+ * @returns Position and next main axis value
38
+ */
39
+ positionChild(child, _index, context, currentMain) {
40
+ const margin = this.getMarginValues(child);
41
+ const isHeadless = child.child.__layoutProps?.headless;
42
+ let x;
43
+ let y;
44
+ let nextMain;
45
+ if (isHeadless) {
46
+ const parentWidth = context.parentSize?.width ?? context.contentArea.width;
47
+ const parentHeight = context.parentSize?.height ?? context.contentArea.height;
48
+ const justify = context.containerProps.justifyContent ?? "start";
49
+ let mainAxisOffset = 0;
50
+ if (justify === "center") {
51
+ mainAxisOffset = (parentWidth - child.size.width) / 2;
52
+ } else if (justify === "end") {
53
+ mainAxisOffset = parentWidth - child.size.width;
54
+ }
55
+ x = mainAxisOffset;
56
+ const crossAxisOffset = calculateAlignItems(
57
+ context.containerProps.alignItems,
58
+ parentHeight,
59
+ child.size.height,
60
+ 0,
61
+ 0
62
+ );
63
+ y = crossAxisOffset;
64
+ nextMain = currentMain;
65
+ } else {
66
+ currentMain += margin.left;
67
+ x = context.padding.left + currentMain;
68
+ const alignOffset = calculateAlignItems(
69
+ context.containerProps.alignItems,
70
+ context.contentArea.height,
71
+ child.size.height,
72
+ margin.top,
73
+ margin.bottom
74
+ );
75
+ y = context.padding.top + alignOffset;
76
+ nextMain = currentMain + child.size.width + margin.right;
77
+ }
78
+ return {
79
+ position: { x, y },
80
+ nextMain
81
+ };
82
+ }
83
+ /**
84
+ * Wrap children into lines based on available width
85
+ * Used when flexWrap is 'wrap' or 'wrap-reverse'
86
+ * @param children - Layout children to wrap
87
+ * @param availableWidth - Available width for each line
88
+ * @param gap - Gap between children
89
+ * @returns Array of layout lines
90
+ */
91
+ wrapChildren(children, availableWidth, gap) {
92
+ const lines = [];
93
+ let currentLine = [];
94
+ let currentLineWidth = 0;
95
+ let currentLineHeight = 0;
96
+ for (const child of children) {
97
+ if (child.child.__layoutProps?.headless) {
98
+ continue;
99
+ }
100
+ const margin = this.getMarginValues(child);
101
+ const props = child.child.__layoutProps;
102
+ let effectiveWidth = child.size.width;
103
+ if (effectiveWidth <= 0 && props) {
104
+ if (props.flexBasis !== void 0 && typeof props.flexBasis === "number") {
105
+ effectiveWidth = props.flexBasis;
106
+ } else if (props.minWidth !== void 0) {
107
+ const parsed = parseSize(props.minWidth);
108
+ effectiveWidth = resolveSize(parsed, availableWidth, 100, void 0);
109
+ } else if (props.flex && props.flex > 0) {
110
+ effectiveWidth = 100;
111
+ }
112
+ }
113
+ const childWidth = effectiveWidth + margin.left + margin.right;
114
+ const childHeight = child.size.height + margin.top + margin.bottom;
115
+ const gapSpace = currentLine.length > 0 ? gap : 0;
116
+ const requiredSpace = currentLineWidth + childWidth + gapSpace;
117
+ if (requiredSpace > availableWidth && currentLine.length > 0) {
118
+ lines.push({
119
+ children: currentLine,
120
+ mainAxisSize: currentLineWidth,
121
+ crossAxisSize: currentLineHeight
122
+ });
123
+ currentLine = [child];
124
+ currentLineWidth = childWidth;
125
+ currentLineHeight = childHeight;
126
+ } else {
127
+ currentLine.push(child);
128
+ currentLineWidth = requiredSpace;
129
+ currentLineHeight = Math.max(currentLineHeight, childHeight);
130
+ }
131
+ }
132
+ if (currentLine.length > 0) {
133
+ lines.push({
134
+ children: currentLine,
135
+ mainAxisSize: currentLineWidth,
136
+ crossAxisSize: currentLineHeight
137
+ });
138
+ }
139
+ return lines;
140
+ }
141
+ }
142
+ export {
143
+ RowLayoutStrategy
144
+ };
145
+ //# sourceMappingURL=row-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-layout.js","sources":["../../../src/layout/strategies/row-layout.ts"],"sourcesContent":["/**\n * Row layout strategy (horizontal stacking)\n * Like SwiftUI's HStack\n */\nimport type { LayoutChild, LayoutContext, LayoutLine, Position } from '../types'\nimport type { ContentMetrics } from '../utils/dimension-calculator'\nimport { parseSize, resolveSize } from '../utils/size-resolver'\nimport { calculateAlignItems } from '../utils/spacing-calculator'\nimport { BaseLayoutStrategy } from './base-strategy'\n\n/**\n * Row layout strategy - stacks children horizontally\n */\nexport class RowLayoutStrategy extends BaseLayoutStrategy {\n /**\n * Calculate content dimensions for row layout\n * For flex children, uses a minimum default size to avoid chicken-egg sizing issues\n * @param children - Array of layout children\n * @param context - Layout context\n * @returns Content metrics\n */\n calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics {\n const FLEX_CHILD_MIN_SIZE = 100 // Minimum size for flex children in content calculation\n let maxHeight = 0\n let totalMainSize = 0\n\n for (const child of children) {\n const total = this.getTotalChildSize(child)\n maxHeight = Math.max(maxHeight, total.height)\n\n // Check if this child participates in flexbox (flex, flexShrink, or flexBasis)\n const props = child.child.__layoutProps\n const isFlexItem =\n (props?.flex !== undefined && props.flex > 0) ||\n props?.flexShrink !== undefined ||\n props?.flexBasis !== undefined\n // If flex child already has a resolved size (> 10), use it; otherwise use minimum\n const childWidth = isFlexItem && child.size.width <= 10 ? FLEX_CHILD_MIN_SIZE : total.width\n\n totalMainSize += childWidth\n }\n\n return {\n maxWidth: 0, // Not used for row\n maxHeight,\n totalMainSize,\n }\n }\n\n /**\n * Position a child in row layout\n * @param child - Layout child\n * @param _index - Child index (unused for row layout)\n * @param context - Layout context\n * @param currentMain - Current X position\n * @returns Position and next main axis value\n */\n positionChild(\n child: LayoutChild,\n _index: number,\n context: LayoutContext,\n currentMain: number\n ): { position: Position; nextMain: number } {\n const margin = this.getMarginValues(child)\n const isHeadless = child.child.__layoutProps?.headless\n\n let x: number\n let y: number\n let nextMain: number\n\n if (isHeadless) {\n // Headless: calculate position directly using alignItems/justifyContent on full parent size\n const parentWidth = context.parentSize?.width ?? context.contentArea.width\n const parentHeight = context.parentSize?.height ?? context.contentArea.height\n\n // justifyContent on main axis (horizontal)\n const justify = context.containerProps.justifyContent ?? 'start'\n let mainAxisOffset = 0\n if (justify === 'center') {\n mainAxisOffset = (parentWidth - child.size.width) / 2\n } else if (justify === 'end') {\n mainAxisOffset = parentWidth - child.size.width\n }\n x = mainAxisOffset\n\n // alignItems on cross axis (vertical)\n const crossAxisOffset = calculateAlignItems(\n context.containerProps.alignItems,\n parentHeight,\n child.size.height,\n 0,\n 0\n )\n y = crossAxisOffset\n\n // Don't advance currentMain for headless\n nextMain = currentMain\n } else {\n // Normal: use container padding and contentArea\n currentMain += margin.left\n x = context.padding.left + currentMain\n\n const alignOffset = calculateAlignItems(\n context.containerProps.alignItems,\n context.contentArea.height,\n child.size.height,\n margin.top,\n margin.bottom\n )\n y = context.padding.top + alignOffset\n\n nextMain = currentMain + child.size.width + margin.right\n }\n\n return {\n position: { x, y },\n nextMain,\n }\n }\n\n /**\n * Wrap children into lines based on available width\n * Used when flexWrap is 'wrap' or 'wrap-reverse'\n * @param children - Layout children to wrap\n * @param availableWidth - Available width for each line\n * @param gap - Gap between children\n * @returns Array of layout lines\n */\n wrapChildren(children: LayoutChild[], availableWidth: number, gap: number): LayoutLine[] {\n const lines: LayoutLine[] = []\n let currentLine: LayoutChild[] = []\n let currentLineWidth = 0\n let currentLineHeight = 0\n\n for (const child of children) {\n // Skip headless children in wrapping calculation\n if (child.child.__layoutProps?.headless) {\n continue\n }\n\n const margin = this.getMarginValues(child)\n const props = child.child.__layoutProps\n\n // For flex items with no size, use flexBasis or minWidth as hint for wrapping\n let effectiveWidth = child.size.width\n if (effectiveWidth <= 0 && props) {\n if (props.flexBasis !== undefined && typeof props.flexBasis === 'number') {\n effectiveWidth = props.flexBasis\n } else if (props.minWidth !== undefined) {\n // Resolve minWidth SizeValue to number\n const parsed = parseSize(props.minWidth)\n effectiveWidth = resolveSize(parsed, availableWidth, 100, undefined)\n } else if (props.flex && props.flex > 0) {\n // Use a reasonable default for flex items with no size hint\n effectiveWidth = 100\n }\n }\n\n const childWidth = effectiveWidth + margin.left + margin.right\n const childHeight = child.size.height + margin.top + margin.bottom\n\n const gapSpace = currentLine.length > 0 ? gap : 0\n const requiredSpace = currentLineWidth + childWidth + gapSpace\n\n // Check if we need to wrap to a new line\n if (requiredSpace > availableWidth && currentLine.length > 0) {\n // Save current line\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineWidth,\n crossAxisSize: currentLineHeight,\n })\n\n // Start new line\n currentLine = [child]\n currentLineWidth = childWidth\n currentLineHeight = childHeight\n } else {\n // Add to current line\n currentLine.push(child)\n currentLineWidth = requiredSpace\n currentLineHeight = Math.max(currentLineHeight, childHeight)\n }\n }\n\n // Add remaining line\n if (currentLine.length > 0) {\n lines.push({\n children: currentLine,\n mainAxisSize: currentLineWidth,\n crossAxisSize: currentLineHeight,\n })\n }\n\n return lines\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const animatedSignal = require("../../animation/animated-signal.cjs");
4
+ const baseStrategy = require("./base-strategy.cjs");
5
+ function toLayoutNumber(value) {
6
+ if (value === void 0) return void 0;
7
+ return animatedSignal.isAnimatedSignal(value) ? value.value : value;
8
+ }
9
+ class StackLayoutStrategy extends baseStrategy.BaseLayoutStrategy {
10
+ /**
11
+ * Calculate content dimensions for stack layout
12
+ * For stack, we track max dimensions as children overlay
13
+ * @param children - Array of layout children
14
+ * @param context - Layout context
15
+ * @returns Content metrics
16
+ */
17
+ calculateMetrics(children, _context) {
18
+ let maxWidth = 0;
19
+ let maxHeight = 0;
20
+ for (const child of children) {
21
+ const total = this.getTotalChildSize(child);
22
+ maxWidth = Math.max(maxWidth, total.width);
23
+ maxHeight = Math.max(maxHeight, total.height);
24
+ }
25
+ return {
26
+ maxWidth,
27
+ maxHeight,
28
+ totalMainSize: 0
29
+ // Not applicable for stack
30
+ };
31
+ }
32
+ /**
33
+ * Position a child in stack layout
34
+ * All children positioned at same location, aligned via alignItems
35
+ * @param child - Layout child
36
+ * @param _index - Child index (unused for stack layout)
37
+ * @param context - Layout context
38
+ * @param currentMain - Current position (unused for stack)
39
+ * @returns Position and unchanged currentMain
40
+ */
41
+ positionChild(child, _index, context, currentMain) {
42
+ const margin = this.getMarginValues(child);
43
+ const { alignItems } = context.containerProps;
44
+ const isHeadless = child.child.__layoutProps?.headless;
45
+ let x;
46
+ let y;
47
+ if (isHeadless) {
48
+ return {
49
+ position: {
50
+ x: toLayoutNumber(child.child.__layoutProps?.x) ?? 0,
51
+ y: toLayoutNumber(child.child.__layoutProps?.y) ?? 0
52
+ },
53
+ nextMain: currentMain
54
+ };
55
+ }
56
+ switch (alignItems) {
57
+ case "start":
58
+ x = context.padding.left + margin.left;
59
+ y = context.padding.top + margin.top;
60
+ break;
61
+ case "center":
62
+ x = context.padding.left + (context.contentArea.width - child.size.width) / 2;
63
+ y = context.padding.top + (context.contentArea.height - child.size.height) / 2;
64
+ break;
65
+ case "end":
66
+ x = context.padding.left + context.contentArea.width - child.size.width - margin.right;
67
+ y = context.padding.top + context.contentArea.height - child.size.height - margin.bottom;
68
+ break;
69
+ case "stretch":
70
+ x = context.padding.left + margin.left;
71
+ y = context.padding.top + margin.top;
72
+ break;
73
+ default:
74
+ x = context.padding.left + margin.left;
75
+ y = context.padding.top + margin.top;
76
+ break;
77
+ }
78
+ const childX = toLayoutNumber(child.child.__layoutProps?.x);
79
+ const childY = toLayoutNumber(child.child.__layoutProps?.y);
80
+ if (childX !== void 0) {
81
+ x += childX;
82
+ }
83
+ if (childY !== void 0) {
84
+ y += childY;
85
+ }
86
+ return {
87
+ position: { x, y },
88
+ nextMain: currentMain
89
+ // Stack doesn't advance main axis
90
+ };
91
+ }
92
+ }
93
+ exports.StackLayoutStrategy = StackLayoutStrategy;
94
+ //# sourceMappingURL=stack-layout.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-layout.cjs","sources":["../../../src/layout/strategies/stack-layout.ts"],"sourcesContent":["/**\n * Stack layout strategy (overlay positioning)\n * Like SwiftUI's ZStack - all children positioned at same location\n */\nimport { isAnimatedSignal } from '../../animation/animated-signal'\nimport type { LayoutChild, LayoutContext, Position } from '../types'\nimport type { ContentMetrics } from '../utils/dimension-calculator'\nimport { BaseLayoutStrategy } from './base-strategy'\n\n/**\n * Unwrap a layout prop value — resolves AnimatedSignal to its .value,\n * passes through plain numbers, returns undefined for undefined.\n */\nfunction toLayoutNumber(value: unknown): number | undefined {\n if (value === undefined) return undefined\n return isAnimatedSignal(value) ? value.value : (value as number)\n}\n\n/**\n * Stack layout strategy - overlays all children at the same position\n */\nexport class StackLayoutStrategy extends BaseLayoutStrategy {\n /**\n * Calculate content dimensions for stack layout\n * For stack, we track max dimensions as children overlay\n * @param children - Array of layout children\n * @param context - Layout context\n * @returns Content metrics\n */\n calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics {\n let maxWidth = 0\n let maxHeight = 0\n\n for (const child of children) {\n const total = this.getTotalChildSize(child)\n maxWidth = Math.max(maxWidth, total.width)\n maxHeight = Math.max(maxHeight, total.height)\n }\n\n return {\n maxWidth,\n maxHeight,\n totalMainSize: 0, // Not applicable for stack\n }\n }\n\n /**\n * Position a child in stack layout\n * All children positioned at same location, aligned via alignItems\n * @param child - Layout child\n * @param _index - Child index (unused for stack layout)\n * @param context - Layout context\n * @param currentMain - Current position (unused for stack)\n * @returns Position and unchanged currentMain\n */\n positionChild(\n child: LayoutChild,\n _index: number,\n context: LayoutContext,\n currentMain: number\n ): { position: Position; nextMain: number } {\n const margin = this.getMarginValues(child)\n const { alignItems } = context.containerProps\n const isHeadless = child.child.__layoutProps?.headless\n\n let x: number\n let y: number\n\n if (isHeadless) {\n return {\n position: {\n x: toLayoutNumber(child.child.__layoutProps?.x) ?? 0,\n y: toLayoutNumber(child.child.__layoutProps?.y) ?? 0,\n },\n nextMain: currentMain,\n }\n }\n\n // Position based on alignItems (applies to both axes for stack)\n switch (alignItems) {\n case 'start':\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n case 'center':\n x = context.padding.left + (context.contentArea.width - child.size.width) / 2\n y = context.padding.top + (context.contentArea.height - child.size.height) / 2\n break\n case 'end':\n x = context.padding.left + context.contentArea.width - child.size.width - margin.right\n y = context.padding.top + context.contentArea.height - child.size.height - margin.bottom\n break\n case 'stretch':\n // TODO: Implement stretch - for now behave like start\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n default:\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n }\n\n // Apply explicit x/y offsets if provided\n const childX = toLayoutNumber(child.child.__layoutProps?.x)\n const childY = toLayoutNumber(child.child.__layoutProps?.y)\n\n if (childX !== undefined) {\n x += childX\n }\n if (childY !== undefined) {\n y += childY\n }\n\n return {\n position: { x, y },\n nextMain: currentMain, // Stack doesn't advance main axis\n }\n }\n}\n"],"names":["isAnimatedSignal","BaseLayoutStrategy"],"mappings":";;;;AAaA,SAAS,eAAe,OAAoC;AAC1D,MAAI,UAAU,OAAW,QAAO;AAChC,SAAOA,eAAAA,iBAAiB,KAAK,IAAI,MAAM,QAAS;AAClD;AAKO,MAAM,4BAA4BC,aAAAA,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1D,iBAAiB,UAAyB,UAAyC;AACjF,QAAI,WAAW;AACf,QAAI,YAAY;AAEhB,eAAW,SAAS,UAAU;AAC5B,YAAM,QAAQ,KAAK,kBAAkB,KAAK;AAC1C,iBAAW,KAAK,IAAI,UAAU,MAAM,KAAK;AACzC,kBAAY,KAAK,IAAI,WAAW,MAAM,MAAM;AAAA,IAC9C;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,eAAe;AAAA;AAAA,IAAA;AAAA,EAEnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cACE,OACA,QACA,SACA,aAC0C;AAC1C,UAAM,SAAS,KAAK,gBAAgB,KAAK;AACzC,UAAM,EAAE,eAAe,QAAQ;AAC/B,UAAM,aAAa,MAAM,MAAM,eAAe;AAE9C,QAAI;AACJ,QAAI;AAEJ,QAAI,YAAY;AACd,aAAO;AAAA,QACL,UAAU;AAAA,UACR,GAAG,eAAe,MAAM,MAAM,eAAe,CAAC,KAAK;AAAA,UACnD,GAAG,eAAe,MAAM,MAAM,eAAe,CAAC,KAAK;AAAA,QAAA;AAAA,QAErD,UAAU;AAAA,MAAA;AAAA,IAEd;AAGA,YAAQ,YAAA;AAAA,MACN,KAAK;AACH,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,MAAM,KAAK,SAAS;AAC5E,YAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,SAAS,MAAM,KAAK,UAAU;AAC7E;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,QAAQ,MAAM,KAAK,QAAQ,OAAO;AACjF,YAAI,QAAQ,QAAQ,MAAM,QAAQ,YAAY,SAAS,MAAM,KAAK,SAAS,OAAO;AAClF;AAAA,MACF,KAAK;AAEH,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,MACF;AACE,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,IAAA;AAIJ,UAAM,SAAS,eAAe,MAAM,MAAM,eAAe,CAAC;AAC1D,UAAM,SAAS,eAAe,MAAM,MAAM,eAAe,CAAC;AAE1D,QAAI,WAAW,QAAW;AACxB,WAAK;AAAA,IACP;AACA,QAAI,WAAW,QAAW;AACxB,WAAK;AAAA,IACP;AAEA,WAAO;AAAA,MACL,UAAU,EAAE,GAAG,EAAA;AAAA,MACf,UAAU;AAAA;AAAA,IAAA;AAAA,EAEd;AACF;;"}
@@ -0,0 +1,30 @@
1
+ import { LayoutChild, LayoutContext, Position } from '../types';
2
+ import { ContentMetrics } from '../utils/dimension-calculator';
3
+ import { BaseLayoutStrategy } from './base-strategy';
4
+ /**
5
+ * Stack layout strategy - overlays all children at the same position
6
+ */
7
+ export declare class StackLayoutStrategy extends BaseLayoutStrategy {
8
+ /**
9
+ * Calculate content dimensions for stack layout
10
+ * For stack, we track max dimensions as children overlay
11
+ * @param children - Array of layout children
12
+ * @param context - Layout context
13
+ * @returns Content metrics
14
+ */
15
+ calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics;
16
+ /**
17
+ * Position a child in stack layout
18
+ * All children positioned at same location, aligned via alignItems
19
+ * @param child - Layout child
20
+ * @param _index - Child index (unused for stack layout)
21
+ * @param context - Layout context
22
+ * @param currentMain - Current position (unused for stack)
23
+ * @returns Position and unchanged currentMain
24
+ */
25
+ positionChild(child: LayoutChild, _index: number, context: LayoutContext, currentMain: number): {
26
+ position: Position;
27
+ nextMain: number;
28
+ };
29
+ }
30
+ //# sourceMappingURL=stack-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-layout.d.ts","sourceRoot":"","sources":["../../../src/layout/strategies/stack-layout.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAWpD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB;IACzD;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,aAAa,GAAG,cAAc;IAiBlF;;;;;;;;OAQG;IACH,aAAa,CACX,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,MAAM,GAClB;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CA2D5C"}
@@ -0,0 +1,94 @@
1
+ import { isAnimatedSignal } from "../../animation/animated-signal.js";
2
+ import { BaseLayoutStrategy } from "./base-strategy.js";
3
+ function toLayoutNumber(value) {
4
+ if (value === void 0) return void 0;
5
+ return isAnimatedSignal(value) ? value.value : value;
6
+ }
7
+ class StackLayoutStrategy extends BaseLayoutStrategy {
8
+ /**
9
+ * Calculate content dimensions for stack layout
10
+ * For stack, we track max dimensions as children overlay
11
+ * @param children - Array of layout children
12
+ * @param context - Layout context
13
+ * @returns Content metrics
14
+ */
15
+ calculateMetrics(children, _context) {
16
+ let maxWidth = 0;
17
+ let maxHeight = 0;
18
+ for (const child of children) {
19
+ const total = this.getTotalChildSize(child);
20
+ maxWidth = Math.max(maxWidth, total.width);
21
+ maxHeight = Math.max(maxHeight, total.height);
22
+ }
23
+ return {
24
+ maxWidth,
25
+ maxHeight,
26
+ totalMainSize: 0
27
+ // Not applicable for stack
28
+ };
29
+ }
30
+ /**
31
+ * Position a child in stack layout
32
+ * All children positioned at same location, aligned via alignItems
33
+ * @param child - Layout child
34
+ * @param _index - Child index (unused for stack layout)
35
+ * @param context - Layout context
36
+ * @param currentMain - Current position (unused for stack)
37
+ * @returns Position and unchanged currentMain
38
+ */
39
+ positionChild(child, _index, context, currentMain) {
40
+ const margin = this.getMarginValues(child);
41
+ const { alignItems } = context.containerProps;
42
+ const isHeadless = child.child.__layoutProps?.headless;
43
+ let x;
44
+ let y;
45
+ if (isHeadless) {
46
+ return {
47
+ position: {
48
+ x: toLayoutNumber(child.child.__layoutProps?.x) ?? 0,
49
+ y: toLayoutNumber(child.child.__layoutProps?.y) ?? 0
50
+ },
51
+ nextMain: currentMain
52
+ };
53
+ }
54
+ switch (alignItems) {
55
+ case "start":
56
+ x = context.padding.left + margin.left;
57
+ y = context.padding.top + margin.top;
58
+ break;
59
+ case "center":
60
+ x = context.padding.left + (context.contentArea.width - child.size.width) / 2;
61
+ y = context.padding.top + (context.contentArea.height - child.size.height) / 2;
62
+ break;
63
+ case "end":
64
+ x = context.padding.left + context.contentArea.width - child.size.width - margin.right;
65
+ y = context.padding.top + context.contentArea.height - child.size.height - margin.bottom;
66
+ break;
67
+ case "stretch":
68
+ x = context.padding.left + margin.left;
69
+ y = context.padding.top + margin.top;
70
+ break;
71
+ default:
72
+ x = context.padding.left + margin.left;
73
+ y = context.padding.top + margin.top;
74
+ break;
75
+ }
76
+ const childX = toLayoutNumber(child.child.__layoutProps?.x);
77
+ const childY = toLayoutNumber(child.child.__layoutProps?.y);
78
+ if (childX !== void 0) {
79
+ x += childX;
80
+ }
81
+ if (childY !== void 0) {
82
+ y += childY;
83
+ }
84
+ return {
85
+ position: { x, y },
86
+ nextMain: currentMain
87
+ // Stack doesn't advance main axis
88
+ };
89
+ }
90
+ }
91
+ export {
92
+ StackLayoutStrategy
93
+ };
94
+ //# sourceMappingURL=stack-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-layout.js","sources":["../../../src/layout/strategies/stack-layout.ts"],"sourcesContent":["/**\n * Stack layout strategy (overlay positioning)\n * Like SwiftUI's ZStack - all children positioned at same location\n */\nimport { isAnimatedSignal } from '../../animation/animated-signal'\nimport type { LayoutChild, LayoutContext, Position } from '../types'\nimport type { ContentMetrics } from '../utils/dimension-calculator'\nimport { BaseLayoutStrategy } from './base-strategy'\n\n/**\n * Unwrap a layout prop value — resolves AnimatedSignal to its .value,\n * passes through plain numbers, returns undefined for undefined.\n */\nfunction toLayoutNumber(value: unknown): number | undefined {\n if (value === undefined) return undefined\n return isAnimatedSignal(value) ? value.value : (value as number)\n}\n\n/**\n * Stack layout strategy - overlays all children at the same position\n */\nexport class StackLayoutStrategy extends BaseLayoutStrategy {\n /**\n * Calculate content dimensions for stack layout\n * For stack, we track max dimensions as children overlay\n * @param children - Array of layout children\n * @param context - Layout context\n * @returns Content metrics\n */\n calculateMetrics(children: LayoutChild[], _context: LayoutContext): ContentMetrics {\n let maxWidth = 0\n let maxHeight = 0\n\n for (const child of children) {\n const total = this.getTotalChildSize(child)\n maxWidth = Math.max(maxWidth, total.width)\n maxHeight = Math.max(maxHeight, total.height)\n }\n\n return {\n maxWidth,\n maxHeight,\n totalMainSize: 0, // Not applicable for stack\n }\n }\n\n /**\n * Position a child in stack layout\n * All children positioned at same location, aligned via alignItems\n * @param child - Layout child\n * @param _index - Child index (unused for stack layout)\n * @param context - Layout context\n * @param currentMain - Current position (unused for stack)\n * @returns Position and unchanged currentMain\n */\n positionChild(\n child: LayoutChild,\n _index: number,\n context: LayoutContext,\n currentMain: number\n ): { position: Position; nextMain: number } {\n const margin = this.getMarginValues(child)\n const { alignItems } = context.containerProps\n const isHeadless = child.child.__layoutProps?.headless\n\n let x: number\n let y: number\n\n if (isHeadless) {\n return {\n position: {\n x: toLayoutNumber(child.child.__layoutProps?.x) ?? 0,\n y: toLayoutNumber(child.child.__layoutProps?.y) ?? 0,\n },\n nextMain: currentMain,\n }\n }\n\n // Position based on alignItems (applies to both axes for stack)\n switch (alignItems) {\n case 'start':\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n case 'center':\n x = context.padding.left + (context.contentArea.width - child.size.width) / 2\n y = context.padding.top + (context.contentArea.height - child.size.height) / 2\n break\n case 'end':\n x = context.padding.left + context.contentArea.width - child.size.width - margin.right\n y = context.padding.top + context.contentArea.height - child.size.height - margin.bottom\n break\n case 'stretch':\n // TODO: Implement stretch - for now behave like start\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n default:\n x = context.padding.left + margin.left\n y = context.padding.top + margin.top\n break\n }\n\n // Apply explicit x/y offsets if provided\n const childX = toLayoutNumber(child.child.__layoutProps?.x)\n const childY = toLayoutNumber(child.child.__layoutProps?.y)\n\n if (childX !== undefined) {\n x += childX\n }\n if (childY !== undefined) {\n y += childY\n }\n\n return {\n position: { x, y },\n nextMain: currentMain, // Stack doesn't advance main axis\n }\n }\n}\n"],"names":[],"mappings":";;AAaA,SAAS,eAAe,OAAoC;AAC1D,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,iBAAiB,KAAK,IAAI,MAAM,QAAS;AAClD;AAKO,MAAM,4BAA4B,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1D,iBAAiB,UAAyB,UAAyC;AACjF,QAAI,WAAW;AACf,QAAI,YAAY;AAEhB,eAAW,SAAS,UAAU;AAC5B,YAAM,QAAQ,KAAK,kBAAkB,KAAK;AAC1C,iBAAW,KAAK,IAAI,UAAU,MAAM,KAAK;AACzC,kBAAY,KAAK,IAAI,WAAW,MAAM,MAAM;AAAA,IAC9C;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,eAAe;AAAA;AAAA,IAAA;AAAA,EAEnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cACE,OACA,QACA,SACA,aAC0C;AAC1C,UAAM,SAAS,KAAK,gBAAgB,KAAK;AACzC,UAAM,EAAE,eAAe,QAAQ;AAC/B,UAAM,aAAa,MAAM,MAAM,eAAe;AAE9C,QAAI;AACJ,QAAI;AAEJ,QAAI,YAAY;AACd,aAAO;AAAA,QACL,UAAU;AAAA,UACR,GAAG,eAAe,MAAM,MAAM,eAAe,CAAC,KAAK;AAAA,UACnD,GAAG,eAAe,MAAM,MAAM,eAAe,CAAC,KAAK;AAAA,QAAA;AAAA,QAErD,UAAU;AAAA,MAAA;AAAA,IAEd;AAGA,YAAQ,YAAA;AAAA,MACN,KAAK;AACH,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,MAAM,KAAK,SAAS;AAC5E,YAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,SAAS,MAAM,KAAK,UAAU;AAC7E;AAAA,MACF,KAAK;AACH,YAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,QAAQ,MAAM,KAAK,QAAQ,OAAO;AACjF,YAAI,QAAQ,QAAQ,MAAM,QAAQ,YAAY,SAAS,MAAM,KAAK,SAAS,OAAO;AAClF;AAAA,MACF,KAAK;AAEH,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,MACF;AACE,YAAI,QAAQ,QAAQ,OAAO,OAAO;AAClC,YAAI,QAAQ,QAAQ,MAAM,OAAO;AACjC;AAAA,IAAA;AAIJ,UAAM,SAAS,eAAe,MAAM,MAAM,eAAe,CAAC;AAC1D,UAAM,SAAS,eAAe,MAAM,MAAM,eAAe,CAAC;AAE1D,QAAI,WAAW,QAAW;AACxB,WAAK;AAAA,IACP;AACA,QAAI,WAAW,QAAW;AACxB,WAAK;AAAA,IACP;AAEA,WAAO;AAAA,MACL,UAAU,EAAE,GAAG,EAAA;AAAA,MACf,UAAU;AAAA;AAAA,IAAA;AAAA,EAEd;AACF;"}