@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.
- package/LICENSE +667 -0
- package/README.md +38 -0
- package/dist/animation/animated-signal.cjs +19 -0
- package/dist/animation/animated-signal.cjs.map +1 -0
- package/dist/animation/animated-signal.d.ts +35 -0
- package/dist/animation/animated-signal.d.ts.map +1 -0
- package/dist/animation/animated-signal.js +19 -0
- package/dist/animation/animated-signal.js.map +1 -0
- package/dist/animation/create-spring.cjs +80 -0
- package/dist/animation/create-spring.cjs.map +1 -0
- package/dist/animation/create-spring.d.ts +56 -0
- package/dist/animation/create-spring.d.ts.map +1 -0
- package/dist/animation/create-spring.js +80 -0
- package/dist/animation/create-spring.js.map +1 -0
- package/dist/animation/easing.cjs +76 -0
- package/dist/animation/easing.cjs.map +1 -0
- package/dist/animation/easing.d.ts +45 -0
- package/dist/animation/easing.d.ts.map +1 -0
- package/dist/animation/easing.js +76 -0
- package/dist/animation/easing.js.map +1 -0
- package/dist/animation/effect-definitions.cjs +441 -0
- package/dist/animation/effect-definitions.cjs.map +1 -0
- package/dist/animation/effect-definitions.d.ts +60 -0
- package/dist/animation/effect-definitions.d.ts.map +1 -0
- package/dist/animation/effect-definitions.js +441 -0
- package/dist/animation/effect-definitions.js.map +1 -0
- package/dist/animation/effect-engine.cjs +189 -0
- package/dist/animation/effect-engine.cjs.map +1 -0
- package/dist/animation/effect-engine.d.ts +70 -0
- package/dist/animation/effect-engine.d.ts.map +1 -0
- package/dist/animation/effect-engine.js +189 -0
- package/dist/animation/effect-engine.js.map +1 -0
- package/dist/animation/index.d.ts +24 -0
- package/dist/animation/index.d.ts.map +1 -0
- package/dist/animation/spring-physics.cjs +94 -0
- package/dist/animation/spring-physics.cjs.map +1 -0
- package/dist/animation/spring-physics.d.ts +145 -0
- package/dist/animation/spring-physics.d.ts.map +1 -0
- package/dist/animation/spring-physics.js +94 -0
- package/dist/animation/spring-physics.js.map +1 -0
- package/dist/animation/tween.cjs +67 -0
- package/dist/animation/tween.cjs.map +1 -0
- package/dist/animation/tween.d.ts +60 -0
- package/dist/animation/tween.d.ts.map +1 -0
- package/dist/animation/tween.js +67 -0
- package/dist/animation/tween.js.map +1 -0
- package/dist/animation/types.d.ts +31 -0
- package/dist/animation/types.d.ts.map +1 -0
- package/dist/animation/useSpring.cjs +152 -0
- package/dist/animation/useSpring.cjs.map +1 -0
- package/dist/animation/useSpring.d.ts +55 -0
- package/dist/animation/useSpring.d.ts.map +1 -0
- package/dist/animation/useSpring.js +149 -0
- package/dist/animation/useSpring.js.map +1 -0
- package/dist/animation/useTween.cjs +208 -0
- package/dist/animation/useTween.cjs.map +1 -0
- package/dist/animation/useTween.d.ts +116 -0
- package/dist/animation/useTween.d.ts.map +1 -0
- package/dist/animation/useTween.js +208 -0
- package/dist/animation/useTween.js.map +1 -0
- package/dist/border-geometry.cjs +447 -0
- package/dist/border-geometry.cjs.map +1 -0
- package/dist/border-geometry.d.ts +114 -0
- package/dist/border-geometry.d.ts.map +1 -0
- package/dist/border-geometry.js +447 -0
- package/dist/border-geometry.js.map +1 -0
- package/dist/colors/color-presets.cjs +236 -0
- package/dist/colors/color-presets.cjs.map +1 -0
- package/dist/colors/color-presets.d.ts +89 -0
- package/dist/colors/color-presets.d.ts.map +1 -0
- package/dist/colors/color-presets.js +236 -0
- package/dist/colors/color-presets.js.map +1 -0
- package/dist/colors/color-theme-helpers.cjs +32 -0
- package/dist/colors/color-theme-helpers.cjs.map +1 -0
- package/dist/colors/color-theme-helpers.d.ts +65 -0
- package/dist/colors/color-theme-helpers.d.ts.map +1 -0
- package/dist/colors/color-theme-helpers.js +32 -0
- package/dist/colors/color-theme-helpers.js.map +1 -0
- package/dist/colors/color-types.cjs +38 -0
- package/dist/colors/color-types.cjs.map +1 -0
- package/dist/colors/color-types.d.ts +112 -0
- package/dist/colors/color-types.d.ts.map +1 -0
- package/dist/colors/color-types.js +38 -0
- package/dist/colors/color-types.js.map +1 -0
- package/dist/colors/color-utils.cjs +197 -0
- package/dist/colors/color-utils.cjs.map +1 -0
- package/dist/colors/color-utils.d.ts +216 -0
- package/dist/colors/color-utils.d.ts.map +1 -0
- package/dist/colors/color-utils.js +197 -0
- package/dist/colors/color-utils.js.map +1 -0
- package/dist/colors/contrast-contracts.cjs +265 -0
- package/dist/colors/contrast-contracts.cjs.map +1 -0
- package/dist/colors/contrast-contracts.d.ts +289 -0
- package/dist/colors/contrast-contracts.d.ts.map +1 -0
- package/dist/colors/contrast-contracts.js +265 -0
- package/dist/colors/contrast-contracts.js.map +1 -0
- package/dist/colors/index.cjs +55 -0
- package/dist/colors/index.cjs.map +1 -0
- package/dist/colors/index.d.ts +16 -0
- package/dist/colors/index.d.ts.map +1 -0
- package/dist/colors/index.js +55 -0
- package/dist/colors/index.js.map +1 -0
- package/dist/core-props.cjs +66 -0
- package/dist/core-props.cjs.map +1 -0
- package/dist/core-props.d.ts +395 -0
- package/dist/core-props.d.ts.map +1 -0
- package/dist/core-props.js +66 -0
- package/dist/core-props.js.map +1 -0
- package/dist/design-tokens/design-token-presets.cjs +91 -0
- package/dist/design-tokens/design-token-presets.cjs.map +1 -0
- package/dist/design-tokens/design-token-presets.d.ts +34 -0
- package/dist/design-tokens/design-token-presets.d.ts.map +1 -0
- package/dist/design-tokens/design-token-presets.js +91 -0
- package/dist/design-tokens/design-token-presets.js.map +1 -0
- package/dist/design-tokens/design-token-types.d.ts +97 -0
- package/dist/design-tokens/design-token-types.d.ts.map +1 -0
- package/dist/design-tokens/index.cjs +10 -0
- package/dist/design-tokens/index.cjs.map +1 -0
- package/dist/design-tokens/index.d.ts +9 -0
- package/dist/design-tokens/index.d.ts.map +1 -0
- package/dist/design-tokens/index.js +10 -0
- package/dist/design-tokens/index.js.map +1 -0
- package/dist/dev-config.cjs +296 -0
- package/dist/dev-config.cjs.map +1 -0
- package/dist/dev-config.d.ts +238 -0
- package/dist/dev-config.d.ts.map +1 -0
- package/dist/dev-config.js +296 -0
- package/dist/dev-config.js.map +1 -0
- package/dist/effects.cjs +69 -0
- package/dist/effects.cjs.map +1 -0
- package/dist/effects.d.ts +152 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/effects.js +69 -0
- package/dist/effects.js.map +1 -0
- package/dist/global-registry.cjs +25 -0
- package/dist/global-registry.cjs.map +1 -0
- package/dist/global-registry.d.ts +19 -0
- package/dist/global-registry.d.ts.map +1 -0
- package/dist/global-registry.js +25 -0
- package/dist/global-registry.js.map +1 -0
- package/dist/hooks.cjs +378 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.ts +322 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +378 -0
- package/dist/hooks.js.map +1 -0
- package/dist/host-adapter.d.ts +414 -0
- package/dist/host-adapter.d.ts.map +1 -0
- package/dist/index.cjs +229 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +226 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.cjs +10 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +5 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +11 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.cjs +44 -0
- package/dist/jsx-runtime.cjs.map +1 -0
- package/dist/jsx-runtime.d.ts +24 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +44 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/jsx-types.d.ts +25 -0
- package/dist/jsx-types.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.cjs +20 -0
- package/dist/layout/appliers/container-applier.cjs.map +1 -0
- package/dist/layout/appliers/container-applier.d.ts +9 -0
- package/dist/layout/appliers/container-applier.d.ts.map +1 -0
- package/dist/layout/appliers/container-applier.js +20 -0
- package/dist/layout/appliers/container-applier.js.map +1 -0
- package/dist/layout/appliers/position-applier.cjs +31 -0
- package/dist/layout/appliers/position-applier.cjs.map +1 -0
- package/dist/layout/appliers/position-applier.d.ts +8 -0
- package/dist/layout/appliers/position-applier.d.ts.map +1 -0
- package/dist/layout/appliers/position-applier.js +31 -0
- package/dist/layout/appliers/position-applier.js.map +1 -0
- package/dist/layout/layout-engine-test-utils.d.ts +26 -0
- package/dist/layout/layout-engine-test-utils.d.ts.map +1 -0
- package/dist/layout/layout-engine.cjs +628 -0
- package/dist/layout/layout-engine.cjs.map +1 -0
- package/dist/layout/layout-engine.d.ts +140 -0
- package/dist/layout/layout-engine.d.ts.map +1 -0
- package/dist/layout/layout-engine.js +628 -0
- package/dist/layout/layout-engine.js.map +1 -0
- package/dist/layout/strategies/base-strategy.cjs +31 -0
- package/dist/layout/strategies/base-strategy.cjs.map +1 -0
- package/dist/layout/strategies/base-strategy.d.ts +59 -0
- package/dist/layout/strategies/base-strategy.d.ts.map +1 -0
- package/dist/layout/strategies/base-strategy.js +31 -0
- package/dist/layout/strategies/base-strategy.js.map +1 -0
- package/dist/layout/strategies/column-layout.cjs +145 -0
- package/dist/layout/strategies/column-layout.cjs.map +1 -0
- package/dist/layout/strategies/column-layout.d.ts +38 -0
- package/dist/layout/strategies/column-layout.d.ts.map +1 -0
- package/dist/layout/strategies/column-layout.js +145 -0
- package/dist/layout/strategies/column-layout.js.map +1 -0
- package/dist/layout/strategies/row-layout.cjs +145 -0
- package/dist/layout/strategies/row-layout.cjs.map +1 -0
- package/dist/layout/strategies/row-layout.d.ts +38 -0
- package/dist/layout/strategies/row-layout.d.ts.map +1 -0
- package/dist/layout/strategies/row-layout.js +145 -0
- package/dist/layout/strategies/row-layout.js.map +1 -0
- package/dist/layout/strategies/stack-layout.cjs +94 -0
- package/dist/layout/strategies/stack-layout.cjs.map +1 -0
- package/dist/layout/strategies/stack-layout.d.ts +30 -0
- package/dist/layout/strategies/stack-layout.d.ts.map +1 -0
- package/dist/layout/strategies/stack-layout.js +94 -0
- package/dist/layout/strategies/stack-layout.js.map +1 -0
- package/dist/layout/types.d.ts +134 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.cjs +129 -0
- package/dist/layout/utils/child-utils.cjs.map +1 -0
- package/dist/layout/utils/child-utils.d.ts +54 -0
- package/dist/layout/utils/child-utils.d.ts.map +1 -0
- package/dist/layout/utils/child-utils.js +129 -0
- package/dist/layout/utils/child-utils.js.map +1 -0
- package/dist/layout/utils/dimension-calculator.cjs +109 -0
- package/dist/layout/utils/dimension-calculator.cjs.map +1 -0
- package/dist/layout/utils/dimension-calculator.d.ts +59 -0
- package/dist/layout/utils/dimension-calculator.d.ts.map +1 -0
- package/dist/layout/utils/dimension-calculator.js +109 -0
- package/dist/layout/utils/dimension-calculator.js.map +1 -0
- package/dist/layout/utils/flex-distributor.cjs +173 -0
- package/dist/layout/utils/flex-distributor.cjs.map +1 -0
- package/dist/layout/utils/flex-distributor.d.ts +18 -0
- package/dist/layout/utils/flex-distributor.d.ts.map +1 -0
- package/dist/layout/utils/flex-distributor.js +173 -0
- package/dist/layout/utils/flex-distributor.js.map +1 -0
- package/dist/layout/utils/size-resolver.cjs +280 -0
- package/dist/layout/utils/size-resolver.cjs.map +1 -0
- package/dist/layout/utils/size-resolver.d.ts +84 -0
- package/dist/layout/utils/size-resolver.d.ts.map +1 -0
- package/dist/layout/utils/size-resolver.js +280 -0
- package/dist/layout/utils/size-resolver.js.map +1 -0
- package/dist/layout/utils/spacing-calculator.cjs +50 -0
- package/dist/layout/utils/spacing-calculator.cjs.map +1 -0
- package/dist/layout/utils/spacing-calculator.d.ts +27 -0
- package/dist/layout/utils/spacing-calculator.d.ts.map +1 -0
- package/dist/layout/utils/spacing-calculator.js +50 -0
- package/dist/layout/utils/spacing-calculator.js.map +1 -0
- package/dist/memo.cjs +18 -0
- package/dist/memo.cjs.map +1 -0
- package/dist/memo.d.ts +29 -0
- package/dist/memo.d.ts.map +1 -0
- package/dist/memo.js +18 -0
- package/dist/memo.js.map +1 -0
- package/dist/nineslice-contract.cjs +60 -0
- package/dist/nineslice-contract.cjs.map +1 -0
- package/dist/nineslice-contract.d.ts +107 -0
- package/dist/nineslice-contract.d.ts.map +1 -0
- package/dist/nineslice-contract.js +60 -0
- package/dist/nineslice-contract.js.map +1 -0
- package/dist/placeholder.cjs +12 -0
- package/dist/placeholder.cjs.map +1 -0
- package/dist/placeholder.d.ts +44 -0
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/placeholder.js +12 -0
- package/dist/placeholder.js.map +1 -0
- package/dist/portal.cjs +89 -0
- package/dist/portal.cjs.map +1 -0
- package/dist/portal.d.ts +62 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +89 -0
- package/dist/portal.js.map +1 -0
- package/dist/primitive-contracts.cjs +12 -0
- package/dist/primitive-contracts.cjs.map +1 -0
- package/dist/primitive-contracts.d.ts +186 -0
- package/dist/primitive-contracts.d.ts.map +1 -0
- package/dist/primitive-contracts.js +12 -0
- package/dist/primitive-contracts.js.map +1 -0
- package/dist/theme.cjs +332 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.ts +204 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +332 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vdom/create-runtime.cjs +79 -0
- package/dist/vdom/create-runtime.cjs.map +1 -0
- package/dist/vdom/create-runtime.d.ts +7 -0
- package/dist/vdom/create-runtime.d.ts.map +1 -0
- package/dist/vdom/create-runtime.js +79 -0
- package/dist/vdom/create-runtime.js.map +1 -0
- package/dist/vdom/index.cjs +8 -0
- package/dist/vdom/index.cjs.map +1 -0
- package/dist/vdom/index.d.ts +4 -0
- package/dist/vdom/index.d.ts.map +1 -0
- package/dist/vdom/index.js +8 -0
- package/dist/vdom/index.js.map +1 -0
- package/dist/vdom/mount.cjs +161 -0
- package/dist/vdom/mount.cjs.map +1 -0
- package/dist/vdom/mount.d.ts +6 -0
- package/dist/vdom/mount.d.ts.map +1 -0
- package/dist/vdom/mount.js +161 -0
- package/dist/vdom/mount.js.map +1 -0
- package/dist/vdom/patch.cjs +163 -0
- package/dist/vdom/patch.cjs.map +1 -0
- package/dist/vdom/patch.d.ts +3 -0
- package/dist/vdom/patch.d.ts.map +1 -0
- package/dist/vdom/patch.js +163 -0
- package/dist/vdom/patch.js.map +1 -0
- package/dist/vdom/registry.cjs +85 -0
- package/dist/vdom/registry.cjs.map +1 -0
- package/dist/vdom/registry.d.ts +28 -0
- package/dist/vdom/registry.d.ts.map +1 -0
- package/dist/vdom/registry.js +85 -0
- package/dist/vdom/registry.js.map +1 -0
- package/dist/vdom/runtime-helpers.cjs +23 -0
- package/dist/vdom/runtime-helpers.cjs.map +1 -0
- package/dist/vdom/runtime-helpers.d.ts +8 -0
- package/dist/vdom/runtime-helpers.d.ts.map +1 -0
- package/dist/vdom/runtime-helpers.js +23 -0
- package/dist/vdom/runtime-helpers.js.map +1 -0
- package/dist/vdom/surface.cjs +107 -0
- package/dist/vdom/surface.cjs.map +1 -0
- package/dist/vdom/surface.d.ts +9 -0
- package/dist/vdom/surface.d.ts.map +1 -0
- package/dist/vdom/surface.js +107 -0
- package/dist/vdom/surface.js.map +1 -0
- package/dist/vdom/types.d.ts +104 -0
- package/dist/vdom/types.d.ts.map +1 -0
- package/dist/vdom/utils.cjs +146 -0
- package/dist/vdom/utils.cjs.map +1 -0
- package/dist/vdom/utils.d.ts +24 -0
- package/dist/vdom/utils.d.ts.map +1 -0
- package/dist/vdom/utils.js +146 -0
- package/dist/vdom/utils.js.map +1 -0
- package/dist/vdom.d.ts +4 -0
- package/dist/vdom.d.ts.map +1 -0
- package/dist/vector-draw-context.d.ts +63 -0
- package/dist/vector-draw-context.d.ts.map +1 -0
- package/package.json +161 -0
- package/vdom/index.cjs +1 -0
- package/vdom/index.d.ts +1 -0
- package/vdom/index.js +1 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { EdgeInsets, LayoutProps } from '../../core-props';
|
|
2
|
+
import { LayoutChild } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Content dimension metrics
|
|
5
|
+
*/
|
|
6
|
+
export interface ContentMetrics {
|
|
7
|
+
maxWidth: number;
|
|
8
|
+
maxHeight: number;
|
|
9
|
+
totalMainSize: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Padding values (normalized)
|
|
13
|
+
*/
|
|
14
|
+
export interface PaddingValues {
|
|
15
|
+
left: number;
|
|
16
|
+
top: number;
|
|
17
|
+
right: number;
|
|
18
|
+
bottom: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Calculate content dimensions based on children and layout direction
|
|
22
|
+
* For flex children, uses a minimum default size to avoid chicken-egg sizing issues
|
|
23
|
+
* @param children - Array of layout children with size and margin info
|
|
24
|
+
* @param direction - Layout direction ('row', 'column', or 'stack')
|
|
25
|
+
* @returns Content metrics including max dimensions and total main axis size
|
|
26
|
+
*/
|
|
27
|
+
export declare function calculateContentDimensions(children: LayoutChild[], direction: 'row' | 'column' | 'stack'): ContentMetrics;
|
|
28
|
+
/**
|
|
29
|
+
* Calculate final container dimensions
|
|
30
|
+
* @param props - Layout properties
|
|
31
|
+
* @param metrics - Content metrics from calculateContentDimensions
|
|
32
|
+
* @param padding - Normalized padding values
|
|
33
|
+
* @param direction - Layout direction
|
|
34
|
+
* @param gap - Gap between children (horizontal and vertical)
|
|
35
|
+
* @param childCount - Number of children
|
|
36
|
+
* @param parentSize - Parent dimensions for percentage resolution
|
|
37
|
+
* @param parentPadding - Parent padding for 'fill' resolution
|
|
38
|
+
* @returns Container width and height in pixels
|
|
39
|
+
*/
|
|
40
|
+
export declare function calculateContainerSize(props: LayoutProps, metrics: ContentMetrics, padding: PaddingValues, direction: 'row' | 'column' | 'stack', gap: {
|
|
41
|
+
horizontal: number;
|
|
42
|
+
vertical: number;
|
|
43
|
+
}, childCount: number, parentSize?: {
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
}, parentPadding?: {
|
|
47
|
+
horizontal: number;
|
|
48
|
+
vertical: number;
|
|
49
|
+
}): {
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Normalize padding from EdgeInsets or number to PaddingValues
|
|
55
|
+
* @param padding - Edge insets (may be undefined, partial, or a single number for all sides)
|
|
56
|
+
* @returns Normalized padding with all values defined
|
|
57
|
+
*/
|
|
58
|
+
export declare function normalizePadding(padding?: number | EdgeInsets): PaddingValues;
|
|
59
|
+
//# sourceMappingURL=dimension-calculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimension-calculator.d.ts","sourceRoot":"","sources":["../../../src/layout/utils/dimension-calculator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAsBD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,GACpC,cAAc,CAmChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,EACrC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC7C,UAAU,EAAE,MAAM,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,GACvD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAuDnC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAe7E"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { parseSize, resolveSize, clampSize } from "./size-resolver.js";
|
|
2
|
+
function normalizeMargin(margin) {
|
|
3
|
+
if (typeof margin === "number") {
|
|
4
|
+
return {
|
|
5
|
+
left: margin,
|
|
6
|
+
top: margin,
|
|
7
|
+
right: margin,
|
|
8
|
+
bottom: margin
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return margin ?? {};
|
|
12
|
+
}
|
|
13
|
+
function getHorizontalMargin(margin) {
|
|
14
|
+
return (margin.left ?? 0) + (margin.right ?? 0);
|
|
15
|
+
}
|
|
16
|
+
function getVerticalMargin(margin) {
|
|
17
|
+
return (margin.top ?? 0) + (margin.bottom ?? 0);
|
|
18
|
+
}
|
|
19
|
+
function calculateContentDimensions(children, direction) {
|
|
20
|
+
const FLEX_CHILD_MIN_SIZE = 100;
|
|
21
|
+
let maxWidth = 0;
|
|
22
|
+
let maxHeight = 0;
|
|
23
|
+
let totalMainSize = 0;
|
|
24
|
+
for (const { size, margin, child } of children) {
|
|
25
|
+
const marginTop = margin.top ?? 0;
|
|
26
|
+
const marginBottom = margin.bottom ?? 0;
|
|
27
|
+
const marginLeft = margin.left ?? 0;
|
|
28
|
+
const marginRight = margin.right ?? 0;
|
|
29
|
+
const hasFlex = (child.__layoutProps?.flex ?? 0) > 0;
|
|
30
|
+
if (direction === "row") {
|
|
31
|
+
const childWidth = hasFlex ? FLEX_CHILD_MIN_SIZE : size.width;
|
|
32
|
+
totalMainSize += marginLeft + childWidth + marginRight;
|
|
33
|
+
const childTotalHeight = marginTop + size.height + marginBottom;
|
|
34
|
+
maxHeight = Math.max(maxHeight, childTotalHeight);
|
|
35
|
+
} else if (direction === "column") {
|
|
36
|
+
const childTotalWidth = marginLeft + size.width + marginRight;
|
|
37
|
+
maxWidth = Math.max(maxWidth, childTotalWidth);
|
|
38
|
+
const childHeight = hasFlex ? FLEX_CHILD_MIN_SIZE : size.height;
|
|
39
|
+
totalMainSize += marginTop + childHeight + marginBottom;
|
|
40
|
+
} else if (direction === "stack") {
|
|
41
|
+
const childTotalWidth = marginLeft + size.width + marginRight;
|
|
42
|
+
const childTotalHeight = marginTop + size.height + marginBottom;
|
|
43
|
+
maxWidth = Math.max(maxWidth, childTotalWidth);
|
|
44
|
+
maxHeight = Math.max(maxHeight, childTotalHeight);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { maxWidth, maxHeight, totalMainSize };
|
|
48
|
+
}
|
|
49
|
+
function calculateContainerSize(props, metrics, padding, direction, gap, childCount, parentSize, parentPadding) {
|
|
50
|
+
let totalMainSizeWithGaps = metrics.totalMainSize;
|
|
51
|
+
if (direction !== "stack" && childCount > 1) {
|
|
52
|
+
const gapValue = direction === "row" ? gap.horizontal : gap.vertical;
|
|
53
|
+
totalMainSizeWithGaps += gapValue * (childCount - 1);
|
|
54
|
+
}
|
|
55
|
+
const contentWidth = direction === "row" ? totalMainSizeWithGaps + padding.left + padding.right : metrics.maxWidth + padding.left + padding.right;
|
|
56
|
+
const contentHeight = direction === "row" ? metrics.maxHeight + padding.top + padding.bottom : totalMainSizeWithGaps + padding.top + padding.bottom;
|
|
57
|
+
const parsedWidth = parseSize(props.width);
|
|
58
|
+
let width = resolveSize(parsedWidth, parentSize?.width, contentWidth, parentPadding?.horizontal);
|
|
59
|
+
const margin = normalizeMargin(props.margin);
|
|
60
|
+
if (parsedWidth.type === "fill") {
|
|
61
|
+
width = Math.max(0, width - getHorizontalMargin(margin));
|
|
62
|
+
}
|
|
63
|
+
const parsedHeight = parseSize(props.height);
|
|
64
|
+
let height = resolveSize(parsedHeight, parentSize?.height, contentHeight, parentPadding?.vertical);
|
|
65
|
+
if (parsedHeight.type === "fill") {
|
|
66
|
+
height = Math.max(0, height - getVerticalMargin(margin));
|
|
67
|
+
}
|
|
68
|
+
width = clampSize(
|
|
69
|
+
width,
|
|
70
|
+
props.minWidth,
|
|
71
|
+
props.maxWidth,
|
|
72
|
+
parentSize?.width,
|
|
73
|
+
contentWidth,
|
|
74
|
+
void 0
|
|
75
|
+
// Don't use parentPadding - parentSize is already content-area
|
|
76
|
+
);
|
|
77
|
+
height = clampSize(
|
|
78
|
+
height,
|
|
79
|
+
props.minHeight,
|
|
80
|
+
props.maxHeight,
|
|
81
|
+
parentSize?.height,
|
|
82
|
+
contentHeight,
|
|
83
|
+
void 0
|
|
84
|
+
// Don't use parentPadding - parentSize is already content-area
|
|
85
|
+
);
|
|
86
|
+
return { width, height };
|
|
87
|
+
}
|
|
88
|
+
function normalizePadding(padding) {
|
|
89
|
+
if (typeof padding === "number") {
|
|
90
|
+
return {
|
|
91
|
+
left: padding,
|
|
92
|
+
top: padding,
|
|
93
|
+
right: padding,
|
|
94
|
+
bottom: padding
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
left: padding?.left ?? 0,
|
|
99
|
+
top: padding?.top ?? 0,
|
|
100
|
+
right: padding?.right ?? 0,
|
|
101
|
+
bottom: padding?.bottom ?? 0
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
calculateContainerSize,
|
|
106
|
+
calculateContentDimensions,
|
|
107
|
+
normalizePadding
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=dimension-calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimension-calculator.js","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":[],"mappings":"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"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const sizeResolver = require("./size-resolver.cjs");
|
|
4
|
+
function distributeFlexSpace(children, availableSpace, direction) {
|
|
5
|
+
if (direction === "stack") {
|
|
6
|
+
return children;
|
|
7
|
+
}
|
|
8
|
+
const flexItems = [];
|
|
9
|
+
let nonFlexSpace = 0;
|
|
10
|
+
children.forEach((layoutChild, index) => {
|
|
11
|
+
const props = layoutChild.child.__layoutProps;
|
|
12
|
+
const hasExplicitFlex = props?.flex !== void 0;
|
|
13
|
+
const hasExplicitShrink = props?.flexShrink !== void 0;
|
|
14
|
+
const hasExplicitBasis = props?.flexBasis !== void 0;
|
|
15
|
+
const flexGrow = props?.flex ?? 0;
|
|
16
|
+
const flexShrink = props?.flexShrink !== void 0 ? props.flexShrink : hasExplicitFlex || hasExplicitBasis ? 1 : 0;
|
|
17
|
+
const flexBasis = props?.flexBasis;
|
|
18
|
+
const margin = layoutChild.margin;
|
|
19
|
+
const marginSize = direction === "row" ? (margin.left ?? 0) + (margin.right ?? 0) : (margin.top ?? 0) + (margin.bottom ?? 0);
|
|
20
|
+
const minSizeValue = direction === "row" ? props?.minWidth : props?.minHeight;
|
|
21
|
+
const maxSizeValue = direction === "row" ? props?.maxWidth : props?.maxHeight;
|
|
22
|
+
const currentSize = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
23
|
+
const minSize = minSizeValue !== void 0 ? sizeResolver.resolveSize(sizeResolver.parseSize(minSizeValue), availableSpace, currentSize, void 0) : void 0;
|
|
24
|
+
const maxSize = maxSizeValue !== void 0 ? sizeResolver.resolveSize(sizeResolver.parseSize(maxSizeValue), availableSpace, currentSize, void 0) : void 0;
|
|
25
|
+
let basisSize;
|
|
26
|
+
if (flexBasis !== void 0) {
|
|
27
|
+
const parsedBasis = sizeResolver.parseSize(flexBasis);
|
|
28
|
+
const currentSize2 = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
29
|
+
basisSize = sizeResolver.resolveSize(parsedBasis, availableSpace, currentSize2, void 0);
|
|
30
|
+
} else {
|
|
31
|
+
basisSize = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
32
|
+
}
|
|
33
|
+
const isFlexItem = hasExplicitFlex || hasExplicitShrink || hasExplicitBasis;
|
|
34
|
+
if (isFlexItem) {
|
|
35
|
+
flexItems.push({
|
|
36
|
+
child: layoutChild,
|
|
37
|
+
index,
|
|
38
|
+
flexGrow,
|
|
39
|
+
flexShrink,
|
|
40
|
+
flexBasis: basisSize,
|
|
41
|
+
minSize,
|
|
42
|
+
maxSize,
|
|
43
|
+
isFrozen: false,
|
|
44
|
+
targetSize: basisSize
|
|
45
|
+
});
|
|
46
|
+
nonFlexSpace += marginSize;
|
|
47
|
+
} else {
|
|
48
|
+
const size = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
49
|
+
nonFlexSpace += size + marginSize;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (flexItems.length === 0) {
|
|
53
|
+
return children;
|
|
54
|
+
}
|
|
55
|
+
let totalFlexBasis = flexItems.reduce((sum, item) => sum + item.flexBasis, 0);
|
|
56
|
+
let freeSpace = availableSpace - nonFlexSpace - totalFlexBasis;
|
|
57
|
+
const updatedChildren = [...children];
|
|
58
|
+
if (freeSpace > 0) {
|
|
59
|
+
distributeGrow(flexItems, freeSpace);
|
|
60
|
+
} else if (freeSpace < 0) {
|
|
61
|
+
distributeShrink(flexItems, freeSpace);
|
|
62
|
+
} else {
|
|
63
|
+
flexItems.forEach((item) => {
|
|
64
|
+
item.targetSize = item.flexBasis;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
flexItems.forEach((item) => {
|
|
68
|
+
if (direction === "row") {
|
|
69
|
+
updatedChildren[item.index] = {
|
|
70
|
+
...item.child,
|
|
71
|
+
size: {
|
|
72
|
+
...item.child.size,
|
|
73
|
+
width: item.targetSize
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
} else {
|
|
77
|
+
updatedChildren[item.index] = {
|
|
78
|
+
...item.child,
|
|
79
|
+
size: {
|
|
80
|
+
...item.child.size,
|
|
81
|
+
height: item.targetSize
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return updatedChildren;
|
|
87
|
+
}
|
|
88
|
+
function distributeGrow(flexItems, freeSpace) {
|
|
89
|
+
let remainingSpace = freeSpace;
|
|
90
|
+
const MAX_ITERATIONS = 10;
|
|
91
|
+
for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
92
|
+
const totalFlexGrow = flexItems.filter((item) => !item.isFrozen).reduce((sum, item) => sum + item.flexGrow, 0);
|
|
93
|
+
if (totalFlexGrow === 0 || remainingSpace <= 0) {
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
let hasViolations = false;
|
|
97
|
+
for (const item of flexItems) {
|
|
98
|
+
if (item.isFrozen) continue;
|
|
99
|
+
const growShare = remainingSpace * item.flexGrow / totalFlexGrow;
|
|
100
|
+
let targetSize = item.flexBasis + growShare;
|
|
101
|
+
if (item.minSize !== void 0 && targetSize < item.minSize) {
|
|
102
|
+
targetSize = item.minSize;
|
|
103
|
+
item.isFrozen = true;
|
|
104
|
+
hasViolations = true;
|
|
105
|
+
} else if (item.maxSize !== void 0 && targetSize > item.maxSize) {
|
|
106
|
+
targetSize = item.maxSize;
|
|
107
|
+
item.isFrozen = true;
|
|
108
|
+
hasViolations = true;
|
|
109
|
+
}
|
|
110
|
+
item.targetSize = targetSize;
|
|
111
|
+
}
|
|
112
|
+
if (!hasViolations) {
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
remainingSpace = freeSpace;
|
|
116
|
+
for (const item of flexItems) {
|
|
117
|
+
if (item.isFrozen) {
|
|
118
|
+
remainingSpace -= item.targetSize - item.flexBasis;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const item of flexItems) {
|
|
123
|
+
if (!item.isFrozen) ;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function distributeShrink(flexItems, freeSpace) {
|
|
127
|
+
let remainingSpace = Math.abs(freeSpace);
|
|
128
|
+
const MAX_ITERATIONS = 10;
|
|
129
|
+
for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
130
|
+
const totalScaledShrink = flexItems.filter((item) => !item.isFrozen).reduce((sum, item) => sum + item.flexShrink * item.flexBasis, 0);
|
|
131
|
+
if (totalScaledShrink === 0 || remainingSpace <= 0) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
let hasViolations = false;
|
|
135
|
+
for (const item of flexItems) {
|
|
136
|
+
if (item.isFrozen) continue;
|
|
137
|
+
const scaledShrink = item.flexShrink * item.flexBasis;
|
|
138
|
+
const shrinkShare = remainingSpace * scaledShrink / totalScaledShrink;
|
|
139
|
+
let targetSize = item.flexBasis - shrinkShare;
|
|
140
|
+
if (item.minSize !== void 0 && targetSize < item.minSize) {
|
|
141
|
+
targetSize = item.minSize;
|
|
142
|
+
item.isFrozen = true;
|
|
143
|
+
hasViolations = true;
|
|
144
|
+
} else if (item.maxSize !== void 0 && targetSize > item.maxSize) {
|
|
145
|
+
targetSize = item.maxSize;
|
|
146
|
+
item.isFrozen = true;
|
|
147
|
+
hasViolations = true;
|
|
148
|
+
}
|
|
149
|
+
item.targetSize = targetSize;
|
|
150
|
+
}
|
|
151
|
+
if (!hasViolations) {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
remainingSpace = Math.abs(freeSpace);
|
|
155
|
+
for (const item of flexItems) {
|
|
156
|
+
if (item.isFrozen) {
|
|
157
|
+
remainingSpace -= item.flexBasis - item.targetSize;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (const item of flexItems) {
|
|
162
|
+
if (!item.isFrozen) ;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function hasFlexChildren(children) {
|
|
166
|
+
return children.some((child) => {
|
|
167
|
+
const props = child.child.__layoutProps;
|
|
168
|
+
return props?.flex !== void 0 && props.flex > 0 || props?.flexShrink !== void 0 || props?.flexBasis !== void 0;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
exports.distributeFlexSpace = distributeFlexSpace;
|
|
172
|
+
exports.hasFlexChildren = hasFlexChildren;
|
|
173
|
+
//# sourceMappingURL=flex-distributor.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex-distributor.cjs","sources":["../../../src/layout/utils/flex-distributor.ts"],"sourcesContent":["/**\n * Flex distribution utilities - handles flexbox logic (grow, shrink, basis) for layout children\n */\nimport type { LayoutChild } from '../types'\nimport { parseSize, resolveSize } from './size-resolver'\n\n/**\n * Flex item data structure\n */\ninterface FlexItem {\n child: LayoutChild\n index: number\n flexGrow: number\n flexShrink: number\n flexBasis: number\n minSize: number | undefined\n maxSize: number | undefined\n isFrozen: boolean\n targetSize: number\n}\n\n/**\n * Calculate flex distribution for children\n * Implements flexbox algorithm with grow, shrink, and basis support\n * Respects min/max constraints during distribution\n * @param children - Layout children\n * @param availableSpace - Total available space on main axis\n * @param direction - Layout direction ('row' or 'column')\n * @returns Updated children with flex sizes resolved\n */\nexport function distributeFlexSpace(\n children: LayoutChild[],\n availableSpace: number,\n direction: 'row' | 'column' | 'stack'\n): LayoutChild[] {\n if (direction === 'stack') {\n return children // Stack doesn't use flex\n }\n\n // Phase 1: Identify flex items and non-flex items\n const flexItems: FlexItem[] = []\n let nonFlexSpace = 0\n\n children.forEach((layoutChild, index) => {\n const props = layoutChild.child.__layoutProps\n const hasExplicitFlex = props?.flex !== undefined\n const hasExplicitShrink = props?.flexShrink !== undefined\n const hasExplicitBasis = props?.flexBasis !== undefined\n\n const flexGrow = props?.flex ?? 0\n // Only default flexShrink to 1 if element explicitly participates in flex\n const flexShrink =\n props?.flexShrink !== undefined\n ? props.flexShrink\n : hasExplicitFlex || hasExplicitBasis\n ? 1\n : 0\n const flexBasis = props?.flexBasis\n\n const margin = layoutChild.margin\n const marginSize =\n direction === 'row'\n ? (margin.left ?? 0) + (margin.right ?? 0)\n : (margin.top ?? 0) + (margin.bottom ?? 0)\n\n // Resolve min/max constraints from SizeValue to pixels\n const minSizeValue = direction === 'row' ? props?.minWidth : props?.minHeight\n const maxSizeValue = direction === 'row' ? props?.maxWidth : props?.maxHeight\n const currentSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n\n const minSize =\n minSizeValue !== undefined\n ? resolveSize(parseSize(minSizeValue), availableSpace, currentSize, undefined)\n : undefined\n const maxSize =\n maxSizeValue !== undefined\n ? resolveSize(parseSize(maxSizeValue), availableSpace, currentSize, undefined)\n : undefined\n\n // Calculate flex-basis\n let basisSize: number\n if (flexBasis !== undefined) {\n // Use explicit flex-basis\n const parsedBasis = parseSize(flexBasis)\n const currentSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n basisSize = resolveSize(parsedBasis, availableSpace, currentSize, undefined)\n } else {\n // Use width/height as flex-basis\n basisSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n }\n\n // Determine if this is a flex item\n // An item is a flex item if it explicitly sets flex, flexShrink, or flexBasis\n const isFlexItem = hasExplicitFlex || hasExplicitShrink || hasExplicitBasis\n\n if (isFlexItem) {\n flexItems.push({\n child: layoutChild,\n index,\n flexGrow,\n flexShrink,\n flexBasis: basisSize,\n minSize,\n maxSize,\n isFrozen: false,\n targetSize: basisSize,\n })\n\n nonFlexSpace += marginSize\n } else {\n // Non-flex item - uses its current size\n const size = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n nonFlexSpace += size + marginSize\n }\n })\n\n // No flex items - return as is\n if (flexItems.length === 0) {\n return children\n }\n\n // Phase 2: Calculate total flex-basis\n let totalFlexBasis = flexItems.reduce((sum, item) => sum + item.flexBasis, 0)\n let freeSpace = availableSpace - nonFlexSpace - totalFlexBasis\n\n // Phase 3: Flex distribution (grow or shrink)\n const updatedChildren = [...children]\n\n if (freeSpace > 0) {\n // GROW: Distribute positive free space\n distributeGrow(flexItems, freeSpace)\n } else if (freeSpace < 0) {\n // SHRINK: Distribute negative free space\n distributeShrink(flexItems, freeSpace)\n } else {\n // Exact fit - use flex-basis\n flexItems.forEach((item) => {\n item.targetSize = item.flexBasis\n })\n }\n\n // Phase 4: Apply calculated sizes\n flexItems.forEach((item) => {\n if (direction === 'row') {\n updatedChildren[item.index] = {\n ...item.child,\n size: {\n ...item.child.size,\n width: item.targetSize,\n },\n }\n } else {\n updatedChildren[item.index] = {\n ...item.child,\n size: {\n ...item.child.size,\n height: item.targetSize,\n },\n }\n }\n })\n\n return updatedChildren\n}\n\n/**\n * Distribute positive free space using flex-grow\n * @param flexItems - Flex items to distribute space among\n * @param freeSpace - Positive free space to distribute\n */\nfunction distributeGrow(flexItems: FlexItem[], freeSpace: number): void {\n let remainingSpace = freeSpace\n const MAX_ITERATIONS = 10\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n // Calculate total flex-grow of unfrozen items\n const totalFlexGrow = flexItems\n .filter((item) => !item.isFrozen)\n .reduce((sum, item) => sum + item.flexGrow, 0)\n\n if (totalFlexGrow === 0 || remainingSpace <= 0) {\n break\n }\n\n let hasViolations = false\n\n // Distribute space proportionally\n for (const item of flexItems) {\n if (item.isFrozen) continue\n\n const growShare = (remainingSpace * item.flexGrow) / totalFlexGrow\n let targetSize = item.flexBasis + growShare\n\n // Apply min/max constraints\n if (item.minSize !== undefined && targetSize < item.minSize) {\n targetSize = item.minSize\n item.isFrozen = true\n hasViolations = true\n } else if (item.maxSize !== undefined && targetSize > item.maxSize) {\n targetSize = item.maxSize\n item.isFrozen = true\n hasViolations = true\n }\n\n item.targetSize = targetSize\n }\n\n if (!hasViolations) {\n break // All items distributed without violations\n }\n\n // Recalculate remaining space for next iteration\n remainingSpace = freeSpace\n for (const item of flexItems) {\n if (item.isFrozen) {\n remainingSpace -= item.targetSize - item.flexBasis\n }\n }\n }\n\n // Set targetSize for any remaining unfrozen items\n for (const item of flexItems) {\n if (!item.isFrozen) {\n // Already set in loop\n }\n }\n}\n\n/**\n * Distribute negative free space using flex-shrink\n * @param flexItems - Flex items to shrink\n * @param freeSpace - Negative free space (deficit)\n */\nfunction distributeShrink(flexItems: FlexItem[], freeSpace: number): void {\n let remainingSpace = Math.abs(freeSpace)\n const MAX_ITERATIONS = 10\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n // Calculate scaled flex-shrink (shrink * basis)\n const totalScaledShrink = flexItems\n .filter((item) => !item.isFrozen)\n .reduce((sum, item) => sum + item.flexShrink * item.flexBasis, 0)\n\n if (totalScaledShrink === 0 || remainingSpace <= 0) {\n break\n }\n\n let hasViolations = false\n\n // Distribute shrinkage proportionally\n for (const item of flexItems) {\n if (item.isFrozen) continue\n\n const scaledShrink = item.flexShrink * item.flexBasis\n const shrinkShare = (remainingSpace * scaledShrink) / totalScaledShrink\n let targetSize = item.flexBasis - shrinkShare\n\n // Apply min/max constraints\n if (item.minSize !== undefined && targetSize < item.minSize) {\n targetSize = item.minSize\n item.isFrozen = true\n hasViolations = true\n } else if (item.maxSize !== undefined && targetSize > item.maxSize) {\n targetSize = item.maxSize\n item.isFrozen = true\n hasViolations = true\n }\n\n item.targetSize = targetSize\n }\n\n if (!hasViolations) {\n break // All items shrunk without violations\n }\n\n // Recalculate remaining space for next iteration\n remainingSpace = Math.abs(freeSpace)\n for (const item of flexItems) {\n if (item.isFrozen) {\n remainingSpace -= item.flexBasis - item.targetSize\n }\n }\n }\n\n // Set targetSize for any remaining unfrozen items\n for (const item of flexItems) {\n if (!item.isFrozen) {\n // Already set in loop\n }\n }\n}\n\n/**\n * Check if any children have flex properties (flex, flexShrink, or flexBasis)\n * @param children - Layout children\n * @returns True if at least one child participates in flexbox\n */\nexport function hasFlexChildren(children: LayoutChild[]): boolean {\n return children.some((child) => {\n const props = child.child.__layoutProps\n return (\n (props?.flex !== undefined && props.flex > 0) ||\n props?.flexShrink !== undefined ||\n props?.flexBasis !== undefined\n )\n })\n}\n"],"names":["resolveSize","parseSize","currentSize"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LayoutChild } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate flex distribution for children
|
|
4
|
+
* Implements flexbox algorithm with grow, shrink, and basis support
|
|
5
|
+
* Respects min/max constraints during distribution
|
|
6
|
+
* @param children - Layout children
|
|
7
|
+
* @param availableSpace - Total available space on main axis
|
|
8
|
+
* @param direction - Layout direction ('row' or 'column')
|
|
9
|
+
* @returns Updated children with flex sizes resolved
|
|
10
|
+
*/
|
|
11
|
+
export declare function distributeFlexSpace(children: LayoutChild[], availableSpace: number, direction: 'row' | 'column' | 'stack'): LayoutChild[];
|
|
12
|
+
/**
|
|
13
|
+
* Check if any children have flex properties (flex, flexShrink, or flexBasis)
|
|
14
|
+
* @param children - Layout children
|
|
15
|
+
* @returns True if at least one child participates in flexbox
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasFlexChildren(children: LayoutChild[]): boolean;
|
|
18
|
+
//# sourceMappingURL=flex-distributor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex-distributor.d.ts","sourceRoot":"","sources":["../../../src/layout/utils/flex-distributor.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAkB3C;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,GACpC,WAAW,EAAE,CAiIf;AAiID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAShE"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { resolveSize, parseSize } from "./size-resolver.js";
|
|
2
|
+
function distributeFlexSpace(children, availableSpace, direction) {
|
|
3
|
+
if (direction === "stack") {
|
|
4
|
+
return children;
|
|
5
|
+
}
|
|
6
|
+
const flexItems = [];
|
|
7
|
+
let nonFlexSpace = 0;
|
|
8
|
+
children.forEach((layoutChild, index) => {
|
|
9
|
+
const props = layoutChild.child.__layoutProps;
|
|
10
|
+
const hasExplicitFlex = props?.flex !== void 0;
|
|
11
|
+
const hasExplicitShrink = props?.flexShrink !== void 0;
|
|
12
|
+
const hasExplicitBasis = props?.flexBasis !== void 0;
|
|
13
|
+
const flexGrow = props?.flex ?? 0;
|
|
14
|
+
const flexShrink = props?.flexShrink !== void 0 ? props.flexShrink : hasExplicitFlex || hasExplicitBasis ? 1 : 0;
|
|
15
|
+
const flexBasis = props?.flexBasis;
|
|
16
|
+
const margin = layoutChild.margin;
|
|
17
|
+
const marginSize = direction === "row" ? (margin.left ?? 0) + (margin.right ?? 0) : (margin.top ?? 0) + (margin.bottom ?? 0);
|
|
18
|
+
const minSizeValue = direction === "row" ? props?.minWidth : props?.minHeight;
|
|
19
|
+
const maxSizeValue = direction === "row" ? props?.maxWidth : props?.maxHeight;
|
|
20
|
+
const currentSize = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
21
|
+
const minSize = minSizeValue !== void 0 ? resolveSize(parseSize(minSizeValue), availableSpace, currentSize, void 0) : void 0;
|
|
22
|
+
const maxSize = maxSizeValue !== void 0 ? resolveSize(parseSize(maxSizeValue), availableSpace, currentSize, void 0) : void 0;
|
|
23
|
+
let basisSize;
|
|
24
|
+
if (flexBasis !== void 0) {
|
|
25
|
+
const parsedBasis = parseSize(flexBasis);
|
|
26
|
+
const currentSize2 = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
27
|
+
basisSize = resolveSize(parsedBasis, availableSpace, currentSize2, void 0);
|
|
28
|
+
} else {
|
|
29
|
+
basisSize = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
30
|
+
}
|
|
31
|
+
const isFlexItem = hasExplicitFlex || hasExplicitShrink || hasExplicitBasis;
|
|
32
|
+
if (isFlexItem) {
|
|
33
|
+
flexItems.push({
|
|
34
|
+
child: layoutChild,
|
|
35
|
+
index,
|
|
36
|
+
flexGrow,
|
|
37
|
+
flexShrink,
|
|
38
|
+
flexBasis: basisSize,
|
|
39
|
+
minSize,
|
|
40
|
+
maxSize,
|
|
41
|
+
isFrozen: false,
|
|
42
|
+
targetSize: basisSize
|
|
43
|
+
});
|
|
44
|
+
nonFlexSpace += marginSize;
|
|
45
|
+
} else {
|
|
46
|
+
const size = direction === "row" ? layoutChild.size.width : layoutChild.size.height;
|
|
47
|
+
nonFlexSpace += size + marginSize;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
if (flexItems.length === 0) {
|
|
51
|
+
return children;
|
|
52
|
+
}
|
|
53
|
+
let totalFlexBasis = flexItems.reduce((sum, item) => sum + item.flexBasis, 0);
|
|
54
|
+
let freeSpace = availableSpace - nonFlexSpace - totalFlexBasis;
|
|
55
|
+
const updatedChildren = [...children];
|
|
56
|
+
if (freeSpace > 0) {
|
|
57
|
+
distributeGrow(flexItems, freeSpace);
|
|
58
|
+
} else if (freeSpace < 0) {
|
|
59
|
+
distributeShrink(flexItems, freeSpace);
|
|
60
|
+
} else {
|
|
61
|
+
flexItems.forEach((item) => {
|
|
62
|
+
item.targetSize = item.flexBasis;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
flexItems.forEach((item) => {
|
|
66
|
+
if (direction === "row") {
|
|
67
|
+
updatedChildren[item.index] = {
|
|
68
|
+
...item.child,
|
|
69
|
+
size: {
|
|
70
|
+
...item.child.size,
|
|
71
|
+
width: item.targetSize
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
updatedChildren[item.index] = {
|
|
76
|
+
...item.child,
|
|
77
|
+
size: {
|
|
78
|
+
...item.child.size,
|
|
79
|
+
height: item.targetSize
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return updatedChildren;
|
|
85
|
+
}
|
|
86
|
+
function distributeGrow(flexItems, freeSpace) {
|
|
87
|
+
let remainingSpace = freeSpace;
|
|
88
|
+
const MAX_ITERATIONS = 10;
|
|
89
|
+
for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
90
|
+
const totalFlexGrow = flexItems.filter((item) => !item.isFrozen).reduce((sum, item) => sum + item.flexGrow, 0);
|
|
91
|
+
if (totalFlexGrow === 0 || remainingSpace <= 0) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
let hasViolations = false;
|
|
95
|
+
for (const item of flexItems) {
|
|
96
|
+
if (item.isFrozen) continue;
|
|
97
|
+
const growShare = remainingSpace * item.flexGrow / totalFlexGrow;
|
|
98
|
+
let targetSize = item.flexBasis + growShare;
|
|
99
|
+
if (item.minSize !== void 0 && targetSize < item.minSize) {
|
|
100
|
+
targetSize = item.minSize;
|
|
101
|
+
item.isFrozen = true;
|
|
102
|
+
hasViolations = true;
|
|
103
|
+
} else if (item.maxSize !== void 0 && targetSize > item.maxSize) {
|
|
104
|
+
targetSize = item.maxSize;
|
|
105
|
+
item.isFrozen = true;
|
|
106
|
+
hasViolations = true;
|
|
107
|
+
}
|
|
108
|
+
item.targetSize = targetSize;
|
|
109
|
+
}
|
|
110
|
+
if (!hasViolations) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
remainingSpace = freeSpace;
|
|
114
|
+
for (const item of flexItems) {
|
|
115
|
+
if (item.isFrozen) {
|
|
116
|
+
remainingSpace -= item.targetSize - item.flexBasis;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const item of flexItems) {
|
|
121
|
+
if (!item.isFrozen) ;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function distributeShrink(flexItems, freeSpace) {
|
|
125
|
+
let remainingSpace = Math.abs(freeSpace);
|
|
126
|
+
const MAX_ITERATIONS = 10;
|
|
127
|
+
for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
128
|
+
const totalScaledShrink = flexItems.filter((item) => !item.isFrozen).reduce((sum, item) => sum + item.flexShrink * item.flexBasis, 0);
|
|
129
|
+
if (totalScaledShrink === 0 || remainingSpace <= 0) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
let hasViolations = false;
|
|
133
|
+
for (const item of flexItems) {
|
|
134
|
+
if (item.isFrozen) continue;
|
|
135
|
+
const scaledShrink = item.flexShrink * item.flexBasis;
|
|
136
|
+
const shrinkShare = remainingSpace * scaledShrink / totalScaledShrink;
|
|
137
|
+
let targetSize = item.flexBasis - shrinkShare;
|
|
138
|
+
if (item.minSize !== void 0 && targetSize < item.minSize) {
|
|
139
|
+
targetSize = item.minSize;
|
|
140
|
+
item.isFrozen = true;
|
|
141
|
+
hasViolations = true;
|
|
142
|
+
} else if (item.maxSize !== void 0 && targetSize > item.maxSize) {
|
|
143
|
+
targetSize = item.maxSize;
|
|
144
|
+
item.isFrozen = true;
|
|
145
|
+
hasViolations = true;
|
|
146
|
+
}
|
|
147
|
+
item.targetSize = targetSize;
|
|
148
|
+
}
|
|
149
|
+
if (!hasViolations) {
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
remainingSpace = Math.abs(freeSpace);
|
|
153
|
+
for (const item of flexItems) {
|
|
154
|
+
if (item.isFrozen) {
|
|
155
|
+
remainingSpace -= item.flexBasis - item.targetSize;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const item of flexItems) {
|
|
160
|
+
if (!item.isFrozen) ;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function hasFlexChildren(children) {
|
|
164
|
+
return children.some((child) => {
|
|
165
|
+
const props = child.child.__layoutProps;
|
|
166
|
+
return props?.flex !== void 0 && props.flex > 0 || props?.flexShrink !== void 0 || props?.flexBasis !== void 0;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
export {
|
|
170
|
+
distributeFlexSpace,
|
|
171
|
+
hasFlexChildren
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=flex-distributor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex-distributor.js","sources":["../../../src/layout/utils/flex-distributor.ts"],"sourcesContent":["/**\n * Flex distribution utilities - handles flexbox logic (grow, shrink, basis) for layout children\n */\nimport type { LayoutChild } from '../types'\nimport { parseSize, resolveSize } from './size-resolver'\n\n/**\n * Flex item data structure\n */\ninterface FlexItem {\n child: LayoutChild\n index: number\n flexGrow: number\n flexShrink: number\n flexBasis: number\n minSize: number | undefined\n maxSize: number | undefined\n isFrozen: boolean\n targetSize: number\n}\n\n/**\n * Calculate flex distribution for children\n * Implements flexbox algorithm with grow, shrink, and basis support\n * Respects min/max constraints during distribution\n * @param children - Layout children\n * @param availableSpace - Total available space on main axis\n * @param direction - Layout direction ('row' or 'column')\n * @returns Updated children with flex sizes resolved\n */\nexport function distributeFlexSpace(\n children: LayoutChild[],\n availableSpace: number,\n direction: 'row' | 'column' | 'stack'\n): LayoutChild[] {\n if (direction === 'stack') {\n return children // Stack doesn't use flex\n }\n\n // Phase 1: Identify flex items and non-flex items\n const flexItems: FlexItem[] = []\n let nonFlexSpace = 0\n\n children.forEach((layoutChild, index) => {\n const props = layoutChild.child.__layoutProps\n const hasExplicitFlex = props?.flex !== undefined\n const hasExplicitShrink = props?.flexShrink !== undefined\n const hasExplicitBasis = props?.flexBasis !== undefined\n\n const flexGrow = props?.flex ?? 0\n // Only default flexShrink to 1 if element explicitly participates in flex\n const flexShrink =\n props?.flexShrink !== undefined\n ? props.flexShrink\n : hasExplicitFlex || hasExplicitBasis\n ? 1\n : 0\n const flexBasis = props?.flexBasis\n\n const margin = layoutChild.margin\n const marginSize =\n direction === 'row'\n ? (margin.left ?? 0) + (margin.right ?? 0)\n : (margin.top ?? 0) + (margin.bottom ?? 0)\n\n // Resolve min/max constraints from SizeValue to pixels\n const minSizeValue = direction === 'row' ? props?.minWidth : props?.minHeight\n const maxSizeValue = direction === 'row' ? props?.maxWidth : props?.maxHeight\n const currentSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n\n const minSize =\n minSizeValue !== undefined\n ? resolveSize(parseSize(minSizeValue), availableSpace, currentSize, undefined)\n : undefined\n const maxSize =\n maxSizeValue !== undefined\n ? resolveSize(parseSize(maxSizeValue), availableSpace, currentSize, undefined)\n : undefined\n\n // Calculate flex-basis\n let basisSize: number\n if (flexBasis !== undefined) {\n // Use explicit flex-basis\n const parsedBasis = parseSize(flexBasis)\n const currentSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n basisSize = resolveSize(parsedBasis, availableSpace, currentSize, undefined)\n } else {\n // Use width/height as flex-basis\n basisSize = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n }\n\n // Determine if this is a flex item\n // An item is a flex item if it explicitly sets flex, flexShrink, or flexBasis\n const isFlexItem = hasExplicitFlex || hasExplicitShrink || hasExplicitBasis\n\n if (isFlexItem) {\n flexItems.push({\n child: layoutChild,\n index,\n flexGrow,\n flexShrink,\n flexBasis: basisSize,\n minSize,\n maxSize,\n isFrozen: false,\n targetSize: basisSize,\n })\n\n nonFlexSpace += marginSize\n } else {\n // Non-flex item - uses its current size\n const size = direction === 'row' ? layoutChild.size.width : layoutChild.size.height\n nonFlexSpace += size + marginSize\n }\n })\n\n // No flex items - return as is\n if (flexItems.length === 0) {\n return children\n }\n\n // Phase 2: Calculate total flex-basis\n let totalFlexBasis = flexItems.reduce((sum, item) => sum + item.flexBasis, 0)\n let freeSpace = availableSpace - nonFlexSpace - totalFlexBasis\n\n // Phase 3: Flex distribution (grow or shrink)\n const updatedChildren = [...children]\n\n if (freeSpace > 0) {\n // GROW: Distribute positive free space\n distributeGrow(flexItems, freeSpace)\n } else if (freeSpace < 0) {\n // SHRINK: Distribute negative free space\n distributeShrink(flexItems, freeSpace)\n } else {\n // Exact fit - use flex-basis\n flexItems.forEach((item) => {\n item.targetSize = item.flexBasis\n })\n }\n\n // Phase 4: Apply calculated sizes\n flexItems.forEach((item) => {\n if (direction === 'row') {\n updatedChildren[item.index] = {\n ...item.child,\n size: {\n ...item.child.size,\n width: item.targetSize,\n },\n }\n } else {\n updatedChildren[item.index] = {\n ...item.child,\n size: {\n ...item.child.size,\n height: item.targetSize,\n },\n }\n }\n })\n\n return updatedChildren\n}\n\n/**\n * Distribute positive free space using flex-grow\n * @param flexItems - Flex items to distribute space among\n * @param freeSpace - Positive free space to distribute\n */\nfunction distributeGrow(flexItems: FlexItem[], freeSpace: number): void {\n let remainingSpace = freeSpace\n const MAX_ITERATIONS = 10\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n // Calculate total flex-grow of unfrozen items\n const totalFlexGrow = flexItems\n .filter((item) => !item.isFrozen)\n .reduce((sum, item) => sum + item.flexGrow, 0)\n\n if (totalFlexGrow === 0 || remainingSpace <= 0) {\n break\n }\n\n let hasViolations = false\n\n // Distribute space proportionally\n for (const item of flexItems) {\n if (item.isFrozen) continue\n\n const growShare = (remainingSpace * item.flexGrow) / totalFlexGrow\n let targetSize = item.flexBasis + growShare\n\n // Apply min/max constraints\n if (item.minSize !== undefined && targetSize < item.minSize) {\n targetSize = item.minSize\n item.isFrozen = true\n hasViolations = true\n } else if (item.maxSize !== undefined && targetSize > item.maxSize) {\n targetSize = item.maxSize\n item.isFrozen = true\n hasViolations = true\n }\n\n item.targetSize = targetSize\n }\n\n if (!hasViolations) {\n break // All items distributed without violations\n }\n\n // Recalculate remaining space for next iteration\n remainingSpace = freeSpace\n for (const item of flexItems) {\n if (item.isFrozen) {\n remainingSpace -= item.targetSize - item.flexBasis\n }\n }\n }\n\n // Set targetSize for any remaining unfrozen items\n for (const item of flexItems) {\n if (!item.isFrozen) {\n // Already set in loop\n }\n }\n}\n\n/**\n * Distribute negative free space using flex-shrink\n * @param flexItems - Flex items to shrink\n * @param freeSpace - Negative free space (deficit)\n */\nfunction distributeShrink(flexItems: FlexItem[], freeSpace: number): void {\n let remainingSpace = Math.abs(freeSpace)\n const MAX_ITERATIONS = 10\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n // Calculate scaled flex-shrink (shrink * basis)\n const totalScaledShrink = flexItems\n .filter((item) => !item.isFrozen)\n .reduce((sum, item) => sum + item.flexShrink * item.flexBasis, 0)\n\n if (totalScaledShrink === 0 || remainingSpace <= 0) {\n break\n }\n\n let hasViolations = false\n\n // Distribute shrinkage proportionally\n for (const item of flexItems) {\n if (item.isFrozen) continue\n\n const scaledShrink = item.flexShrink * item.flexBasis\n const shrinkShare = (remainingSpace * scaledShrink) / totalScaledShrink\n let targetSize = item.flexBasis - shrinkShare\n\n // Apply min/max constraints\n if (item.minSize !== undefined && targetSize < item.minSize) {\n targetSize = item.minSize\n item.isFrozen = true\n hasViolations = true\n } else if (item.maxSize !== undefined && targetSize > item.maxSize) {\n targetSize = item.maxSize\n item.isFrozen = true\n hasViolations = true\n }\n\n item.targetSize = targetSize\n }\n\n if (!hasViolations) {\n break // All items shrunk without violations\n }\n\n // Recalculate remaining space for next iteration\n remainingSpace = Math.abs(freeSpace)\n for (const item of flexItems) {\n if (item.isFrozen) {\n remainingSpace -= item.flexBasis - item.targetSize\n }\n }\n }\n\n // Set targetSize for any remaining unfrozen items\n for (const item of flexItems) {\n if (!item.isFrozen) {\n // Already set in loop\n }\n }\n}\n\n/**\n * Check if any children have flex properties (flex, flexShrink, or flexBasis)\n * @param children - Layout children\n * @returns True if at least one child participates in flexbox\n */\nexport function hasFlexChildren(children: LayoutChild[]): boolean {\n return children.some((child) => {\n const props = child.child.__layoutProps\n return (\n (props?.flex !== undefined && props.flex > 0) ||\n props?.flexShrink !== undefined ||\n props?.flexBasis !== undefined\n )\n })\n}\n"],"names":["currentSize"],"mappings":"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"}
|