@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,134 @@
1
+ import { BackgroundProps, EdgeInsets, LayoutProps, TransformProps } from '../core-props';
2
+ /** Size information for layout calculations */
3
+ export interface LayoutSize {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ /** Interface for nodes that can provide their layout dimensions dynamically */
8
+ export interface LayoutSizeProvider {
9
+ __getLayoutSize: () => LayoutSize;
10
+ }
11
+ /** Computed padding values */
12
+ export interface PaddingValues {
13
+ top: number;
14
+ right: number;
15
+ bottom: number;
16
+ left: number;
17
+ }
18
+ /** Position for a child element */
19
+ export interface Position {
20
+ x: number;
21
+ y: number;
22
+ }
23
+ /** Content area dimensions (container minus padding) */
24
+ export interface ContentArea {
25
+ width: number;
26
+ height: number;
27
+ }
28
+ /**
29
+ * Renderer-neutral interface for any node that participates in layout.
30
+ *
31
+ * Any renderer (Phaser, PixiJS, ...) can satisfy this via duck-typing
32
+ * by attaching __layoutProps, __getLayoutSize, etc. to their node objects.
33
+ */
34
+ export interface LayoutNode {
35
+ /** Horizontal position */
36
+ x?: number;
37
+ /** Vertical position */
38
+ y?: number;
39
+ /** Node width */
40
+ width?: number;
41
+ /** Node height */
42
+ height?: number;
43
+ /** Visibility flag */
44
+ visible?: boolean;
45
+ /** Set position (used by layout engine for child placement) */
46
+ setPosition?: (x: number, y: number) => void;
47
+ /** Set size (used by layout engine for child sizing) */
48
+ setSize?: (width: number, height: number) => void;
49
+ /** Set visibility of the node. Used by overlay/portal components on container refs. */
50
+ setVisible?: (visible: boolean) => void;
51
+ /** Parent container reference (for depth calculation and layout invalidation) */
52
+ parent?: LayoutContainer;
53
+ /** Optional logical layout parent when renderer internals use wrapper containers */
54
+ __layoutParent?: unknown;
55
+ /** Layout configuration (gap, padding, direction, etc.) */
56
+ __layoutProps?: Partial<LayoutProps & BackgroundProps & TransformProps>;
57
+ /** Get current layout-computed size */
58
+ __getLayoutSize?: () => LayoutSize;
59
+ /** Cached layout size (for invalidation) */
60
+ __cachedLayoutSize?: LayoutSize;
61
+ /** Last logical position assigned by the layout engine */
62
+ __layoutPosition?: Position;
63
+ /** Incremented whenever the layout engine assigns a position */
64
+ __layoutPositionRevision?: number;
65
+ /** Backup of original __getLayoutSize (for overlay restoration) */
66
+ __originalGetLayoutSize?: () => LayoutSize;
67
+ /** Marker: this node renders a background fill */
68
+ __isBackground?: boolean;
69
+ /** Background image reference — renderer-specific, typed by each renderer package */
70
+ __background?: unknown;
71
+ }
72
+ /**
73
+ * Renderer-neutral interface for container nodes that manage children.
74
+ * Extends LayoutNode with child-management capabilities.
75
+ */
76
+ export interface LayoutContainer extends LayoutNode {
77
+ /** Child nodes list */
78
+ list?: unknown[];
79
+ }
80
+ /** Prepared child data for layout calculations */
81
+ export interface LayoutChild {
82
+ child: LayoutContainer;
83
+ size: LayoutSize;
84
+ margin: EdgeInsets;
85
+ }
86
+ /** A line of children in a wrapped flex layout */
87
+ export interface LayoutLine {
88
+ children: LayoutChild[];
89
+ mainAxisSize: number;
90
+ crossAxisSize: number;
91
+ }
92
+ /** Parsed size representation */
93
+ export interface ParsedSize {
94
+ /** Size type: fixed pixels, percentage of parent, viewport units, auto, calc, fill */
95
+ type: 'fixed' | 'percent' | 'vw' | 'vh' | 'auto' | 'calc' | 'fill';
96
+ /** Numeric value */
97
+ value?: number;
98
+ /** Calc expression data (only for type='calc') */
99
+ calc?: CalcExpression;
100
+ }
101
+ /** Calc expression representation */
102
+ export interface CalcExpression {
103
+ left: CalcOperand | CalcExpression;
104
+ operator: '+' | '-' | '*' | '/';
105
+ right: CalcOperand | CalcExpression;
106
+ }
107
+ /** Calc operand */
108
+ export interface CalcOperand {
109
+ type: 'fixed' | 'percent' | 'vw' | 'vh';
110
+ value: number;
111
+ }
112
+ /** Computed metrics from children analysis */
113
+ export interface ContentMetrics {
114
+ maxWidth: number;
115
+ maxHeight: number;
116
+ totalMainSize: number;
117
+ }
118
+ /** Complete layout context passed to strategies */
119
+ export interface LayoutContext {
120
+ containerProps: LayoutProps;
121
+ padding: PaddingValues;
122
+ contentArea: ContentArea;
123
+ gap: {
124
+ horizontal: number;
125
+ vertical: number;
126
+ };
127
+ children: LayoutChild[];
128
+ /** Parent dimensions for percentage resolution */
129
+ parentSize?: {
130
+ width: number;
131
+ height: number;
132
+ };
133
+ }
134
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/layout/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const devConfig = require("../../dev-config.cjs");
4
+ const sizeResolver = require("./size-resolver.cjs");
5
+ function isLayoutChild(child) {
6
+ if (child.__isBackground) return false;
7
+ const displayMode = child.__layoutProps?.visible;
8
+ if (displayMode === "none") return false;
9
+ return typeof child.__getLayoutSize === "function";
10
+ }
11
+ function getMargin(child) {
12
+ const margin = child.__layoutProps?.margin;
13
+ if (typeof margin === "number") {
14
+ return { top: margin, right: margin, bottom: margin, left: margin };
15
+ }
16
+ return margin ?? {};
17
+ }
18
+ function getHorizontalMargin(margin) {
19
+ return (margin.left ?? 0) + (margin.right ?? 0);
20
+ }
21
+ function getVerticalMargin(margin) {
22
+ return (margin.top ?? 0) + (margin.bottom ?? 0);
23
+ }
24
+ function getChildSize(child, parentSize, parentPadding) {
25
+ if (child.__layoutProps && (child.__layoutProps.width !== void 0 || child.__layoutProps.height !== void 0)) {
26
+ const layoutWidth = child.__layoutProps.width;
27
+ const layoutHeight = child.__layoutProps.height;
28
+ const margin = getMargin(child);
29
+ const parsedWidth = sizeResolver.parseSize(layoutWidth);
30
+ let width2 = sizeResolver.resolveSize(
31
+ parsedWidth,
32
+ parentSize?.width,
33
+ child.width ?? 100,
34
+ parentPadding?.horizontal
35
+ );
36
+ if (parsedWidth.type === "fill") {
37
+ width2 = Math.max(0, width2 - getHorizontalMargin(margin));
38
+ }
39
+ const parsedHeight = sizeResolver.parseSize(layoutHeight);
40
+ let height2 = sizeResolver.resolveSize(
41
+ parsedHeight,
42
+ parentSize?.height,
43
+ child.height ?? 20,
44
+ parentPadding?.vertical
45
+ );
46
+ if (parsedHeight.type === "fill") {
47
+ height2 = Math.max(0, height2 - getVerticalMargin(margin));
48
+ }
49
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
50
+ width2 = sizeResolver.clampSize(
51
+ width2,
52
+ minWidth,
53
+ maxWidth,
54
+ parentSize?.width,
55
+ child.width,
56
+ parentPadding?.horizontal
57
+ );
58
+ height2 = sizeResolver.clampSize(
59
+ height2,
60
+ minHeight,
61
+ maxHeight,
62
+ parentSize?.height,
63
+ child.height,
64
+ parentPadding?.vertical
65
+ );
66
+ return { width: width2, height: height2 };
67
+ }
68
+ if (child.__getLayoutSize) {
69
+ let size = child.__getLayoutSize();
70
+ if (child.__layoutProps) {
71
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
72
+ size = {
73
+ width: sizeResolver.clampSize(
74
+ size.width,
75
+ minWidth,
76
+ maxWidth,
77
+ parentSize?.width,
78
+ child.width,
79
+ parentPadding?.horizontal
80
+ ),
81
+ height: sizeResolver.clampSize(
82
+ size.height,
83
+ minHeight,
84
+ maxHeight,
85
+ parentSize?.height,
86
+ child.height,
87
+ parentPadding?.vertical
88
+ )
89
+ };
90
+ }
91
+ return size;
92
+ }
93
+ let width = child.width ?? 100;
94
+ let height = child.height ?? 20;
95
+ if (child.__layoutProps) {
96
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
97
+ width = sizeResolver.clampSize(
98
+ width,
99
+ minWidth,
100
+ maxWidth,
101
+ parentSize?.width,
102
+ child.width,
103
+ parentPadding?.horizontal
104
+ );
105
+ height = sizeResolver.clampSize(
106
+ height,
107
+ minHeight,
108
+ maxHeight,
109
+ parentSize?.height,
110
+ child.height,
111
+ parentPadding?.vertical
112
+ );
113
+ }
114
+ return { width, height };
115
+ }
116
+ function processNestedContainer(child, calculateLayoutFn, parentSize, parentPadding) {
117
+ if (!("list" in child) || !Array.isArray(child.list)) {
118
+ return;
119
+ }
120
+ const childContainer = child;
121
+ const childLayoutProps = child.__layoutProps ?? {};
122
+ devConfig.DebugLogger.log("layout", "Child is a container, calculating nested layout first");
123
+ calculateLayoutFn(childContainer, childLayoutProps, parentSize, parentPadding);
124
+ }
125
+ exports.getChildSize = getChildSize;
126
+ exports.getMargin = getMargin;
127
+ exports.isLayoutChild = isLayoutChild;
128
+ exports.processNestedContainer = processNestedContainer;
129
+ //# sourceMappingURL=child-utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-utils.cjs","sources":["../../../src/layout/utils/child-utils.ts"],"sourcesContent":["/**\n * Utility functions for working with layout children.\n * Renderer-neutral — operates on LayoutContainer duck-typing.\n */\nimport type { EdgeInsets, LayoutProps } from '../../core-props'\nimport { DebugLogger } from '../../dev-config'\nimport type { LayoutContainer, LayoutSize } from '../types'\nimport { clampSize, parseSize, resolveSize } from './size-resolver'\n\n/**\n * Check if a child should participate in layout calculations\n * Headless objects participate in layout (for alignment) but report size 0\n * @param child - Child game object\n * @returns True if child should be included in layout\n */\nexport function isLayoutChild(child: LayoutContainer): boolean {\n // Skip background graphics (special role - defines container dimensions)\n if (child.__isBackground) return false\n\n // Check display mode from __layoutProps (visible prop)\n const displayMode = child.__layoutProps?.visible\n\n // Skip children with visible=\"none\" - they don't take up space (like CSS display: none)\n // Note: visible=false / \"invisible\" still occupies space (like CSS visibility: hidden)\n // Note: alpha=0 is different - it renders transparent but still occupies space\n if (displayMode === 'none') return false\n\n // Require __getLayoutSize for layout participation\n // Note: Headless objects still participate, they just report size 0\n return typeof child.__getLayoutSize === 'function'\n}\n\n/**\n * Get effective margin for a child\n * Normalizes margin to EdgeInsets (supports number for all sides)\n * Headless objects have no margin (positioned as point)\n * @param child - Child game object\n * @returns Edge insets\n */\nexport function getMargin(child: LayoutContainer): EdgeInsets {\n const margin = child.__layoutProps?.margin\n if (typeof margin === 'number') {\n return { top: margin, right: margin, bottom: margin, left: margin }\n }\n return margin ?? {}\n}\n\nfunction getHorizontalMargin(margin: EdgeInsets): number {\n return (margin.left ?? 0) + (margin.right ?? 0)\n}\n\nfunction getVerticalMargin(margin: EdgeInsets): number {\n return (margin.top ?? 0) + (margin.bottom ?? 0)\n}\n\n/**\n * Get effective size of a child\n * Calls __getLayoutSize if available, otherwise falls back to layoutProps or default\n * Note: String sizes (percentages) are resolved later with parent context\n * @param child - Child game object\n * @param parentSize - Optional parent dimensions for percentage resolution\n * @param parentPadding - Optional parent padding for 'fill' resolution\n * @returns Width and height in pixels\n */\nexport function getChildSize(\n child: LayoutContainer,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n): LayoutSize {\n // For flex children, we still need to calculate their actual size\n // (especially for cross-axis dimension in row/column layouts)\n // The main-axis size will be overridden by flex distribution anyway\n\n // If __layoutProps exists, use it (has priority for explicit layout configuration)\n if (\n child.__layoutProps &&\n (child.__layoutProps.width !== undefined || child.__layoutProps.height !== undefined)\n ) {\n const layoutWidth = child.__layoutProps.width\n const layoutHeight = child.__layoutProps.height\n const margin = getMargin(child)\n\n // Resolve width\n const parsedWidth = parseSize(layoutWidth)\n let width = resolveSize(\n parsedWidth,\n parentSize?.width,\n child.width ?? 100,\n parentPadding?.horizontal\n )\n if (parsedWidth.type === 'fill') {\n width = Math.max(0, width - getHorizontalMargin(margin))\n }\n\n // Resolve height\n const parsedHeight = parseSize(layoutHeight)\n let height = resolveSize(\n parsedHeight,\n parentSize?.height,\n child.height ?? 20,\n parentPadding?.vertical\n )\n if (parsedHeight.type === 'fill') {\n height = Math.max(0, height - getVerticalMargin(margin))\n }\n\n // Apply min/max constraints\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n width = clampSize(\n width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n )\n height = clampSize(\n height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n )\n\n return { width, height }\n }\n\n // Use dynamic size provider if available\n if (child.__getLayoutSize) {\n let size = child.__getLayoutSize()\n\n // Apply constraints if layoutProps exist (even without explicit width/height)\n if (child.__layoutProps) {\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n size = {\n width: clampSize(\n size.width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n ),\n height: clampSize(\n size.height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n ),\n }\n }\n\n return size\n }\n\n // Fallback to current dimensions or default\n let width = child.width ?? 100\n let height = child.height ?? 20\n\n // Apply constraints if layoutProps exist\n if (child.__layoutProps) {\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n width = clampSize(\n width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n )\n height = clampSize(\n height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n )\n }\n\n return { width, height }\n}\n\n/**\n * Process a child container by recursively calculating its layout\n * @param child - Child game object to process\n * @param calculateLayoutFn - Layout calculation function (passed to avoid circular dependency)\n * @param parentSize - Optional parent dimensions for percentage resolution\n * @param parentPadding - Optional parent padding for 'fill' resolution\n */\nexport function processNestedContainer(\n child: LayoutContainer,\n calculateLayoutFn: (\n container: LayoutContainer,\n props: LayoutProps,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n ) => void,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n): void {\n if (!('list' in child) || !Array.isArray((child as LayoutContainer).list)) {\n return\n }\n\n const childContainer = child as LayoutContainer\n const childLayoutProps = child.__layoutProps ?? {}\n\n DebugLogger.log('layout', 'Child is a container, calculating nested layout first')\n\n calculateLayoutFn(childContainer, childLayoutProps, parentSize, parentPadding)\n}\n"],"names":["parseSize","width","resolveSize","height","clampSize","DebugLogger"],"mappings":";;;;AAeO,SAAS,cAAc,OAAiC;AAE7D,MAAI,MAAM,eAAgB,QAAO;AAGjC,QAAM,cAAc,MAAM,eAAe;AAKzC,MAAI,gBAAgB,OAAQ,QAAO;AAInC,SAAO,OAAO,MAAM,oBAAoB;AAC1C;AASO,SAAS,UAAU,OAAoC;AAC5D,QAAM,SAAS,MAAM,eAAe;AACpC,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,EAAE,KAAK,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,MAAM,OAAA;AAAA,EAC7D;AACA,SAAO,UAAU,CAAA;AACnB;AAEA,SAAS,oBAAoB,QAA4B;AACvD,UAAQ,OAAO,QAAQ,MAAM,OAAO,SAAS;AAC/C;AAEA,SAAS,kBAAkB,QAA4B;AACrD,UAAQ,OAAO,OAAO,MAAM,OAAO,UAAU;AAC/C;AAWO,SAAS,aACd,OACA,YACA,eACY;AAMZ,MACE,MAAM,kBACL,MAAM,cAAc,UAAU,UAAa,MAAM,cAAc,WAAW,SAC3E;AACA,UAAM,cAAc,MAAM,cAAc;AACxC,UAAM,eAAe,MAAM,cAAc;AACzC,UAAM,SAAS,UAAU,KAAK;AAG9B,UAAM,cAAcA,aAAAA,UAAU,WAAW;AACzC,QAAIC,SAAQC,aAAAA;AAAAA,MACV;AAAA,MACA,YAAY;AAAA,MACZ,MAAM,SAAS;AAAA,MACf,eAAe;AAAA,IAAA;AAEjB,QAAI,YAAY,SAAS,QAAQ;AAC/BD,eAAQ,KAAK,IAAI,GAAGA,SAAQ,oBAAoB,MAAM,CAAC;AAAA,IACzD;AAGA,UAAM,eAAeD,aAAAA,UAAU,YAAY;AAC3C,QAAIG,UAASD,aAAAA;AAAAA,MACX;AAAA,MACA,YAAY;AAAA,MACZ,MAAM,UAAU;AAAA,MAChB,eAAe;AAAA,IAAA;AAEjB,QAAI,aAAa,SAAS,QAAQ;AAChCC,gBAAS,KAAK,IAAI,GAAGA,UAAS,kBAAkB,MAAM,CAAC;AAAA,IACzD;AAGA,UAAM,EAAE,UAAU,UAAU,WAAW,UAAA,IAAc,MAAM;AAC3DF,aAAQG,aAAAA;AAAAA,MACNH;AAAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,eAAe;AAAA,IAAA;AAEjBE,cAASC,aAAAA;AAAAA,MACPD;AAAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,eAAe;AAAA,IAAA;AAGjB,WAAO,EAAE,OAAAF,QAAO,QAAAE,QAAAA;AAAAA,EAClB;AAGA,MAAI,MAAM,iBAAiB;AACzB,QAAI,OAAO,MAAM,gBAAA;AAGjB,QAAI,MAAM,eAAe;AACvB,YAAM,EAAE,UAAU,UAAU,WAAW,UAAA,IAAc,MAAM;AAC3D,aAAO;AAAA,QACL,OAAOC,aAAAA;AAAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,MAAM;AAAA,UACN,eAAe;AAAA,QAAA;AAAA,QAEjB,QAAQA,aAAAA;AAAAA,UACN,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,MAAM;AAAA,UACN,eAAe;AAAA,QAAA;AAAA,MACjB;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,MAAM,SAAS;AAC3B,MAAI,SAAS,MAAM,UAAU;AAG7B,MAAI,MAAM,eAAe;AACvB,UAAM,EAAE,UAAU,UAAU,WAAW,UAAA,IAAc,MAAM;AAC3D,YAAQA,aAAAA;AAAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,eAAe;AAAA,IAAA;AAEjB,aAASA,aAAAA;AAAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,eAAe;AAAA,IAAA;AAAA,EAEnB;AAEA,SAAO,EAAE,OAAO,OAAA;AAClB;AASO,SAAS,uBACd,OACA,mBAMA,YACA,eACM;AACN,MAAI,EAAE,UAAU,UAAU,CAAC,MAAM,QAAS,MAA0B,IAAI,GAAG;AACzE;AAAA,EACF;AAEA,QAAM,iBAAiB;AACvB,QAAM,mBAAmB,MAAM,iBAAiB,CAAA;AAEhDC,wBAAY,IAAI,UAAU,uDAAuD;AAEjF,oBAAkB,gBAAgB,kBAAkB,YAAY,aAAa;AAC/E;;;;;"}
@@ -0,0 +1,54 @@
1
+ import { EdgeInsets, LayoutProps } from '../../core-props';
2
+ import { LayoutContainer, LayoutSize } from '../types';
3
+ /**
4
+ * Check if a child should participate in layout calculations
5
+ * Headless objects participate in layout (for alignment) but report size 0
6
+ * @param child - Child game object
7
+ * @returns True if child should be included in layout
8
+ */
9
+ export declare function isLayoutChild(child: LayoutContainer): boolean;
10
+ /**
11
+ * Get effective margin for a child
12
+ * Normalizes margin to EdgeInsets (supports number for all sides)
13
+ * Headless objects have no margin (positioned as point)
14
+ * @param child - Child game object
15
+ * @returns Edge insets
16
+ */
17
+ export declare function getMargin(child: LayoutContainer): EdgeInsets;
18
+ /**
19
+ * Get effective size of a child
20
+ * Calls __getLayoutSize if available, otherwise falls back to layoutProps or default
21
+ * Note: String sizes (percentages) are resolved later with parent context
22
+ * @param child - Child game object
23
+ * @param parentSize - Optional parent dimensions for percentage resolution
24
+ * @param parentPadding - Optional parent padding for 'fill' resolution
25
+ * @returns Width and height in pixels
26
+ */
27
+ export declare function getChildSize(child: LayoutContainer, parentSize?: {
28
+ width: number;
29
+ height: number;
30
+ }, parentPadding?: {
31
+ horizontal: number;
32
+ vertical: number;
33
+ }): LayoutSize;
34
+ /**
35
+ * Process a child container by recursively calculating its layout
36
+ * @param child - Child game object to process
37
+ * @param calculateLayoutFn - Layout calculation function (passed to avoid circular dependency)
38
+ * @param parentSize - Optional parent dimensions for percentage resolution
39
+ * @param parentPadding - Optional parent padding for 'fill' resolution
40
+ */
41
+ export declare function processNestedContainer(child: LayoutContainer, calculateLayoutFn: (container: LayoutContainer, props: LayoutProps, parentSize?: {
42
+ width: number;
43
+ height: number;
44
+ }, parentPadding?: {
45
+ horizontal: number;
46
+ vertical: number;
47
+ }) => void, parentSize?: {
48
+ width: number;
49
+ height: number;
50
+ }, parentPadding?: {
51
+ horizontal: number;
52
+ vertical: number;
53
+ }): void;
54
+ //# sourceMappingURL=child-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-utils.d.ts","sourceRoot":"","sources":["../../../src/layout/utils/child-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG3D;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAe7D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,UAAU,CAM5D;AAUD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,UAAU,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC9C,aAAa,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACvD,UAAU,CAoHZ;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,iBAAiB,EAAE,CACjB,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,WAAW,EAClB,UAAU,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC9C,aAAa,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,KACrD,IAAI,EACT,UAAU,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC9C,aAAa,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACvD,IAAI,CAWN"}
@@ -0,0 +1,129 @@
1
+ import { DebugLogger } from "../../dev-config.js";
2
+ import { parseSize, resolveSize, clampSize } from "./size-resolver.js";
3
+ function isLayoutChild(child) {
4
+ if (child.__isBackground) return false;
5
+ const displayMode = child.__layoutProps?.visible;
6
+ if (displayMode === "none") return false;
7
+ return typeof child.__getLayoutSize === "function";
8
+ }
9
+ function getMargin(child) {
10
+ const margin = child.__layoutProps?.margin;
11
+ if (typeof margin === "number") {
12
+ return { top: margin, right: margin, bottom: margin, left: margin };
13
+ }
14
+ return margin ?? {};
15
+ }
16
+ function getHorizontalMargin(margin) {
17
+ return (margin.left ?? 0) + (margin.right ?? 0);
18
+ }
19
+ function getVerticalMargin(margin) {
20
+ return (margin.top ?? 0) + (margin.bottom ?? 0);
21
+ }
22
+ function getChildSize(child, parentSize, parentPadding) {
23
+ if (child.__layoutProps && (child.__layoutProps.width !== void 0 || child.__layoutProps.height !== void 0)) {
24
+ const layoutWidth = child.__layoutProps.width;
25
+ const layoutHeight = child.__layoutProps.height;
26
+ const margin = getMargin(child);
27
+ const parsedWidth = parseSize(layoutWidth);
28
+ let width2 = resolveSize(
29
+ parsedWidth,
30
+ parentSize?.width,
31
+ child.width ?? 100,
32
+ parentPadding?.horizontal
33
+ );
34
+ if (parsedWidth.type === "fill") {
35
+ width2 = Math.max(0, width2 - getHorizontalMargin(margin));
36
+ }
37
+ const parsedHeight = parseSize(layoutHeight);
38
+ let height2 = resolveSize(
39
+ parsedHeight,
40
+ parentSize?.height,
41
+ child.height ?? 20,
42
+ parentPadding?.vertical
43
+ );
44
+ if (parsedHeight.type === "fill") {
45
+ height2 = Math.max(0, height2 - getVerticalMargin(margin));
46
+ }
47
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
48
+ width2 = clampSize(
49
+ width2,
50
+ minWidth,
51
+ maxWidth,
52
+ parentSize?.width,
53
+ child.width,
54
+ parentPadding?.horizontal
55
+ );
56
+ height2 = clampSize(
57
+ height2,
58
+ minHeight,
59
+ maxHeight,
60
+ parentSize?.height,
61
+ child.height,
62
+ parentPadding?.vertical
63
+ );
64
+ return { width: width2, height: height2 };
65
+ }
66
+ if (child.__getLayoutSize) {
67
+ let size = child.__getLayoutSize();
68
+ if (child.__layoutProps) {
69
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
70
+ size = {
71
+ width: clampSize(
72
+ size.width,
73
+ minWidth,
74
+ maxWidth,
75
+ parentSize?.width,
76
+ child.width,
77
+ parentPadding?.horizontal
78
+ ),
79
+ height: clampSize(
80
+ size.height,
81
+ minHeight,
82
+ maxHeight,
83
+ parentSize?.height,
84
+ child.height,
85
+ parentPadding?.vertical
86
+ )
87
+ };
88
+ }
89
+ return size;
90
+ }
91
+ let width = child.width ?? 100;
92
+ let height = child.height ?? 20;
93
+ if (child.__layoutProps) {
94
+ const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps;
95
+ width = clampSize(
96
+ width,
97
+ minWidth,
98
+ maxWidth,
99
+ parentSize?.width,
100
+ child.width,
101
+ parentPadding?.horizontal
102
+ );
103
+ height = clampSize(
104
+ height,
105
+ minHeight,
106
+ maxHeight,
107
+ parentSize?.height,
108
+ child.height,
109
+ parentPadding?.vertical
110
+ );
111
+ }
112
+ return { width, height };
113
+ }
114
+ function processNestedContainer(child, calculateLayoutFn, parentSize, parentPadding) {
115
+ if (!("list" in child) || !Array.isArray(child.list)) {
116
+ return;
117
+ }
118
+ const childContainer = child;
119
+ const childLayoutProps = child.__layoutProps ?? {};
120
+ DebugLogger.log("layout", "Child is a container, calculating nested layout first");
121
+ calculateLayoutFn(childContainer, childLayoutProps, parentSize, parentPadding);
122
+ }
123
+ export {
124
+ getChildSize,
125
+ getMargin,
126
+ isLayoutChild,
127
+ processNestedContainer
128
+ };
129
+ //# sourceMappingURL=child-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"child-utils.js","sources":["../../../src/layout/utils/child-utils.ts"],"sourcesContent":["/**\n * Utility functions for working with layout children.\n * Renderer-neutral — operates on LayoutContainer duck-typing.\n */\nimport type { EdgeInsets, LayoutProps } from '../../core-props'\nimport { DebugLogger } from '../../dev-config'\nimport type { LayoutContainer, LayoutSize } from '../types'\nimport { clampSize, parseSize, resolveSize } from './size-resolver'\n\n/**\n * Check if a child should participate in layout calculations\n * Headless objects participate in layout (for alignment) but report size 0\n * @param child - Child game object\n * @returns True if child should be included in layout\n */\nexport function isLayoutChild(child: LayoutContainer): boolean {\n // Skip background graphics (special role - defines container dimensions)\n if (child.__isBackground) return false\n\n // Check display mode from __layoutProps (visible prop)\n const displayMode = child.__layoutProps?.visible\n\n // Skip children with visible=\"none\" - they don't take up space (like CSS display: none)\n // Note: visible=false / \"invisible\" still occupies space (like CSS visibility: hidden)\n // Note: alpha=0 is different - it renders transparent but still occupies space\n if (displayMode === 'none') return false\n\n // Require __getLayoutSize for layout participation\n // Note: Headless objects still participate, they just report size 0\n return typeof child.__getLayoutSize === 'function'\n}\n\n/**\n * Get effective margin for a child\n * Normalizes margin to EdgeInsets (supports number for all sides)\n * Headless objects have no margin (positioned as point)\n * @param child - Child game object\n * @returns Edge insets\n */\nexport function getMargin(child: LayoutContainer): EdgeInsets {\n const margin = child.__layoutProps?.margin\n if (typeof margin === 'number') {\n return { top: margin, right: margin, bottom: margin, left: margin }\n }\n return margin ?? {}\n}\n\nfunction getHorizontalMargin(margin: EdgeInsets): number {\n return (margin.left ?? 0) + (margin.right ?? 0)\n}\n\nfunction getVerticalMargin(margin: EdgeInsets): number {\n return (margin.top ?? 0) + (margin.bottom ?? 0)\n}\n\n/**\n * Get effective size of a child\n * Calls __getLayoutSize if available, otherwise falls back to layoutProps or default\n * Note: String sizes (percentages) are resolved later with parent context\n * @param child - Child game object\n * @param parentSize - Optional parent dimensions for percentage resolution\n * @param parentPadding - Optional parent padding for 'fill' resolution\n * @returns Width and height in pixels\n */\nexport function getChildSize(\n child: LayoutContainer,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n): LayoutSize {\n // For flex children, we still need to calculate their actual size\n // (especially for cross-axis dimension in row/column layouts)\n // The main-axis size will be overridden by flex distribution anyway\n\n // If __layoutProps exists, use it (has priority for explicit layout configuration)\n if (\n child.__layoutProps &&\n (child.__layoutProps.width !== undefined || child.__layoutProps.height !== undefined)\n ) {\n const layoutWidth = child.__layoutProps.width\n const layoutHeight = child.__layoutProps.height\n const margin = getMargin(child)\n\n // Resolve width\n const parsedWidth = parseSize(layoutWidth)\n let width = resolveSize(\n parsedWidth,\n parentSize?.width,\n child.width ?? 100,\n parentPadding?.horizontal\n )\n if (parsedWidth.type === 'fill') {\n width = Math.max(0, width - getHorizontalMargin(margin))\n }\n\n // Resolve height\n const parsedHeight = parseSize(layoutHeight)\n let height = resolveSize(\n parsedHeight,\n parentSize?.height,\n child.height ?? 20,\n parentPadding?.vertical\n )\n if (parsedHeight.type === 'fill') {\n height = Math.max(0, height - getVerticalMargin(margin))\n }\n\n // Apply min/max constraints\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n width = clampSize(\n width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n )\n height = clampSize(\n height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n )\n\n return { width, height }\n }\n\n // Use dynamic size provider if available\n if (child.__getLayoutSize) {\n let size = child.__getLayoutSize()\n\n // Apply constraints if layoutProps exist (even without explicit width/height)\n if (child.__layoutProps) {\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n size = {\n width: clampSize(\n size.width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n ),\n height: clampSize(\n size.height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n ),\n }\n }\n\n return size\n }\n\n // Fallback to current dimensions or default\n let width = child.width ?? 100\n let height = child.height ?? 20\n\n // Apply constraints if layoutProps exist\n if (child.__layoutProps) {\n const { minWidth, maxWidth, minHeight, maxHeight } = child.__layoutProps\n width = clampSize(\n width,\n minWidth,\n maxWidth,\n parentSize?.width,\n child.width,\n parentPadding?.horizontal\n )\n height = clampSize(\n height,\n minHeight,\n maxHeight,\n parentSize?.height,\n child.height,\n parentPadding?.vertical\n )\n }\n\n return { width, height }\n}\n\n/**\n * Process a child container by recursively calculating its layout\n * @param child - Child game object to process\n * @param calculateLayoutFn - Layout calculation function (passed to avoid circular dependency)\n * @param parentSize - Optional parent dimensions for percentage resolution\n * @param parentPadding - Optional parent padding for 'fill' resolution\n */\nexport function processNestedContainer(\n child: LayoutContainer,\n calculateLayoutFn: (\n container: LayoutContainer,\n props: LayoutProps,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n ) => void,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n): void {\n if (!('list' in child) || !Array.isArray((child as LayoutContainer).list)) {\n return\n }\n\n const childContainer = child as LayoutContainer\n const childLayoutProps = child.__layoutProps ?? {}\n\n DebugLogger.log('layout', 'Child is a container, calculating nested layout first')\n\n calculateLayoutFn(childContainer, childLayoutProps, parentSize, parentPadding)\n}\n"],"names":["width","height"],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const sizeResolver = require("./size-resolver.cjs");
4
+ function normalizeMargin(margin) {
5
+ if (typeof margin === "number") {
6
+ return {
7
+ left: margin,
8
+ top: margin,
9
+ right: margin,
10
+ bottom: margin
11
+ };
12
+ }
13
+ return margin ?? {};
14
+ }
15
+ function getHorizontalMargin(margin) {
16
+ return (margin.left ?? 0) + (margin.right ?? 0);
17
+ }
18
+ function getVerticalMargin(margin) {
19
+ return (margin.top ?? 0) + (margin.bottom ?? 0);
20
+ }
21
+ function calculateContentDimensions(children, direction) {
22
+ const FLEX_CHILD_MIN_SIZE = 100;
23
+ let maxWidth = 0;
24
+ let maxHeight = 0;
25
+ let totalMainSize = 0;
26
+ for (const { size, margin, child } of children) {
27
+ const marginTop = margin.top ?? 0;
28
+ const marginBottom = margin.bottom ?? 0;
29
+ const marginLeft = margin.left ?? 0;
30
+ const marginRight = margin.right ?? 0;
31
+ const hasFlex = (child.__layoutProps?.flex ?? 0) > 0;
32
+ if (direction === "row") {
33
+ const childWidth = hasFlex ? FLEX_CHILD_MIN_SIZE : size.width;
34
+ totalMainSize += marginLeft + childWidth + marginRight;
35
+ const childTotalHeight = marginTop + size.height + marginBottom;
36
+ maxHeight = Math.max(maxHeight, childTotalHeight);
37
+ } else if (direction === "column") {
38
+ const childTotalWidth = marginLeft + size.width + marginRight;
39
+ maxWidth = Math.max(maxWidth, childTotalWidth);
40
+ const childHeight = hasFlex ? FLEX_CHILD_MIN_SIZE : size.height;
41
+ totalMainSize += marginTop + childHeight + marginBottom;
42
+ } else if (direction === "stack") {
43
+ const childTotalWidth = marginLeft + size.width + marginRight;
44
+ const childTotalHeight = marginTop + size.height + marginBottom;
45
+ maxWidth = Math.max(maxWidth, childTotalWidth);
46
+ maxHeight = Math.max(maxHeight, childTotalHeight);
47
+ }
48
+ }
49
+ return { maxWidth, maxHeight, totalMainSize };
50
+ }
51
+ function calculateContainerSize(props, metrics, padding, direction, gap, childCount, parentSize, parentPadding) {
52
+ let totalMainSizeWithGaps = metrics.totalMainSize;
53
+ if (direction !== "stack" && childCount > 1) {
54
+ const gapValue = direction === "row" ? gap.horizontal : gap.vertical;
55
+ totalMainSizeWithGaps += gapValue * (childCount - 1);
56
+ }
57
+ const contentWidth = direction === "row" ? totalMainSizeWithGaps + padding.left + padding.right : metrics.maxWidth + padding.left + padding.right;
58
+ const contentHeight = direction === "row" ? metrics.maxHeight + padding.top + padding.bottom : totalMainSizeWithGaps + padding.top + padding.bottom;
59
+ const parsedWidth = sizeResolver.parseSize(props.width);
60
+ let width = sizeResolver.resolveSize(parsedWidth, parentSize?.width, contentWidth, parentPadding?.horizontal);
61
+ const margin = normalizeMargin(props.margin);
62
+ if (parsedWidth.type === "fill") {
63
+ width = Math.max(0, width - getHorizontalMargin(margin));
64
+ }
65
+ const parsedHeight = sizeResolver.parseSize(props.height);
66
+ let height = sizeResolver.resolveSize(parsedHeight, parentSize?.height, contentHeight, parentPadding?.vertical);
67
+ if (parsedHeight.type === "fill") {
68
+ height = Math.max(0, height - getVerticalMargin(margin));
69
+ }
70
+ width = sizeResolver.clampSize(
71
+ width,
72
+ props.minWidth,
73
+ props.maxWidth,
74
+ parentSize?.width,
75
+ contentWidth,
76
+ void 0
77
+ // Don't use parentPadding - parentSize is already content-area
78
+ );
79
+ height = sizeResolver.clampSize(
80
+ height,
81
+ props.minHeight,
82
+ props.maxHeight,
83
+ parentSize?.height,
84
+ contentHeight,
85
+ void 0
86
+ // Don't use parentPadding - parentSize is already content-area
87
+ );
88
+ return { width, height };
89
+ }
90
+ function normalizePadding(padding) {
91
+ if (typeof padding === "number") {
92
+ return {
93
+ left: padding,
94
+ top: padding,
95
+ right: padding,
96
+ bottom: padding
97
+ };
98
+ }
99
+ return {
100
+ left: padding?.left ?? 0,
101
+ top: padding?.top ?? 0,
102
+ right: padding?.right ?? 0,
103
+ bottom: padding?.bottom ?? 0
104
+ };
105
+ }
106
+ exports.calculateContainerSize = calculateContainerSize;
107
+ exports.calculateContentDimensions = calculateContentDimensions;
108
+ exports.normalizePadding = normalizePadding;
109
+ //# sourceMappingURL=dimension-calculator.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dimension-calculator.cjs","sources":["../../../src/layout/utils/dimension-calculator.ts"],"sourcesContent":["/**\n * Dimension calculation utilities for layout system\n * Handles content size tracking and container dimension computation\n */\nimport type { EdgeInsets, LayoutProps } from '../../core-props'\nimport type { LayoutChild } from '../types'\nimport { clampSize, parseSize, resolveSize } from './size-resolver'\n\n/**\n * Content dimension metrics\n */\nexport interface ContentMetrics {\n maxWidth: number\n maxHeight: number\n totalMainSize: number\n}\n\n/**\n * Padding values (normalized)\n */\nexport interface PaddingValues {\n left: number\n top: number\n right: number\n bottom: number\n}\n\nfunction normalizeMargin(margin?: number | EdgeInsets): EdgeInsets {\n if (typeof margin === 'number') {\n return {\n left: margin,\n top: margin,\n right: margin,\n bottom: margin,\n }\n }\n return margin ?? {}\n}\n\nfunction getHorizontalMargin(margin: EdgeInsets): number {\n return (margin.left ?? 0) + (margin.right ?? 0)\n}\n\nfunction getVerticalMargin(margin: EdgeInsets): number {\n return (margin.top ?? 0) + (margin.bottom ?? 0)\n}\n\n/**\n * Calculate content dimensions based on children and layout direction\n * For flex children, uses a minimum default size to avoid chicken-egg sizing issues\n * @param children - Array of layout children with size and margin info\n * @param direction - Layout direction ('row', 'column', or 'stack')\n * @returns Content metrics including max dimensions and total main axis size\n */\nexport function calculateContentDimensions(\n children: LayoutChild[],\n direction: 'row' | 'column' | 'stack'\n): ContentMetrics {\n const FLEX_CHILD_MIN_SIZE = 100 // Minimum size for flex children in content calculation\n let maxWidth = 0\n let maxHeight = 0\n let totalMainSize = 0\n\n for (const { size, margin, child } of children) {\n const marginTop = margin.top ?? 0\n const marginBottom = margin.bottom ?? 0\n const marginLeft = margin.left ?? 0\n const marginRight = margin.right ?? 0\n\n // Check if this child has flex property\n const hasFlex = (child.__layoutProps?.flex ?? 0) > 0\n\n if (direction === 'row') {\n const childWidth = hasFlex ? FLEX_CHILD_MIN_SIZE : size.width\n totalMainSize += marginLeft + childWidth + marginRight\n const childTotalHeight = marginTop + size.height + marginBottom\n maxHeight = Math.max(maxHeight, childTotalHeight)\n } else if (direction === 'column') {\n const childTotalWidth = marginLeft + size.width + marginRight\n maxWidth = Math.max(maxWidth, childTotalWidth)\n const childHeight = hasFlex ? FLEX_CHILD_MIN_SIZE : size.height\n totalMainSize += marginTop + childHeight + marginBottom\n } else if (direction === 'stack') {\n // For stack, track max dimensions (children overlay)\n const childTotalWidth = marginLeft + size.width + marginRight\n const childTotalHeight = marginTop + size.height + marginBottom\n maxWidth = Math.max(maxWidth, childTotalWidth)\n maxHeight = Math.max(maxHeight, childTotalHeight)\n }\n }\n\n return { maxWidth, maxHeight, totalMainSize }\n}\n\n/**\n * Calculate final container dimensions\n * @param props - Layout properties\n * @param metrics - Content metrics from calculateContentDimensions\n * @param padding - Normalized padding values\n * @param direction - Layout direction\n * @param gap - Gap between children (horizontal and vertical)\n * @param childCount - Number of children\n * @param parentSize - Parent dimensions for percentage resolution\n * @param parentPadding - Parent padding for 'fill' resolution\n * @returns Container width and height in pixels\n */\nexport function calculateContainerSize(\n props: LayoutProps,\n metrics: ContentMetrics,\n padding: PaddingValues,\n direction: 'row' | 'column' | 'stack',\n gap: { horizontal: number; vertical: number },\n childCount: number,\n parentSize?: { width: number; height: number },\n parentPadding?: { horizontal: number; vertical: number }\n): { width: number; height: number } {\n // Add gaps to total main size (not applicable for stack)\n let totalMainSizeWithGaps = metrics.totalMainSize\n if (direction !== 'stack' && childCount > 1) {\n const gapValue = direction === 'row' ? gap.horizontal : gap.vertical\n totalMainSizeWithGaps += gapValue * (childCount - 1)\n }\n\n // Calculate content-based default sizes\n const contentWidth =\n direction === 'row'\n ? totalMainSizeWithGaps + padding.left + padding.right\n : metrics.maxWidth + padding.left + padding.right\n\n const contentHeight =\n direction === 'row'\n ? metrics.maxHeight + padding.top + padding.bottom\n : totalMainSizeWithGaps + padding.top + padding.bottom\n\n // Resolve width\n const parsedWidth = parseSize(props.width)\n let width = resolveSize(parsedWidth, parentSize?.width, contentWidth, parentPadding?.horizontal)\n const margin = normalizeMargin(props.margin)\n if (parsedWidth.type === 'fill') {\n width = Math.max(0, width - getHorizontalMargin(margin))\n }\n\n // Resolve height\n const parsedHeight = parseSize(props.height)\n let height = resolveSize(parsedHeight, parentSize?.height, contentHeight, parentPadding?.vertical)\n if (parsedHeight.type === 'fill') {\n height = Math.max(0, height - getVerticalMargin(margin))\n }\n\n // Apply min/max constraints to container size\n // Note: parentSize is already the content-area of the parent container (after padding),\n // so we should NOT apply parentPadding again for percentage-based constraints\n width = clampSize(\n width,\n props.minWidth,\n props.maxWidth,\n parentSize?.width,\n contentWidth,\n undefined // Don't use parentPadding - parentSize is already content-area\n )\n height = clampSize(\n height,\n props.minHeight,\n props.maxHeight,\n parentSize?.height,\n contentHeight,\n undefined // Don't use parentPadding - parentSize is already content-area\n )\n\n return { width, height }\n}\n\n/**\n * Normalize padding from EdgeInsets or number to PaddingValues\n * @param padding - Edge insets (may be undefined, partial, or a single number for all sides)\n * @returns Normalized padding with all values defined\n */\nexport function normalizePadding(padding?: number | EdgeInsets): PaddingValues {\n if (typeof padding === 'number') {\n return {\n left: padding,\n top: padding,\n right: padding,\n bottom: padding,\n }\n }\n return {\n left: padding?.left ?? 0,\n top: padding?.top ?? 0,\n right: padding?.right ?? 0,\n bottom: padding?.bottom ?? 0,\n }\n}\n"],"names":["parseSize","resolveSize","clampSize"],"mappings":"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"}