@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,628 @@
|
|
|
1
|
+
import { normalizeGap } from "../core-props.js";
|
|
2
|
+
import { DebugLogger } from "../dev-config.js";
|
|
3
|
+
import { getOrCreateGlobalValue, setGlobalValue, getGlobalValue } from "../global-registry.js";
|
|
4
|
+
import { applyContainerDimensions } from "./appliers/container-applier.js";
|
|
5
|
+
import { applyChildPositions } from "./appliers/position-applier.js";
|
|
6
|
+
import { ColumnLayoutStrategy } from "./strategies/column-layout.js";
|
|
7
|
+
import { RowLayoutStrategy } from "./strategies/row-layout.js";
|
|
8
|
+
import { StackLayoutStrategy } from "./strategies/stack-layout.js";
|
|
9
|
+
import { isLayoutChild, processNestedContainer, getChildSize, getMargin } from "./utils/child-utils.js";
|
|
10
|
+
import { normalizePadding, calculateContainerSize } from "./utils/dimension-calculator.js";
|
|
11
|
+
import { hasFlexChildren, distributeFlexSpace } from "./utils/flex-distributor.js";
|
|
12
|
+
import { parseSize, resolveSize, clampSize } from "./utils/size-resolver.js";
|
|
13
|
+
import { calculateJustifyContent, calculateAlignItems } from "./utils/spacing-calculator.js";
|
|
14
|
+
const GLOBAL_NS = "@number10/jsx-core:layout";
|
|
15
|
+
const _overflowClipRegistryKey = /* @__PURE__ */ Symbol.for(`${GLOBAL_NS}:overflowClipRegistry`);
|
|
16
|
+
const _onAfterLayoutKey = /* @__PURE__ */ Symbol.for(`${GLOBAL_NS}:onAfterLayout`);
|
|
17
|
+
function getOverflowClipRegistry() {
|
|
18
|
+
return getOrCreateGlobalValue(_overflowClipRegistryKey, () => []);
|
|
19
|
+
}
|
|
20
|
+
function getOnAfterLayout() {
|
|
21
|
+
return getGlobalValue(_onAfterLayoutKey) ?? noopAfterLayout;
|
|
22
|
+
}
|
|
23
|
+
function setOnAfterLayout(fn) {
|
|
24
|
+
setGlobalValue(_onAfterLayoutKey, fn);
|
|
25
|
+
}
|
|
26
|
+
const noopAfterLayout = () => {
|
|
27
|
+
};
|
|
28
|
+
function registerApplyOverflowClip(fn) {
|
|
29
|
+
getOverflowClipRegistry().push(fn);
|
|
30
|
+
}
|
|
31
|
+
function setApplyOverflowClip(fn) {
|
|
32
|
+
const registry = getOverflowClipRegistry();
|
|
33
|
+
registry.length = 0;
|
|
34
|
+
registry.push(fn);
|
|
35
|
+
}
|
|
36
|
+
function setAfterLayout(fn) {
|
|
37
|
+
setOnAfterLayout(fn);
|
|
38
|
+
}
|
|
39
|
+
class DeferredLayoutQueue {
|
|
40
|
+
static callbacks = [];
|
|
41
|
+
static scheduled = false;
|
|
42
|
+
/**
|
|
43
|
+
* Schedule a callback to execute after current layout pass completes
|
|
44
|
+
* All callbacks are batched and executed in single requestAnimationFrame
|
|
45
|
+
* @param callback - Function to execute in next frame
|
|
46
|
+
*/
|
|
47
|
+
static defer(callback) {
|
|
48
|
+
this.callbacks.push(callback);
|
|
49
|
+
if (!this.scheduled) {
|
|
50
|
+
this.scheduled = true;
|
|
51
|
+
requestAnimationFrame(() => this.flush());
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute all pending callbacks in batch
|
|
56
|
+
* Called once per frame via requestAnimationFrame
|
|
57
|
+
*/
|
|
58
|
+
static flush() {
|
|
59
|
+
this.scheduled = false;
|
|
60
|
+
const callbacks = [...this.callbacks];
|
|
61
|
+
this.callbacks = [];
|
|
62
|
+
for (const callback of callbacks) {
|
|
63
|
+
try {
|
|
64
|
+
callback();
|
|
65
|
+
} catch (error) {
|
|
66
|
+
DebugLogger.error("DeferredLayoutQueue", "Error in deferred callback:", error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
class LayoutBatchQueue {
|
|
72
|
+
static pending = /* @__PURE__ */ new Map();
|
|
73
|
+
static scheduled = false;
|
|
74
|
+
/**
|
|
75
|
+
* Enable synchronous mode for testing
|
|
76
|
+
* When true, layouts execute immediately instead of batching
|
|
77
|
+
*/
|
|
78
|
+
static synchronous = false;
|
|
79
|
+
/**
|
|
80
|
+
* Schedule a layout calculation to execute after current call stack
|
|
81
|
+
* Uses microtask (Promise) instead of requestAnimationFrame to avoid flickering
|
|
82
|
+
* If container is already scheduled, updates entry with latest props
|
|
83
|
+
* @param container - Container to calculate layout for
|
|
84
|
+
* @param containerProps - Layout props
|
|
85
|
+
* @param parentSize - Optional parent size for percentage resolution
|
|
86
|
+
* @param parentPadding - Optional parent padding for fill resolution
|
|
87
|
+
*/
|
|
88
|
+
static schedule(container, containerProps, parentSize, parentPadding) {
|
|
89
|
+
if (this.synchronous) {
|
|
90
|
+
calculateLayoutImmediate(container, containerProps, parentSize, parentPadding);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.pending.set(container, { container, containerProps, parentSize, parentPadding });
|
|
94
|
+
if (!this.scheduled) {
|
|
95
|
+
this.scheduled = true;
|
|
96
|
+
Promise.resolve().then(() => this.flush());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Execute all pending layout calculations immediately
|
|
101
|
+
* Processes in bottom-up order (deepest children first)
|
|
102
|
+
* This prevents redundant parent recalculations
|
|
103
|
+
*/
|
|
104
|
+
static flush() {
|
|
105
|
+
this.scheduled = false;
|
|
106
|
+
if (this.pending.size === 0) return;
|
|
107
|
+
DebugLogger.time("performance", "LayoutBatchQueue.flush");
|
|
108
|
+
const entries = Array.from(this.pending.values());
|
|
109
|
+
this.pending.clear();
|
|
110
|
+
entries.sort((a, b) => {
|
|
111
|
+
const depthA = getContainerDepth(a.container);
|
|
112
|
+
const depthB = getContainerDepth(b.container);
|
|
113
|
+
return depthB - depthA;
|
|
114
|
+
});
|
|
115
|
+
for (const entry of entries) {
|
|
116
|
+
try {
|
|
117
|
+
const node = entry.container;
|
|
118
|
+
if (node.destroyed === true) continue;
|
|
119
|
+
if (entry.container.visible === false) continue;
|
|
120
|
+
calculateLayoutImmediate(
|
|
121
|
+
entry.container,
|
|
122
|
+
entry.containerProps,
|
|
123
|
+
entry.parentSize,
|
|
124
|
+
entry.parentPadding
|
|
125
|
+
);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
DebugLogger.error("LayoutBatchQueue", "Error calculating layout:", error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
DebugLogger.timeEnd("performance", "LayoutBatchQueue.flush");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function getContainerDepth(container) {
|
|
134
|
+
let depth = 0;
|
|
135
|
+
let current = getLayoutParent(container);
|
|
136
|
+
while (current) {
|
|
137
|
+
depth++;
|
|
138
|
+
current = getLayoutParent(current);
|
|
139
|
+
}
|
|
140
|
+
return depth;
|
|
141
|
+
}
|
|
142
|
+
function getLayoutParent(container) {
|
|
143
|
+
if (container.__layoutParent) {
|
|
144
|
+
return container.__layoutParent;
|
|
145
|
+
}
|
|
146
|
+
if (container.parent) {
|
|
147
|
+
return container.parent;
|
|
148
|
+
}
|
|
149
|
+
const parentContainer = container.parentContainer;
|
|
150
|
+
if (parentContainer && typeof parentContainer === "object") {
|
|
151
|
+
return parentContainer;
|
|
152
|
+
}
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
function applyOverflowMask(container, containerProps, width, height) {
|
|
156
|
+
for (const clip of getOverflowClipRegistry()) {
|
|
157
|
+
clip(container, containerProps, width, height);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const strategies = {
|
|
161
|
+
column: new ColumnLayoutStrategy(),
|
|
162
|
+
row: new RowLayoutStrategy(),
|
|
163
|
+
stack: new StackLayoutStrategy()
|
|
164
|
+
};
|
|
165
|
+
const LAYOUT_CYCLE_EPSILON = 0.5;
|
|
166
|
+
const LAYOUT_CYCLE_TIME_MS = 20;
|
|
167
|
+
const LAYOUT_CYCLE_MAX = 5;
|
|
168
|
+
const LAYOUT_MAX_SIZE = 2e5;
|
|
169
|
+
const layoutCycleGuard = /* @__PURE__ */ new WeakMap();
|
|
170
|
+
const deferredParentInvalidations = /* @__PURE__ */ new WeakSet();
|
|
171
|
+
function isCloseSize(a, b, epsilon) {
|
|
172
|
+
return Math.abs(a.width - b.width) < epsilon && Math.abs(a.height - b.height) < epsilon;
|
|
173
|
+
}
|
|
174
|
+
function invalidateParentLayoutIfNeeded(container, oldSize, newWidth, newHeight) {
|
|
175
|
+
if (!oldSize || Math.abs(oldSize.width - newWidth) < LAYOUT_CYCLE_EPSILON && Math.abs(oldSize.height - newHeight) < LAYOUT_CYCLE_EPSILON) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (!Number.isFinite(newWidth) || !Number.isFinite(newHeight) || newWidth > LAYOUT_MAX_SIZE || newHeight > LAYOUT_MAX_SIZE) {
|
|
179
|
+
DebugLogger.warn("layout", "Runaway layout size detected, skipping parent invalidation", {
|
|
180
|
+
oldSize,
|
|
181
|
+
newSize: { width: newWidth, height: newHeight },
|
|
182
|
+
containerProps: container.__layoutProps,
|
|
183
|
+
childCount: container.list?.length ?? 0
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const newSize = { width: newWidth, height: newHeight };
|
|
188
|
+
const now = Date.now();
|
|
189
|
+
const parent = getLayoutParent(container);
|
|
190
|
+
if (!parent || !parent.__layoutProps) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const guard = layoutCycleGuard.get(container);
|
|
194
|
+
if (guard) {
|
|
195
|
+
const repeatsPrev = guard.prev ? isCloseSize(guard.prev, newSize, LAYOUT_CYCLE_EPSILON) : false;
|
|
196
|
+
if (repeatsPrev && now - guard.lastTime < LAYOUT_CYCLE_TIME_MS) {
|
|
197
|
+
guard.count += 1;
|
|
198
|
+
} else {
|
|
199
|
+
guard.count = 0;
|
|
200
|
+
}
|
|
201
|
+
guard.prev = guard.last;
|
|
202
|
+
guard.last = newSize;
|
|
203
|
+
guard.lastTime = now;
|
|
204
|
+
layoutCycleGuard.set(container, guard);
|
|
205
|
+
if (guard.count >= LAYOUT_CYCLE_MAX) {
|
|
206
|
+
DebugLogger.log("layout", "Layout cycle detected, deferring parent invalidation", {
|
|
207
|
+
container,
|
|
208
|
+
oldSize,
|
|
209
|
+
newSize
|
|
210
|
+
});
|
|
211
|
+
guard.count = 0;
|
|
212
|
+
guard.lastTime = 0;
|
|
213
|
+
layoutCycleGuard.set(container, guard);
|
|
214
|
+
deferParentLayoutInvalidation(container);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
layoutCycleGuard.set(container, {
|
|
219
|
+
last: newSize,
|
|
220
|
+
count: 0,
|
|
221
|
+
lastTime: now
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
DebugLogger.log(
|
|
225
|
+
"layout",
|
|
226
|
+
"Container size changed, invalidating parent:",
|
|
227
|
+
`${oldSize.width}x${oldSize.height} -> ${newWidth}x${newHeight}`
|
|
228
|
+
);
|
|
229
|
+
invalidateParentLayout(container);
|
|
230
|
+
}
|
|
231
|
+
function deferParentLayoutInvalidation(container) {
|
|
232
|
+
if (deferredParentInvalidations.has(container)) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
deferredParentInvalidations.add(container);
|
|
236
|
+
DeferredLayoutQueue.defer(() => {
|
|
237
|
+
deferredParentInvalidations.delete(container);
|
|
238
|
+
invalidateParentLayout(container);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function invalidateParentLayout(container) {
|
|
242
|
+
const parent = getLayoutParent(container);
|
|
243
|
+
if (!parent || !parent.__layoutProps) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const grandParent = getLayoutParent(parent);
|
|
247
|
+
let grandParentSize;
|
|
248
|
+
if (grandParent && grandParent.__getLayoutSize) {
|
|
249
|
+
const totalSize = grandParent.__getLayoutSize();
|
|
250
|
+
const padding = grandParent.__layoutProps?.padding ?? 0;
|
|
251
|
+
const normPadding = typeof padding === "number" ? { left: padding, right: padding, top: padding, bottom: padding } : {
|
|
252
|
+
left: padding.left ?? 0,
|
|
253
|
+
right: padding.right ?? 0,
|
|
254
|
+
top: padding.top ?? 0,
|
|
255
|
+
bottom: padding.bottom ?? 0
|
|
256
|
+
};
|
|
257
|
+
grandParentSize = {
|
|
258
|
+
width: totalSize.width - normPadding.left - normPadding.right,
|
|
259
|
+
height: totalSize.height - normPadding.top - normPadding.bottom
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
calculateLayout(parent, parent.__layoutProps, grandParentSize);
|
|
263
|
+
}
|
|
264
|
+
function calculateLayoutImmediate(container, containerProps, parentSize, parentPadding) {
|
|
265
|
+
const children = container.list ?? [];
|
|
266
|
+
const containerWithLayout = container;
|
|
267
|
+
const oldContainerSize = containerWithLayout.__getLayoutSize?.();
|
|
268
|
+
if (!children || !Array.isArray(children)) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
DebugLogger.time("performance", "calculateLayout");
|
|
272
|
+
const direction = containerProps.direction ?? "column";
|
|
273
|
+
const padding = normalizePadding(containerProps.padding);
|
|
274
|
+
const gap = normalizeGap(containerProps.gap);
|
|
275
|
+
const justifyContent = containerProps.justifyContent ?? "start";
|
|
276
|
+
DebugLogger.log("layout", `Direction: ${direction}, Padding:`, padding);
|
|
277
|
+
let currentContainerSize;
|
|
278
|
+
const parsedWidth = parseSize(containerProps.width);
|
|
279
|
+
const canCalculateWidth = parsedWidth.type === "fixed" || parentSize?.width !== void 0 && (parsedWidth.type === "percent" || parsedWidth.type === "fill" || parsedWidth.type === "calc");
|
|
280
|
+
const width = canCalculateWidth ? resolveSize(parsedWidth, parentSize?.width, container.width, parentPadding?.horizontal) : void 0;
|
|
281
|
+
const parsedHeight = parseSize(containerProps.height);
|
|
282
|
+
const canCalculateHeight = parsedHeight.type === "fixed" || parentSize?.height !== void 0 && (parsedHeight.type === "percent" || parsedHeight.type === "fill" || parsedHeight.type === "calc");
|
|
283
|
+
const height = canCalculateHeight ? resolveSize(parsedHeight, parentSize?.height, container.height, parentPadding?.vertical) : void 0;
|
|
284
|
+
if (width !== void 0 || height !== void 0) {
|
|
285
|
+
const clampedWidth = width !== void 0 ? clampSize(
|
|
286
|
+
width,
|
|
287
|
+
containerProps.minWidth,
|
|
288
|
+
containerProps.maxWidth,
|
|
289
|
+
parentSize?.width,
|
|
290
|
+
container.width,
|
|
291
|
+
parentPadding?.horizontal
|
|
292
|
+
) : container.width ?? 0;
|
|
293
|
+
const clampedHeight = height !== void 0 ? clampSize(
|
|
294
|
+
height,
|
|
295
|
+
containerProps.minHeight,
|
|
296
|
+
containerProps.maxHeight,
|
|
297
|
+
parentSize?.height,
|
|
298
|
+
container.height,
|
|
299
|
+
parentPadding?.vertical
|
|
300
|
+
) : container.height ?? 0;
|
|
301
|
+
currentContainerSize = {
|
|
302
|
+
width: clampedWidth,
|
|
303
|
+
height: clampedHeight
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const availableContentSize = currentContainerSize ? {
|
|
307
|
+
width: currentContainerSize.width - padding.left - padding.right,
|
|
308
|
+
height: currentContainerSize.height - padding.top - padding.bottom
|
|
309
|
+
} : void 0;
|
|
310
|
+
DebugLogger.log("layout", "Pre-calculated container size:", currentContainerSize);
|
|
311
|
+
DebugLogger.log("layout", "Available content size (for fill):", availableContentSize);
|
|
312
|
+
const layoutChildren = [];
|
|
313
|
+
for (const child of children) {
|
|
314
|
+
if (!isLayoutChild(child)) {
|
|
315
|
+
DebugLogger.log("layout", "Skipping non-layout child:", {
|
|
316
|
+
isBackground: child.__isBackground,
|
|
317
|
+
headless: child.__layoutProps?.headless,
|
|
318
|
+
hasLayoutSize: typeof child.__getLayoutSize === "function"
|
|
319
|
+
});
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const hasFlex = (child.__layoutProps?.flex ?? 0) > 0;
|
|
323
|
+
if (!hasFlex) {
|
|
324
|
+
const parentSizeForNested = currentContainerSize ? {
|
|
325
|
+
width: currentContainerSize.width - padding.left - padding.right,
|
|
326
|
+
height: currentContainerSize.height - padding.top - padding.bottom
|
|
327
|
+
} : parentSize ? {
|
|
328
|
+
width: parentSize.width - (parentPadding?.horizontal ?? 0),
|
|
329
|
+
height: parentSize.height - (parentPadding?.vertical ?? 0)
|
|
330
|
+
} : void 0;
|
|
331
|
+
processNestedContainer(
|
|
332
|
+
child,
|
|
333
|
+
calculateLayout,
|
|
334
|
+
parentSizeForNested,
|
|
335
|
+
void 0
|
|
336
|
+
// No padding offset needed since we pass content-area
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
const contentAreaForChild = currentContainerSize ? {
|
|
340
|
+
width: currentContainerSize.width - padding.left - padding.right,
|
|
341
|
+
height: currentContainerSize.height - padding.top - padding.bottom
|
|
342
|
+
} : parentSize ? {
|
|
343
|
+
width: parentSize.width - (parentPadding?.horizontal ?? 0),
|
|
344
|
+
height: parentSize.height - (parentPadding?.vertical ?? 0)
|
|
345
|
+
} : void 0;
|
|
346
|
+
const size = getChildSize(child, contentAreaForChild, void 0);
|
|
347
|
+
const margin = getMargin(child);
|
|
348
|
+
layoutChildren.push({ child, size, margin });
|
|
349
|
+
}
|
|
350
|
+
const strategy = strategies[direction];
|
|
351
|
+
if (!strategy) {
|
|
352
|
+
DebugLogger.error("Layout", `Unknown direction: ${direction}`);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const contextPartial = {
|
|
356
|
+
containerProps,
|
|
357
|
+
padding,
|
|
358
|
+
gap,
|
|
359
|
+
children: layoutChildren
|
|
360
|
+
};
|
|
361
|
+
const metrics = strategy.calculateMetrics(layoutChildren, contextPartial);
|
|
362
|
+
const flexWrap = containerProps.flexWrap ?? "nowrap";
|
|
363
|
+
const shouldWrap = flexWrap !== "nowrap" && direction !== "stack";
|
|
364
|
+
const { width: containerWidth, height: containerHeight } = calculateContainerSize(
|
|
365
|
+
containerProps,
|
|
366
|
+
metrics,
|
|
367
|
+
padding,
|
|
368
|
+
direction,
|
|
369
|
+
gap,
|
|
370
|
+
layoutChildren.length,
|
|
371
|
+
parentSize,
|
|
372
|
+
parentPadding
|
|
373
|
+
);
|
|
374
|
+
let finalLayoutChildren = layoutChildren;
|
|
375
|
+
if (hasFlexChildren(layoutChildren) && !shouldWrap) {
|
|
376
|
+
const contentSize = direction === "row" ? containerWidth - padding.left - padding.right : containerHeight - padding.top - padding.bottom;
|
|
377
|
+
const gapValue2 = direction === "row" ? gap.horizontal : gap.vertical;
|
|
378
|
+
const totalGapSpace2 = layoutChildren.length > 1 ? gapValue2 * (layoutChildren.length - 1) : 0;
|
|
379
|
+
const availableMainSpace2 = contentSize - totalGapSpace2;
|
|
380
|
+
finalLayoutChildren = distributeFlexSpace(layoutChildren, availableMainSpace2, direction);
|
|
381
|
+
for (const layoutChild of finalLayoutChildren) {
|
|
382
|
+
const props = layoutChild.child.__layoutProps;
|
|
383
|
+
const isFlexItem = props?.flex !== void 0 && props.flex > 0 || props?.flexShrink !== void 0 || props?.flexBasis !== void 0;
|
|
384
|
+
if (isFlexItem) {
|
|
385
|
+
const originalProps = { ...layoutChild.child.__layoutProps };
|
|
386
|
+
if (direction === "row") {
|
|
387
|
+
layoutChild.child.__layoutProps = {
|
|
388
|
+
...layoutChild.child.__layoutProps,
|
|
389
|
+
width: layoutChild.size.width
|
|
390
|
+
};
|
|
391
|
+
} else {
|
|
392
|
+
layoutChild.child.__layoutProps = {
|
|
393
|
+
...layoutChild.child.__layoutProps,
|
|
394
|
+
height: layoutChild.size.height
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
processNestedContainer(
|
|
398
|
+
layoutChild.child,
|
|
399
|
+
calculateLayout,
|
|
400
|
+
{
|
|
401
|
+
width: containerWidth,
|
|
402
|
+
height: containerHeight
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
horizontal: padding.left + padding.right,
|
|
406
|
+
vertical: padding.top + padding.bottom
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
layoutChild.child.__layoutProps = originalProps;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
const updatedMetrics = strategy.calculateMetrics(
|
|
413
|
+
finalLayoutChildren,
|
|
414
|
+
contextPartial
|
|
415
|
+
);
|
|
416
|
+
metrics.totalMainSize = updatedMetrics.totalMainSize;
|
|
417
|
+
if (direction === "column") {
|
|
418
|
+
metrics.maxWidth = updatedMetrics.maxWidth;
|
|
419
|
+
} else if (direction === "row") {
|
|
420
|
+
metrics.maxHeight = updatedMetrics.maxHeight;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const contentArea = {
|
|
424
|
+
width: containerWidth - padding.left - padding.right,
|
|
425
|
+
height: containerHeight - padding.top - padding.bottom
|
|
426
|
+
};
|
|
427
|
+
const context = {
|
|
428
|
+
...contextPartial,
|
|
429
|
+
children: finalLayoutChildren,
|
|
430
|
+
contentArea,
|
|
431
|
+
parentSize: {
|
|
432
|
+
width: containerWidth,
|
|
433
|
+
height: containerHeight
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
const availableMainSpace = direction === "row" ? contentArea.width : contentArea.height;
|
|
437
|
+
const gapValue = direction === "row" ? gap.horizontal : gap.vertical;
|
|
438
|
+
const totalGapSpace = finalLayoutChildren.length > 1 ? gapValue * (finalLayoutChildren.length - 1) : 0;
|
|
439
|
+
const remainingSpace = availableMainSpace - metrics.totalMainSize - totalGapSpace;
|
|
440
|
+
let mainStart = 0;
|
|
441
|
+
let spaceBetween = 0;
|
|
442
|
+
if (direction !== "stack") {
|
|
443
|
+
const justifyResult = calculateJustifyContent(
|
|
444
|
+
justifyContent,
|
|
445
|
+
remainingSpace,
|
|
446
|
+
finalLayoutChildren.length
|
|
447
|
+
);
|
|
448
|
+
mainStart = justifyResult.mainStart;
|
|
449
|
+
spaceBetween = justifyResult.spaceBetween;
|
|
450
|
+
}
|
|
451
|
+
const alignItems = containerProps.alignItems ?? "start";
|
|
452
|
+
if (alignItems === "stretch" && direction !== "stack") {
|
|
453
|
+
for (const layoutChild of finalLayoutChildren) {
|
|
454
|
+
const margin = getMargin(layoutChild.child);
|
|
455
|
+
const child = layoutChild.child;
|
|
456
|
+
if (direction === "row") {
|
|
457
|
+
const stretchHeight = contentArea.height - (margin.top ?? 0) - (margin.bottom ?? 0);
|
|
458
|
+
layoutChild.size.height = Math.max(0, stretchHeight);
|
|
459
|
+
if (child.__layoutProps) {
|
|
460
|
+
const originalHeight = child.__layoutProps.height;
|
|
461
|
+
child.__layoutProps = { ...child.__layoutProps, height: stretchHeight };
|
|
462
|
+
processNestedContainer(child, calculateLayout, {
|
|
463
|
+
width: containerWidth,
|
|
464
|
+
height: containerHeight
|
|
465
|
+
});
|
|
466
|
+
child.__layoutProps = { ...child.__layoutProps, height: originalHeight };
|
|
467
|
+
}
|
|
468
|
+
} else if (direction === "column") {
|
|
469
|
+
const stretchWidth = contentArea.width - (margin.left ?? 0) - (margin.right ?? 0);
|
|
470
|
+
layoutChild.size.width = Math.max(0, stretchWidth);
|
|
471
|
+
if (child.__layoutProps) {
|
|
472
|
+
const originalWidth = child.__layoutProps.width;
|
|
473
|
+
child.__layoutProps = { ...child.__layoutProps, width: stretchWidth };
|
|
474
|
+
processNestedContainer(child, calculateLayout, {
|
|
475
|
+
width: containerWidth,
|
|
476
|
+
height: containerHeight
|
|
477
|
+
});
|
|
478
|
+
child.__layoutProps = { ...child.__layoutProps, width: originalWidth };
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const positions = [];
|
|
484
|
+
let adjustedContainerWidth = containerWidth;
|
|
485
|
+
let adjustedContainerHeight = containerHeight;
|
|
486
|
+
if (shouldWrap && "wrapChildren" in strategy) {
|
|
487
|
+
const availableMainSize = direction === "row" ? contentArea.width : contentArea.height;
|
|
488
|
+
const mainGapValue = direction === "row" ? gap.horizontal : gap.vertical;
|
|
489
|
+
const lines = strategy.wrapChildren(
|
|
490
|
+
finalLayoutChildren,
|
|
491
|
+
availableMainSize,
|
|
492
|
+
mainGapValue
|
|
493
|
+
);
|
|
494
|
+
if (flexWrap === "wrap-reverse") {
|
|
495
|
+
lines.reverse();
|
|
496
|
+
}
|
|
497
|
+
const totalCrossSize = lines.reduce(
|
|
498
|
+
(sum, line) => sum + line.crossAxisSize,
|
|
499
|
+
0
|
|
500
|
+
);
|
|
501
|
+
const crossGapValue = direction === "row" ? gap.vertical : gap.horizontal;
|
|
502
|
+
const totalLineGaps = (lines.length - 1) * crossGapValue;
|
|
503
|
+
if (direction === "row" && (containerProps.height === void 0 || containerProps.height === "auto")) {
|
|
504
|
+
adjustedContainerHeight = totalCrossSize + totalLineGaps + padding.top + padding.bottom;
|
|
505
|
+
} else if (direction === "column" && (containerProps.width === void 0 || containerProps.width === "auto")) {
|
|
506
|
+
adjustedContainerWidth = totalCrossSize + totalLineGaps + padding.left + padding.right;
|
|
507
|
+
}
|
|
508
|
+
const availableCrossSize = direction === "row" ? contentArea.height : contentArea.width;
|
|
509
|
+
const freeCrossSpace = availableCrossSize - totalCrossSize - totalLineGaps;
|
|
510
|
+
const alignContent = containerProps.alignContent ?? "stretch";
|
|
511
|
+
let crossOffset = 0;
|
|
512
|
+
let lineCrossSpacing = 0;
|
|
513
|
+
if (alignContent === "center") {
|
|
514
|
+
crossOffset = freeCrossSpace / 2;
|
|
515
|
+
} else if (alignContent === "end") {
|
|
516
|
+
crossOffset = freeCrossSpace;
|
|
517
|
+
} else if (alignContent === "space-between" && lines.length > 1) {
|
|
518
|
+
lineCrossSpacing = freeCrossSpace / (lines.length - 1);
|
|
519
|
+
} else if (alignContent === "space-around") {
|
|
520
|
+
lineCrossSpacing = freeCrossSpace / lines.length;
|
|
521
|
+
crossOffset = lineCrossSpacing / 2;
|
|
522
|
+
}
|
|
523
|
+
for (const line of lines) {
|
|
524
|
+
let lineChildren = line.children;
|
|
525
|
+
if (hasFlexChildren(line.children)) {
|
|
526
|
+
const lineGapSpace2 = (line.children.length - 1) * mainGapValue;
|
|
527
|
+
const lineAvailableSpace = availableMainSize - lineGapSpace2;
|
|
528
|
+
lineChildren = distributeFlexSpace(line.children, lineAvailableSpace, direction);
|
|
529
|
+
line.mainAxisSize = lineChildren.reduce((sum, child) => {
|
|
530
|
+
const size = direction === "row" ? child.size.width : child.size.height;
|
|
531
|
+
const margin = getMargin(child.child);
|
|
532
|
+
const marginSize = direction === "row" ? (margin.left ?? 0) + (margin.right ?? 0) : (margin.top ?? 0) + (margin.bottom ?? 0);
|
|
533
|
+
return sum + size + marginSize;
|
|
534
|
+
}, 0);
|
|
535
|
+
}
|
|
536
|
+
const lineMainSize = line.mainAxisSize;
|
|
537
|
+
const lineAvailableMain = availableMainSize;
|
|
538
|
+
const lineRemainingSpace = lineAvailableMain - lineMainSize;
|
|
539
|
+
const lineGapSpace = (line.children.length - 1) * mainGapValue;
|
|
540
|
+
const lineFreeSpace = lineRemainingSpace - lineGapSpace;
|
|
541
|
+
const lineJustifyResult = calculateJustifyContent(
|
|
542
|
+
justifyContent,
|
|
543
|
+
lineFreeSpace,
|
|
544
|
+
line.children.length
|
|
545
|
+
);
|
|
546
|
+
let lineMainOffset = lineJustifyResult.mainStart;
|
|
547
|
+
const lineSpaceBetween = lineJustifyResult.spaceBetween;
|
|
548
|
+
for (let i = 0; i < lineChildren.length; i++) {
|
|
549
|
+
const child = lineChildren[i];
|
|
550
|
+
if (!child) continue;
|
|
551
|
+
const margin = getMargin(child.child);
|
|
552
|
+
let x;
|
|
553
|
+
let y;
|
|
554
|
+
if (direction === "row") {
|
|
555
|
+
lineMainOffset += margin.left ?? 0;
|
|
556
|
+
x = padding.left + lineMainOffset;
|
|
557
|
+
const childCrossOffset = calculateAlignItems(
|
|
558
|
+
alignItems,
|
|
559
|
+
line.crossAxisSize,
|
|
560
|
+
child.size.height,
|
|
561
|
+
margin.top ?? 0,
|
|
562
|
+
margin.bottom ?? 0
|
|
563
|
+
);
|
|
564
|
+
y = padding.top + crossOffset + childCrossOffset;
|
|
565
|
+
lineMainOffset += child.size.width + (margin.right ?? 0);
|
|
566
|
+
if (i < lineChildren.length - 1) {
|
|
567
|
+
lineMainOffset += mainGapValue + lineSpaceBetween;
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
lineMainOffset += margin.top ?? 0;
|
|
571
|
+
y = padding.top + lineMainOffset;
|
|
572
|
+
const childCrossOffset = calculateAlignItems(
|
|
573
|
+
alignItems,
|
|
574
|
+
line.crossAxisSize,
|
|
575
|
+
child.size.width,
|
|
576
|
+
margin.left ?? 0,
|
|
577
|
+
margin.right ?? 0
|
|
578
|
+
);
|
|
579
|
+
x = padding.left + crossOffset + childCrossOffset;
|
|
580
|
+
lineMainOffset += child.size.height + (margin.bottom ?? 0);
|
|
581
|
+
if (i < lineChildren.length - 1) {
|
|
582
|
+
lineMainOffset += mainGapValue + lineSpaceBetween;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
const childIndex = finalLayoutChildren.indexOf(child);
|
|
586
|
+
if (childIndex !== -1) {
|
|
587
|
+
positions[childIndex] = { x, y };
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
crossOffset += line.crossAxisSize + crossGapValue + lineCrossSpacing;
|
|
591
|
+
}
|
|
592
|
+
} else {
|
|
593
|
+
let currentMain = mainStart;
|
|
594
|
+
for (let i = 0; i < finalLayoutChildren.length; i++) {
|
|
595
|
+
const child = finalLayoutChildren[i];
|
|
596
|
+
if (!child) continue;
|
|
597
|
+
const result = strategy.positionChild(child, i, context, currentMain);
|
|
598
|
+
positions.push(result.position);
|
|
599
|
+
currentMain = result.nextMain;
|
|
600
|
+
if (direction !== "stack" && i < finalLayoutChildren.length - 1) {
|
|
601
|
+
currentMain += gapValue + spaceBetween;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
applyChildPositions(finalLayoutChildren, positions);
|
|
606
|
+
applyContainerDimensions(container, adjustedContainerWidth, adjustedContainerHeight);
|
|
607
|
+
getOnAfterLayout()(container, adjustedContainerWidth, adjustedContainerHeight);
|
|
608
|
+
applyOverflowMask(container, containerProps, adjustedContainerWidth, adjustedContainerHeight);
|
|
609
|
+
DebugLogger.timeEnd("performance", "calculateLayout");
|
|
610
|
+
invalidateParentLayoutIfNeeded(
|
|
611
|
+
container,
|
|
612
|
+
oldContainerSize,
|
|
613
|
+
adjustedContainerWidth,
|
|
614
|
+
adjustedContainerHeight
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
function calculateLayout(container, containerProps, parentSize, parentPadding) {
|
|
618
|
+
LayoutBatchQueue.schedule(container, containerProps, parentSize, parentPadding);
|
|
619
|
+
}
|
|
620
|
+
export {
|
|
621
|
+
DeferredLayoutQueue,
|
|
622
|
+
LayoutBatchQueue,
|
|
623
|
+
calculateLayout,
|
|
624
|
+
registerApplyOverflowClip,
|
|
625
|
+
setAfterLayout,
|
|
626
|
+
setApplyOverflowClip
|
|
627
|
+
};
|
|
628
|
+
//# sourceMappingURL=layout-engine.js.map
|