react-native-gtkx 0.1.0-alpha.1
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 +21 -0
- package/README.md +73 -0
- package/dist/animated/composite.d.ts +5 -0
- package/dist/animated/composite.js +132 -0
- package/dist/animated/composite.js.map +1 -0
- package/dist/animated/create-animated.d.ts +12 -0
- package/dist/animated/create-animated.js +17 -0
- package/dist/animated/create-animated.js.map +1 -0
- package/dist/animated/easing.d.ts +11 -0
- package/dist/animated/easing.js +91 -0
- package/dist/animated/easing.js.map +1 -0
- package/dist/animated/frame-loop.d.ts +6 -0
- package/dist/animated/frame-loop.js +25 -0
- package/dist/animated/frame-loop.js.map +1 -0
- package/dist/animated/index.d.ts +6 -0
- package/dist/animated/index.js +7 -0
- package/dist/animated/index.js.map +1 -0
- package/dist/animated/interpolate.d.ts +2 -0
- package/dist/animated/interpolate.js +90 -0
- package/dist/animated/interpolate.js.map +1 -0
- package/dist/animated/native-driver.d.ts +1 -0
- package/dist/animated/native-driver.js +17 -0
- package/dist/animated/native-driver.js.map +1 -0
- package/dist/animated/spring.d.ts +3 -0
- package/dist/animated/spring.js +67 -0
- package/dist/animated/spring.js.map +1 -0
- package/dist/animated/timing.d.ts +3 -0
- package/dist/animated/timing.js +30 -0
- package/dist/animated/timing.js.map +1 -0
- package/dist/animated/types.d.ts +51 -0
- package/dist/animated/types.js +6 -0
- package/dist/animated/types.js.map +1 -0
- package/dist/animated/value-animation.d.ts +9 -0
- package/dist/animated/value-animation.js +65 -0
- package/dist/animated/value-animation.js.map +1 -0
- package/dist/animated/value.d.ts +46 -0
- package/dist/animated/value.js +130 -0
- package/dist/animated/value.js.map +1 -0
- package/dist/apis/alert.d.ts +16 -0
- package/dist/apis/alert.js +33 -0
- package/dist/apis/alert.js.map +1 -0
- package/dist/apis/app-state.d.ts +11 -0
- package/dist/apis/app-state.js +54 -0
- package/dist/apis/app-state.js.map +1 -0
- package/dist/apis/appearance.d.ts +12 -0
- package/dist/apis/appearance.js +33 -0
- package/dist/apis/appearance.js.map +1 -0
- package/dist/apis/dev-settings.d.ts +9 -0
- package/dist/apis/dev-settings.js +25 -0
- package/dist/apis/dev-settings.js.map +1 -0
- package/dist/apis/dimensions.d.ts +14 -0
- package/dist/apis/dimensions.js +80 -0
- package/dist/apis/dimensions.js.map +1 -0
- package/dist/apis/emitter.d.ts +8 -0
- package/dist/apis/emitter.js +35 -0
- package/dist/apis/emitter.js.map +1 -0
- package/dist/apis/hooks.d.ts +11 -0
- package/dist/apis/hooks.js +29 -0
- package/dist/apis/hooks.js.map +1 -0
- package/dist/apis/host.d.ts +45 -0
- package/dist/apis/host.gtkx.d.ts +2 -0
- package/dist/apis/host.gtkx.js +301 -0
- package/dist/apis/host.gtkx.js.map +1 -0
- package/dist/apis/host.js +6 -0
- package/dist/apis/host.js.map +1 -0
- package/dist/apis/index.d.ts +39 -0
- package/dist/apis/index.js +21 -0
- package/dist/apis/index.js.map +1 -0
- package/dist/apis/linking.d.ts +7 -0
- package/dist/apis/linking.js +28 -0
- package/dist/apis/linking.js.map +1 -0
- package/dist/apis/platform.d.ts +14 -0
- package/dist/apis/platform.js +23 -0
- package/dist/apis/platform.js.map +1 -0
- package/dist/components/activity-indicator.d.ts +10 -0
- package/dist/components/activity-indicator.js +21 -0
- package/dist/components/activity-indicator.js.map +1 -0
- package/dist/components/animated.d.ts +34 -0
- package/dist/components/animated.js +152 -0
- package/dist/components/animated.js.map +1 -0
- package/dist/components/app-registry.d.ts +14 -0
- package/dist/components/app-registry.js +61 -0
- package/dist/components/app-registry.js.map +1 -0
- package/dist/components/flat-list.d.ts +48 -0
- package/dist/components/flat-list.js +23 -0
- package/dist/components/flat-list.js.map +1 -0
- package/dist/components/host-node.d.ts +10 -0
- package/dist/components/host-node.js +10 -0
- package/dist/components/host-node.js.map +1 -0
- package/dist/components/image-loader.d.ts +17 -0
- package/dist/components/image-loader.js +54 -0
- package/dist/components/image-loader.js.map +1 -0
- package/dist/components/image.d.ts +19 -0
- package/dist/components/image.js +73 -0
- package/dist/components/image.js.map +1 -0
- package/dist/components/index.d.ts +14 -0
- package/dist/components/index.js +14 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/modal.d.ts +12 -0
- package/dist/components/modal.js +18 -0
- package/dist/components/modal.js.map +1 -0
- package/dist/components/pressable.d.ts +33 -0
- package/dist/components/pressable.js +116 -0
- package/dist/components/pressable.js.map +1 -0
- package/dist/components/rect-store.d.ts +17 -0
- package/dist/components/rect-store.js +40 -0
- package/dist/components/rect-store.js.map +1 -0
- package/dist/components/root.d.ts +8 -0
- package/dist/components/root.js +59 -0
- package/dist/components/root.js.map +1 -0
- package/dist/components/scroll-view.d.ts +56 -0
- package/dist/components/scroll-view.js +324 -0
- package/dist/components/scroll-view.js.map +1 -0
- package/dist/components/switch.d.ts +11 -0
- package/dist/components/switch.js +20 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/text-input.d.ts +23 -0
- package/dist/components/text-input.js +151 -0
- package/dist/components/text-input.js.map +1 -0
- package/dist/components/text.d.ts +11 -0
- package/dist/components/text.js +100 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/use-layout-child.d.ts +36 -0
- package/dist/components/use-layout-child.js +177 -0
- package/dist/components/use-layout-child.js.map +1 -0
- package/dist/components/view.d.ts +13 -0
- package/dist/components/view.js +60 -0
- package/dist/components/view.js.map +1 -0
- package/dist/components/virtualized-list.d.ts +67 -0
- package/dist/components/virtualized-list.js +519 -0
- package/dist/components/virtualized-list.js.map +1 -0
- package/dist/contracts.d.ts +119 -0
- package/dist/contracts.js +5 -0
- package/dist/contracts.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +16 -0
- package/dist/gtkx/bridge/index.js +25 -0
- package/dist/gtkx/bridge/index.js.map +1 -0
- package/dist/gtkx/bridge/layout-manager.d.ts +11 -0
- package/dist/gtkx/bridge/layout-manager.js +87 -0
- package/dist/gtkx/bridge/layout-manager.js.map +1 -0
- package/dist/gtkx/bridge/measure.d.ts +9 -0
- package/dist/gtkx/bridge/measure.js +20 -0
- package/dist/gtkx/bridge/measure.js.map +1 -0
- package/dist/gtkx/bridge/theme.d.ts +4 -0
- package/dist/gtkx/bridge/theme.js +5 -0
- package/dist/gtkx/bridge/theme.js.map +1 -0
- package/dist/gtkx/bridge/view-box.d.ts +7 -0
- package/dist/gtkx/bridge/view-box.js +40 -0
- package/dist/gtkx/bridge/view-box.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/apply-style.d.ts +4 -0
- package/dist/layout/apply-style.js +148 -0
- package/dist/layout/apply-style.js.map +1 -0
- package/dist/layout/engine.d.ts +22 -0
- package/dist/layout/engine.js +90 -0
- package/dist/layout/engine.js.map +1 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +4 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/node.d.ts +33 -0
- package/dist/layout/node.js +151 -0
- package/dist/layout/node.js.map +1 -0
- package/dist/layout/yoga.d.ts +13 -0
- package/dist/layout/yoga.js +52 -0
- package/dist/layout/yoga.js.map +1 -0
- package/dist/metro/index.d.ts +42 -0
- package/dist/metro/index.js +119 -0
- package/dist/metro/index.js.map +1 -0
- package/dist/runner/host-dev.d.ts +1 -0
- package/dist/runner/host-dev.js +208 -0
- package/dist/runner/host-dev.js.map +1 -0
- package/dist/runner/host.d.ts +1 -0
- package/dist/runner/host.js +101 -0
- package/dist/runner/host.js.map +1 -0
- package/dist/runner/index.d.ts +26 -0
- package/dist/runner/index.js +179 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/style/colors.d.ts +17 -0
- package/dist/style/colors.js +375 -0
- package/dist/style/colors.js.map +1 -0
- package/dist/style/dev-warning.d.ts +2 -0
- package/dist/style/dev-warning.js +18 -0
- package/dist/style/dev-warning.js.map +1 -0
- package/dist/style/index.d.ts +7 -0
- package/dist/style/index.js +14 -0
- package/dist/style/index.js.map +1 -0
- package/dist/style/registry.d.ts +12 -0
- package/dist/style/registry.gtkx.d.ts +2 -0
- package/dist/style/registry.gtkx.js +9 -0
- package/dist/style/registry.gtkx.js.map +1 -0
- package/dist/style/registry.js +23 -0
- package/dist/style/registry.js.map +1 -0
- package/dist/style/split-style.d.ts +6 -0
- package/dist/style/split-style.js +107 -0
- package/dist/style/split-style.js.map +1 -0
- package/dist/style/style-sheet.d.ts +43 -0
- package/dist/style/style-sheet.js +57 -0
- package/dist/style/style-sheet.js.map +1 -0
- package/dist/style/text-align.d.ts +7 -0
- package/dist/style/text-align.js +22 -0
- package/dist/style/text-align.js.map +1 -0
- package/dist/style/visual-css.d.ts +6 -0
- package/dist/style/visual-css.js +133 -0
- package/dist/style/visual-css.js.map +1 -0
- package/dist/vite/index.d.ts +53 -0
- package/dist/vite/index.js +127 -0
- package/dist/vite/index.js.map +1 -0
- package/package.json +88 -0
- package/react-native.config.js +21 -0
- package/types.d.ts +43 -0
- package/types.js +4 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { ALIGN, DISPLAY, Edge, FLEX_DIRECTION, Gutter, JUSTIFY, OVERFLOW, POSITION, WRAP, } from "./yoga";
|
|
2
|
+
const isPercent = (value) => typeof value === "string" && value.endsWith("%");
|
|
3
|
+
const applyDimension = (value, setters) => {
|
|
4
|
+
if (value === undefined) {
|
|
5
|
+
setters.reset();
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (value === "auto") {
|
|
9
|
+
setters.auto?.();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (isPercent(value)) {
|
|
13
|
+
setters.percent?.(Number.parseFloat(value));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === "number") {
|
|
17
|
+
setters.point(value);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const parseAspectRatio = (value) => {
|
|
21
|
+
if (value === undefined) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === "number") {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
const parts = value.split("/").map((part) => Number.parseFloat(part.trim()));
|
|
28
|
+
if (parts.length === 2 && parts[0] !== undefined && parts[1]) {
|
|
29
|
+
return parts[0] / parts[1];
|
|
30
|
+
}
|
|
31
|
+
const single = Number.parseFloat(value);
|
|
32
|
+
return Number.isNaN(single) ? undefined : single;
|
|
33
|
+
};
|
|
34
|
+
// React Native defaults differ from raw Yoga: column direction, flexShrink 0,
|
|
35
|
+
// align-content flex-start, position relative. Applied at node creation and
|
|
36
|
+
// re-applied when a style prop is removed on update.
|
|
37
|
+
export const applyNodeDefaults = (node) => {
|
|
38
|
+
node.setFlexDirection(FLEX_DIRECTION.column);
|
|
39
|
+
node.setAlignContent(ALIGN["flex-start"]);
|
|
40
|
+
node.setFlexShrink(0);
|
|
41
|
+
node.setPositionType(POSITION.relative);
|
|
42
|
+
};
|
|
43
|
+
const MARGIN_EDGES = [
|
|
44
|
+
["margin", Edge.All],
|
|
45
|
+
["marginHorizontal", Edge.Horizontal],
|
|
46
|
+
["marginVertical", Edge.Vertical],
|
|
47
|
+
["marginTop", Edge.Top],
|
|
48
|
+
["marginBottom", Edge.Bottom],
|
|
49
|
+
["marginLeft", Edge.Left],
|
|
50
|
+
["marginRight", Edge.Right],
|
|
51
|
+
];
|
|
52
|
+
const PADDING_EDGES = [
|
|
53
|
+
["padding", Edge.All],
|
|
54
|
+
["paddingHorizontal", Edge.Horizontal],
|
|
55
|
+
["paddingVertical", Edge.Vertical],
|
|
56
|
+
["paddingTop", Edge.Top],
|
|
57
|
+
["paddingBottom", Edge.Bottom],
|
|
58
|
+
["paddingLeft", Edge.Left],
|
|
59
|
+
["paddingRight", Edge.Right],
|
|
60
|
+
];
|
|
61
|
+
const POSITION_EDGES = [
|
|
62
|
+
["top", Edge.Top],
|
|
63
|
+
["bottom", Edge.Bottom],
|
|
64
|
+
["left", Edge.Left],
|
|
65
|
+
["right", Edge.Right],
|
|
66
|
+
];
|
|
67
|
+
// Applies an RN layout style onto a Yoga node. Handles prop removal by
|
|
68
|
+
// resetting to RN defaults, so updates never leak stale values.
|
|
69
|
+
export const applyLayoutStyle = (node, style) => {
|
|
70
|
+
node.setFlexDirection(FLEX_DIRECTION[style.flexDirection ?? "column"] ?? FLEX_DIRECTION.column);
|
|
71
|
+
node.setJustifyContent(JUSTIFY[style.justifyContent ?? "flex-start"]);
|
|
72
|
+
node.setAlignItems(ALIGN[style.alignItems ?? "stretch"] ?? ALIGN.stretch);
|
|
73
|
+
node.setAlignSelf(ALIGN[style.alignSelf ?? "auto"] ?? ALIGN.auto);
|
|
74
|
+
node.setAlignContent(ALIGN[style.alignContent ?? "flex-start"] ?? ALIGN["flex-start"]);
|
|
75
|
+
node.setFlexWrap(WRAP[style.flexWrap ?? "nowrap"]);
|
|
76
|
+
node.setPositionType(POSITION[style.position ?? "relative"]);
|
|
77
|
+
node.setOverflow(OVERFLOW[style.overflow ?? "visible"]);
|
|
78
|
+
node.setDisplay(DISPLAY[style.display ?? "flex"]);
|
|
79
|
+
node.setFlex(style.flex ?? Number.NaN);
|
|
80
|
+
node.setFlexGrow(style.flexGrow ?? Number.NaN);
|
|
81
|
+
node.setFlexShrink(style.flexShrink ?? 0);
|
|
82
|
+
applyDimension(style.flexBasis, {
|
|
83
|
+
point: (v) => node.setFlexBasis(v),
|
|
84
|
+
percent: (v) => node.setFlexBasisPercent(v),
|
|
85
|
+
auto: () => node.setFlexBasisAuto(),
|
|
86
|
+
reset: () => node.setFlexBasisAuto(),
|
|
87
|
+
});
|
|
88
|
+
applyDimension(style.width, {
|
|
89
|
+
point: (v) => node.setWidth(v),
|
|
90
|
+
percent: (v) => node.setWidthPercent(v),
|
|
91
|
+
auto: () => node.setWidthAuto(),
|
|
92
|
+
reset: () => node.setWidthAuto(),
|
|
93
|
+
});
|
|
94
|
+
applyDimension(style.height, {
|
|
95
|
+
point: (v) => node.setHeight(v),
|
|
96
|
+
percent: (v) => node.setHeightPercent(v),
|
|
97
|
+
auto: () => node.setHeightAuto(),
|
|
98
|
+
reset: () => node.setHeightAuto(),
|
|
99
|
+
});
|
|
100
|
+
applyDimension(style.minWidth, {
|
|
101
|
+
point: (v) => node.setMinWidth(v),
|
|
102
|
+
percent: (v) => node.setMinWidthPercent(v),
|
|
103
|
+
reset: () => node.setMinWidth(Number.NaN),
|
|
104
|
+
});
|
|
105
|
+
applyDimension(style.minHeight, {
|
|
106
|
+
point: (v) => node.setMinHeight(v),
|
|
107
|
+
percent: (v) => node.setMinHeightPercent(v),
|
|
108
|
+
reset: () => node.setMinHeight(Number.NaN),
|
|
109
|
+
});
|
|
110
|
+
applyDimension(style.maxWidth, {
|
|
111
|
+
point: (v) => node.setMaxWidth(v),
|
|
112
|
+
percent: (v) => node.setMaxWidthPercent(v),
|
|
113
|
+
reset: () => node.setMaxWidth(Number.NaN),
|
|
114
|
+
});
|
|
115
|
+
applyDimension(style.maxHeight, {
|
|
116
|
+
point: (v) => node.setMaxHeight(v),
|
|
117
|
+
percent: (v) => node.setMaxHeightPercent(v),
|
|
118
|
+
reset: () => node.setMaxHeight(Number.NaN),
|
|
119
|
+
});
|
|
120
|
+
for (const [prop, edge] of MARGIN_EDGES) {
|
|
121
|
+
applyDimension(style[prop], {
|
|
122
|
+
point: (v) => node.setMargin(edge, v),
|
|
123
|
+
percent: (v) => node.setMarginPercent(edge, v),
|
|
124
|
+
auto: () => node.setMarginAuto(edge),
|
|
125
|
+
reset: () => node.setMargin(edge, Number.NaN),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
for (const [prop, edge] of PADDING_EDGES) {
|
|
129
|
+
applyDimension(style[prop], {
|
|
130
|
+
point: (v) => node.setPadding(edge, v),
|
|
131
|
+
percent: (v) => node.setPaddingPercent(edge, v),
|
|
132
|
+
reset: () => node.setPadding(edge, Number.NaN),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
for (const [prop, edge] of POSITION_EDGES) {
|
|
136
|
+
applyDimension(style[prop], {
|
|
137
|
+
point: (v) => node.setPosition(edge, v),
|
|
138
|
+
percent: (v) => node.setPositionPercent(edge, v),
|
|
139
|
+
reset: () => node.setPosition(edge, Number.NaN),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
node.setGap(Gutter.All, style.gap ?? Number.NaN);
|
|
143
|
+
node.setGap(Gutter.Row, style.rowGap ?? Number.NaN);
|
|
144
|
+
node.setGap(Gutter.Column, style.columnGap ?? Number.NaN);
|
|
145
|
+
const aspectRatio = parseAspectRatio(style.aspectRatio);
|
|
146
|
+
node.setAspectRatio(aspectRatio ?? Number.NaN);
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=apply-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-style.js","sourceRoot":"","sources":["../../src/layout/apply-style.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DimensionValue, LayoutStyle } from \"../contracts\"\nimport {\n ALIGN,\n DISPLAY,\n Edge,\n FLEX_DIRECTION,\n Gutter,\n JUSTIFY,\n OVERFLOW,\n POSITION,\n WRAP,\n type YogaNode,\n} from \"./yoga\"\n\ntype DimensionSetters = {\n point: (value: number) => void\n percent?: (value: number) => void\n auto?: () => void\n reset: () => void\n}\n\nconst isPercent = (value: DimensionValue): value is `${number}%` =>\n typeof value === \"string\" && value.endsWith(\"%\")\n\nconst applyDimension = (\n value: DimensionValue | undefined,\n setters: DimensionSetters,\n): void => {\n if (value === undefined) {\n setters.reset()\n return\n }\n if (value === \"auto\") {\n setters.auto?.()\n return\n }\n if (isPercent(value)) {\n setters.percent?.(Number.parseFloat(value))\n return\n }\n if (typeof value === \"number\") {\n setters.point(value)\n }\n}\n\nconst parseAspectRatio = (\n value: number | string | undefined,\n): number | undefined => {\n if (value === undefined) {\n return undefined\n }\n if (typeof value === \"number\") {\n return value\n }\n const parts = value.split(\"/\").map((part) => Number.parseFloat(part.trim()))\n if (parts.length === 2 && parts[0] !== undefined && parts[1]) {\n return parts[0] / parts[1]\n }\n const single = Number.parseFloat(value)\n return Number.isNaN(single) ? undefined : single\n}\n\n// React Native defaults differ from raw Yoga: column direction, flexShrink 0,\n// align-content flex-start, position relative. Applied at node creation and\n// re-applied when a style prop is removed on update.\nexport const applyNodeDefaults = (node: YogaNode): void => {\n node.setFlexDirection(FLEX_DIRECTION.column)\n node.setAlignContent(ALIGN[\"flex-start\"])\n node.setFlexShrink(0)\n node.setPositionType(POSITION.relative)\n}\n\ntype EdgeDimensionProps = Extract<\n keyof LayoutStyle,\n | `margin${string}`\n | `padding${string}`\n | \"margin\"\n | \"padding\"\n | \"top\"\n | \"left\"\n | \"right\"\n | \"bottom\"\n>\n\nconst MARGIN_EDGES: ReadonlyArray<[EdgeDimensionProps, Edge]> = [\n [\"margin\", Edge.All],\n [\"marginHorizontal\", Edge.Horizontal],\n [\"marginVertical\", Edge.Vertical],\n [\"marginTop\", Edge.Top],\n [\"marginBottom\", Edge.Bottom],\n [\"marginLeft\", Edge.Left],\n [\"marginRight\", Edge.Right],\n]\n\nconst PADDING_EDGES: ReadonlyArray<[EdgeDimensionProps, Edge]> = [\n [\"padding\", Edge.All],\n [\"paddingHorizontal\", Edge.Horizontal],\n [\"paddingVertical\", Edge.Vertical],\n [\"paddingTop\", Edge.Top],\n [\"paddingBottom\", Edge.Bottom],\n [\"paddingLeft\", Edge.Left],\n [\"paddingRight\", Edge.Right],\n]\n\nconst POSITION_EDGES: ReadonlyArray<[EdgeDimensionProps, Edge]> = [\n [\"top\", Edge.Top],\n [\"bottom\", Edge.Bottom],\n [\"left\", Edge.Left],\n [\"right\", Edge.Right],\n]\n\n// Applies an RN layout style onto a Yoga node. Handles prop removal by\n// resetting to RN defaults, so updates never leak stale values.\nexport const applyLayoutStyle = (node: YogaNode, style: LayoutStyle): void => {\n node.setFlexDirection(\n FLEX_DIRECTION[style.flexDirection ?? \"column\"] ?? FLEX_DIRECTION.column,\n )\n node.setJustifyContent(JUSTIFY[style.justifyContent ?? \"flex-start\"])\n node.setAlignItems(ALIGN[style.alignItems ?? \"stretch\"] ?? ALIGN.stretch)\n node.setAlignSelf(ALIGN[style.alignSelf ?? \"auto\"] ?? ALIGN.auto)\n node.setAlignContent(\n ALIGN[style.alignContent ?? \"flex-start\"] ?? ALIGN[\"flex-start\"],\n )\n node.setFlexWrap(WRAP[style.flexWrap ?? \"nowrap\"])\n node.setPositionType(POSITION[style.position ?? \"relative\"])\n node.setOverflow(OVERFLOW[style.overflow ?? \"visible\"])\n node.setDisplay(DISPLAY[style.display ?? \"flex\"])\n\n node.setFlex(style.flex ?? Number.NaN)\n node.setFlexGrow(style.flexGrow ?? Number.NaN)\n node.setFlexShrink(style.flexShrink ?? 0)\n\n applyDimension(style.flexBasis, {\n point: (v) => node.setFlexBasis(v),\n percent: (v) => node.setFlexBasisPercent(v),\n auto: () => node.setFlexBasisAuto(),\n reset: () => node.setFlexBasisAuto(),\n })\n applyDimension(style.width, {\n point: (v) => node.setWidth(v),\n percent: (v) => node.setWidthPercent(v),\n auto: () => node.setWidthAuto(),\n reset: () => node.setWidthAuto(),\n })\n applyDimension(style.height, {\n point: (v) => node.setHeight(v),\n percent: (v) => node.setHeightPercent(v),\n auto: () => node.setHeightAuto(),\n reset: () => node.setHeightAuto(),\n })\n applyDimension(style.minWidth, {\n point: (v) => node.setMinWidth(v),\n percent: (v) => node.setMinWidthPercent(v),\n reset: () => node.setMinWidth(Number.NaN),\n })\n applyDimension(style.minHeight, {\n point: (v) => node.setMinHeight(v),\n percent: (v) => node.setMinHeightPercent(v),\n reset: () => node.setMinHeight(Number.NaN),\n })\n applyDimension(style.maxWidth, {\n point: (v) => node.setMaxWidth(v),\n percent: (v) => node.setMaxWidthPercent(v),\n reset: () => node.setMaxWidth(Number.NaN),\n })\n applyDimension(style.maxHeight, {\n point: (v) => node.setMaxHeight(v),\n percent: (v) => node.setMaxHeightPercent(v),\n reset: () => node.setMaxHeight(Number.NaN),\n })\n\n for (const [prop, edge] of MARGIN_EDGES) {\n applyDimension(style[prop], {\n point: (v) => node.setMargin(edge, v),\n percent: (v) => node.setMarginPercent(edge, v),\n auto: () => node.setMarginAuto(edge),\n reset: () => node.setMargin(edge, Number.NaN),\n })\n }\n for (const [prop, edge] of PADDING_EDGES) {\n applyDimension(style[prop], {\n point: (v) => node.setPadding(edge, v),\n percent: (v) => node.setPaddingPercent(edge, v),\n reset: () => node.setPadding(edge, Number.NaN),\n })\n }\n for (const [prop, edge] of POSITION_EDGES) {\n applyDimension(style[prop], {\n point: (v) => node.setPosition(edge, v),\n percent: (v) => node.setPositionPercent(edge, v),\n reset: () => node.setPosition(edge, Number.NaN),\n })\n }\n\n node.setGap(Gutter.All, style.gap ?? Number.NaN)\n node.setGap(Gutter.Row, style.rowGap ?? Number.NaN)\n node.setGap(Gutter.Column, style.columnGap ?? Number.NaN)\n\n const aspectRatio = parseAspectRatio(style.aspectRatio)\n node.setAspectRatio(aspectRatio ?? Number.NaN)\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LayoutNode } from "./node";
|
|
2
|
+
export type ViewportSize = {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
};
|
|
6
|
+
export declare class LayoutEngine {
|
|
7
|
+
readonly root: LayoutNode;
|
|
8
|
+
private viewport;
|
|
9
|
+
private dirty;
|
|
10
|
+
private scheduled;
|
|
11
|
+
private disposed;
|
|
12
|
+
constructor(viewport: ViewportSize);
|
|
13
|
+
createNode(): LayoutNode;
|
|
14
|
+
setViewport(viewport: ViewportSize): void;
|
|
15
|
+
getViewport(): ViewportSize;
|
|
16
|
+
flushSync(): void;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
private requestFlush;
|
|
19
|
+
private commitTree;
|
|
20
|
+
private collectChanges;
|
|
21
|
+
private freeTree;
|
|
22
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { LayoutNode } from "./node";
|
|
2
|
+
import { Direction } from "./yoga";
|
|
3
|
+
// One engine per window root. Batches every mutation (style, tree, measure
|
|
4
|
+
// invalidation) into a single Yoga pass per microtask, then walks the shadow
|
|
5
|
+
// tree, diffs rects and fires commit (widget move) + onLayout callbacks only
|
|
6
|
+
// for nodes whose rect actually changed.
|
|
7
|
+
export class LayoutEngine {
|
|
8
|
+
root;
|
|
9
|
+
viewport;
|
|
10
|
+
dirty = false;
|
|
11
|
+
scheduled = false;
|
|
12
|
+
disposed = false;
|
|
13
|
+
constructor(viewport) {
|
|
14
|
+
this.viewport = viewport;
|
|
15
|
+
this.root = new LayoutNode(this.requestFlush);
|
|
16
|
+
}
|
|
17
|
+
createNode() {
|
|
18
|
+
return new LayoutNode(this.requestFlush);
|
|
19
|
+
}
|
|
20
|
+
setViewport(viewport) {
|
|
21
|
+
if (viewport.width === this.viewport.width &&
|
|
22
|
+
viewport.height === this.viewport.height) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.viewport = viewport;
|
|
26
|
+
this.requestFlush();
|
|
27
|
+
}
|
|
28
|
+
getViewport() {
|
|
29
|
+
return this.viewport;
|
|
30
|
+
}
|
|
31
|
+
// Synchronous pass — used by tests and by resize handling when the caller
|
|
32
|
+
// needs rects immediately after a mutation.
|
|
33
|
+
flushSync() {
|
|
34
|
+
if (!this.dirty || this.disposed) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.dirty = false;
|
|
38
|
+
this.root.yoga.calculateLayout(this.viewport.width, this.viewport.height, Direction.LTR);
|
|
39
|
+
this.commitTree(this.root);
|
|
40
|
+
}
|
|
41
|
+
dispose() {
|
|
42
|
+
if (this.disposed) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.disposed = true;
|
|
46
|
+
this.freeTree(this.root);
|
|
47
|
+
}
|
|
48
|
+
requestFlush = () => {
|
|
49
|
+
this.dirty = true;
|
|
50
|
+
if (this.scheduled || this.disposed) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.scheduled = true;
|
|
54
|
+
queueMicrotask(() => {
|
|
55
|
+
this.scheduled = false;
|
|
56
|
+
this.flushSync();
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
// Pre-order walk: parents commit before children so a child is always
|
|
60
|
+
// positioned inside an already-sized container.
|
|
61
|
+
commitTree(node) {
|
|
62
|
+
const entries = [];
|
|
63
|
+
this.collectChanges(node, entries);
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
entry.node.notifyCommit(entry.rect);
|
|
66
|
+
}
|
|
67
|
+
// onLayout fires after the whole pass is committed, like React Native.
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
if (entry.changed) {
|
|
70
|
+
entry.node.notifyLayout(entry.rect);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
collectChanges(node, out) {
|
|
75
|
+
const change = node.collectChange();
|
|
76
|
+
if (change !== null) {
|
|
77
|
+
out.push({ node, rect: change.rect, changed: change.changed });
|
|
78
|
+
}
|
|
79
|
+
for (const child of node.children) {
|
|
80
|
+
this.collectChanges(child, out);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
freeTree(node) {
|
|
84
|
+
for (const child of [...node.children]) {
|
|
85
|
+
this.freeTree(child);
|
|
86
|
+
}
|
|
87
|
+
node.free();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/layout/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Rect } from \"../contracts\"\nimport { LayoutNode } from \"./node\"\nimport { Direction } from \"./yoga\"\n\nexport type ViewportSize = { width: number; height: number }\n\n// One engine per window root. Batches every mutation (style, tree, measure\n// invalidation) into a single Yoga pass per microtask, then walks the shadow\n// tree, diffs rects and fires commit (widget move) + onLayout callbacks only\n// for nodes whose rect actually changed.\nexport class LayoutEngine {\n readonly root: LayoutNode\n\n private viewport: ViewportSize\n private dirty = false\n private scheduled = false\n private disposed = false\n\n constructor(viewport: ViewportSize) {\n this.viewport = viewport\n this.root = new LayoutNode(this.requestFlush)\n }\n\n createNode(): LayoutNode {\n return new LayoutNode(this.requestFlush)\n }\n\n setViewport(viewport: ViewportSize): void {\n if (\n viewport.width === this.viewport.width &&\n viewport.height === this.viewport.height\n ) {\n return\n }\n this.viewport = viewport\n this.requestFlush()\n }\n\n getViewport(): ViewportSize {\n return this.viewport\n }\n\n // Synchronous pass — used by tests and by resize handling when the caller\n // needs rects immediately after a mutation.\n flushSync(): void {\n if (!this.dirty || this.disposed) {\n return\n }\n this.dirty = false\n this.root.yoga.calculateLayout(\n this.viewport.width,\n this.viewport.height,\n Direction.LTR,\n )\n this.commitTree(this.root)\n }\n\n dispose(): void {\n if (this.disposed) {\n return\n }\n this.disposed = true\n this.freeTree(this.root)\n }\n\n private requestFlush = (): void => {\n this.dirty = true\n if (this.scheduled || this.disposed) {\n return\n }\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flushSync()\n })\n }\n\n // Pre-order walk: parents commit before children so a child is always\n // positioned inside an already-sized container.\n private commitTree(node: LayoutNode): void {\n const entries: Array<{ node: LayoutNode; rect: Rect; changed: boolean }> =\n []\n this.collectChanges(node, entries)\n for (const entry of entries) {\n entry.node.notifyCommit(entry.rect)\n }\n // onLayout fires after the whole pass is committed, like React Native.\n for (const entry of entries) {\n if (entry.changed) {\n entry.node.notifyLayout(entry.rect)\n }\n }\n }\n\n private collectChanges(\n node: LayoutNode,\n out: Array<{ node: LayoutNode; rect: Rect; changed: boolean }>,\n ): void {\n const change = node.collectChange()\n if (change !== null) {\n out.push({ node, rect: change.rect, changed: change.changed })\n }\n for (const child of node.children) {\n this.collectChanges(child, out)\n }\n }\n\n private freeTree(node: LayoutNode): void {\n for (const child of [...node.children]) {\n this.freeTree(child)\n }\n node.free()\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,YAAY,EAAqB,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA","sourcesContent":["export { applyLayoutStyle, applyNodeDefaults } from \"./apply-style\"\nexport { LayoutEngine, type ViewportSize } from \"./engine\"\nexport { getLiveNodeCount, LayoutNode } from \"./node\"\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { LayoutNodeApi, LayoutStyle, MeasureFn, Rect } from "../contracts";
|
|
2
|
+
import { type YogaNode } from "./yoga";
|
|
3
|
+
type DirtyListener = () => void;
|
|
4
|
+
export declare const getLiveNodeCount: () => number;
|
|
5
|
+
export declare class LayoutNode implements LayoutNodeApi {
|
|
6
|
+
readonly yoga: YogaNode;
|
|
7
|
+
parent: LayoutNode | null;
|
|
8
|
+
readonly children: LayoutNode[];
|
|
9
|
+
private onDirty;
|
|
10
|
+
private onLayoutCallback;
|
|
11
|
+
private commitCallback;
|
|
12
|
+
private lastRect;
|
|
13
|
+
private freed;
|
|
14
|
+
private hasMeasure;
|
|
15
|
+
private forceCommit;
|
|
16
|
+
constructor(onDirty: DirtyListener);
|
|
17
|
+
setStyle(style: LayoutStyle): void;
|
|
18
|
+
setMeasureFn(measure: MeasureFn | null): void;
|
|
19
|
+
markDirty(): void;
|
|
20
|
+
getRect(): Rect | null;
|
|
21
|
+
setOnLayout(callback: ((rect: Rect) => void) | null): void;
|
|
22
|
+
setCommit(callback: ((rect: Rect) => void) | null): void;
|
|
23
|
+
insertChild(child: LayoutNode, index: number): void;
|
|
24
|
+
removeChild(child: LayoutNode): void;
|
|
25
|
+
collectChange(): {
|
|
26
|
+
rect: Rect;
|
|
27
|
+
changed: boolean;
|
|
28
|
+
} | null;
|
|
29
|
+
notifyCommit(rect: Rect): void;
|
|
30
|
+
notifyLayout(rect: Rect): void;
|
|
31
|
+
free(): void;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { applyLayoutStyle, applyNodeDefaults } from "./apply-style";
|
|
2
|
+
import { createYogaNode, MEASURE_MODE } from "./yoga";
|
|
3
|
+
let liveNodeCount = 0;
|
|
4
|
+
// Number of not-yet-freed nodes; used by tests to detect leaks.
|
|
5
|
+
export const getLiveNodeCount = () => liveNodeCount;
|
|
6
|
+
// Shadow-tree node: owns one Yoga node, mirrors the React component tree.
|
|
7
|
+
// Components talk to it through the LayoutNodeApi contract; the engine walks
|
|
8
|
+
// it after every layout pass to diff rects and notify commit/onLayout hooks.
|
|
9
|
+
export class LayoutNode {
|
|
10
|
+
yoga;
|
|
11
|
+
parent = null;
|
|
12
|
+
children = [];
|
|
13
|
+
onDirty;
|
|
14
|
+
onLayoutCallback = null;
|
|
15
|
+
commitCallback = null;
|
|
16
|
+
lastRect = null;
|
|
17
|
+
freed = false;
|
|
18
|
+
hasMeasure = false;
|
|
19
|
+
forceCommit = false;
|
|
20
|
+
constructor(onDirty) {
|
|
21
|
+
this.yoga = createYogaNode();
|
|
22
|
+
applyNodeDefaults(this.yoga);
|
|
23
|
+
this.onDirty = onDirty;
|
|
24
|
+
liveNodeCount += 1;
|
|
25
|
+
}
|
|
26
|
+
setStyle(style) {
|
|
27
|
+
if (this.freed) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
applyLayoutStyle(this.yoga, style);
|
|
31
|
+
this.onDirty();
|
|
32
|
+
}
|
|
33
|
+
setMeasureFn(measure) {
|
|
34
|
+
if (this.freed) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (measure === null) {
|
|
38
|
+
// Unsetting an absent measure func destroys a null wasm binding and
|
|
39
|
+
// crashes yoga-wasm — track presence explicitly.
|
|
40
|
+
if (this.hasMeasure) {
|
|
41
|
+
this.yoga.unsetMeasureFunc();
|
|
42
|
+
this.hasMeasure = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.yoga.setMeasureFunc((width, widthMode, height, heightMode) => measure(width, MEASURE_MODE[widthMode], height, MEASURE_MODE[heightMode]));
|
|
47
|
+
this.hasMeasure = true;
|
|
48
|
+
}
|
|
49
|
+
this.onDirty();
|
|
50
|
+
}
|
|
51
|
+
markDirty() {
|
|
52
|
+
// Only measure-backed leaves may be marked dirty in Yoga.
|
|
53
|
+
if (this.freed || !this.hasMeasure) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.yoga.markDirty();
|
|
57
|
+
// Re-measuring resets the widget size request; even an unchanged rect
|
|
58
|
+
// must recommit so the request is re-applied.
|
|
59
|
+
this.forceCommit = true;
|
|
60
|
+
this.onDirty();
|
|
61
|
+
}
|
|
62
|
+
getRect() {
|
|
63
|
+
return this.lastRect;
|
|
64
|
+
}
|
|
65
|
+
setOnLayout(callback) {
|
|
66
|
+
this.onLayoutCallback = callback;
|
|
67
|
+
}
|
|
68
|
+
// The commit hook is the write path to GTK: the component layer moves its
|
|
69
|
+
// widget's stored rect when the engine reports a new one.
|
|
70
|
+
setCommit(callback) {
|
|
71
|
+
this.commitCallback = callback;
|
|
72
|
+
// A late-registered commit hook must still receive the current rect.
|
|
73
|
+
if (callback !== null && this.lastRect !== null) {
|
|
74
|
+
callback(this.lastRect);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
insertChild(child, index) {
|
|
78
|
+
if (this.freed || child.freed) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
child.parent = this;
|
|
82
|
+
this.children.splice(index, 0, child);
|
|
83
|
+
this.yoga.insertChild(child.yoga, index);
|
|
84
|
+
this.onDirty();
|
|
85
|
+
}
|
|
86
|
+
removeChild(child) {
|
|
87
|
+
const index = this.children.indexOf(child);
|
|
88
|
+
if (index === -1) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.children.splice(index, 1);
|
|
92
|
+
child.parent = null;
|
|
93
|
+
// Touching the wasm node of a freed parent corrupts the emscripten heap.
|
|
94
|
+
if (!this.freed && !child.freed) {
|
|
95
|
+
this.yoga.removeChild(child.yoga);
|
|
96
|
+
this.onDirty();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Reads the computed rect (parent-relative). Measured leaves always
|
|
100
|
+
// recommit: any Yoga-invoked re-measure resets their widget size request,
|
|
101
|
+
// and Yoga may re-measure without markDirty (constraint changes), so the
|
|
102
|
+
// request must be re-applied after every pass. onLayout still fires only
|
|
103
|
+
// on real changes.
|
|
104
|
+
collectChange() {
|
|
105
|
+
const rect = {
|
|
106
|
+
x: this.yoga.getComputedLeft(),
|
|
107
|
+
y: this.yoga.getComputedTop(),
|
|
108
|
+
width: this.yoga.getComputedWidth(),
|
|
109
|
+
height: this.yoga.getComputedHeight(),
|
|
110
|
+
};
|
|
111
|
+
const previous = this.lastRect;
|
|
112
|
+
const unchanged = previous !== null &&
|
|
113
|
+
previous.x === rect.x &&
|
|
114
|
+
previous.y === rect.y &&
|
|
115
|
+
previous.width === rect.width &&
|
|
116
|
+
previous.height === rect.height;
|
|
117
|
+
const changed = this.forceCommit || !unchanged;
|
|
118
|
+
this.forceCommit = false;
|
|
119
|
+
if (!changed && !this.hasMeasure) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
this.lastRect = rect;
|
|
123
|
+
return { rect, changed };
|
|
124
|
+
}
|
|
125
|
+
notifyCommit(rect) {
|
|
126
|
+
this.commitCallback?.(rect);
|
|
127
|
+
}
|
|
128
|
+
notifyLayout(rect) {
|
|
129
|
+
this.onLayoutCallback?.(rect);
|
|
130
|
+
}
|
|
131
|
+
free() {
|
|
132
|
+
if (this.freed) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.parent?.removeChild(this);
|
|
136
|
+
// React unmounts parents before children (effect cleanup order), so a
|
|
137
|
+
// container can be freed while its children are still linked — detach
|
|
138
|
+
// them first or their own free() would touch freed wasm memory.
|
|
139
|
+
for (const child of [...this.children]) {
|
|
140
|
+
this.removeChild(child);
|
|
141
|
+
}
|
|
142
|
+
if (this.hasMeasure) {
|
|
143
|
+
this.yoga.unsetMeasureFunc();
|
|
144
|
+
this.hasMeasure = false;
|
|
145
|
+
}
|
|
146
|
+
this.freed = true;
|
|
147
|
+
this.yoga.free();
|
|
148
|
+
liveNodeCount -= 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/layout/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LayoutNodeApi, LayoutStyle, MeasureFn, Rect } from \"../contracts\"\nimport { applyLayoutStyle, applyNodeDefaults } from \"./apply-style\"\nimport { createYogaNode, MEASURE_MODE, type YogaNode } from \"./yoga\"\n\ntype DirtyListener = () => void\n\nlet liveNodeCount = 0\n\n// Number of not-yet-freed nodes; used by tests to detect leaks.\nexport const getLiveNodeCount = (): number => liveNodeCount\n\n// Shadow-tree node: owns one Yoga node, mirrors the React component tree.\n// Components talk to it through the LayoutNodeApi contract; the engine walks\n// it after every layout pass to diff rects and notify commit/onLayout hooks.\nexport class LayoutNode implements LayoutNodeApi {\n readonly yoga: YogaNode\n parent: LayoutNode | null = null\n readonly children: LayoutNode[] = []\n\n private onDirty: DirtyListener\n private onLayoutCallback: ((rect: Rect) => void) | null = null\n private commitCallback: ((rect: Rect) => void) | null = null\n private lastRect: Rect | null = null\n private freed = false\n private hasMeasure = false\n private forceCommit = false\n\n constructor(onDirty: DirtyListener) {\n this.yoga = createYogaNode()\n applyNodeDefaults(this.yoga)\n this.onDirty = onDirty\n liveNodeCount += 1\n }\n\n setStyle(style: LayoutStyle): void {\n if (this.freed) {\n return\n }\n applyLayoutStyle(this.yoga, style)\n this.onDirty()\n }\n\n setMeasureFn(measure: MeasureFn | null): void {\n if (this.freed) {\n return\n }\n if (measure === null) {\n // Unsetting an absent measure func destroys a null wasm binding and\n // crashes yoga-wasm — track presence explicitly.\n if (this.hasMeasure) {\n this.yoga.unsetMeasureFunc()\n this.hasMeasure = false\n }\n } else {\n this.yoga.setMeasureFunc((width, widthMode, height, heightMode) =>\n measure(\n width,\n MEASURE_MODE[widthMode],\n height,\n MEASURE_MODE[heightMode],\n ),\n )\n this.hasMeasure = true\n }\n this.onDirty()\n }\n\n markDirty(): void {\n // Only measure-backed leaves may be marked dirty in Yoga.\n if (this.freed || !this.hasMeasure) {\n return\n }\n this.yoga.markDirty()\n // Re-measuring resets the widget size request; even an unchanged rect\n // must recommit so the request is re-applied.\n this.forceCommit = true\n this.onDirty()\n }\n\n getRect(): Rect | null {\n return this.lastRect\n }\n\n setOnLayout(callback: ((rect: Rect) => void) | null): void {\n this.onLayoutCallback = callback\n }\n\n // The commit hook is the write path to GTK: the component layer moves its\n // widget's stored rect when the engine reports a new one.\n setCommit(callback: ((rect: Rect) => void) | null): void {\n this.commitCallback = callback\n // A late-registered commit hook must still receive the current rect.\n if (callback !== null && this.lastRect !== null) {\n callback(this.lastRect)\n }\n }\n\n insertChild(child: LayoutNode, index: number): void {\n if (this.freed || child.freed) {\n return\n }\n child.parent = this\n this.children.splice(index, 0, child)\n this.yoga.insertChild(child.yoga, index)\n this.onDirty()\n }\n\n removeChild(child: LayoutNode): void {\n const index = this.children.indexOf(child)\n if (index === -1) {\n return\n }\n this.children.splice(index, 1)\n child.parent = null\n // Touching the wasm node of a freed parent corrupts the emscripten heap.\n if (!this.freed && !child.freed) {\n this.yoga.removeChild(child.yoga)\n this.onDirty()\n }\n }\n\n // Reads the computed rect (parent-relative). Measured leaves always\n // recommit: any Yoga-invoked re-measure resets their widget size request,\n // and Yoga may re-measure without markDirty (constraint changes), so the\n // request must be re-applied after every pass. onLayout still fires only\n // on real changes.\n collectChange(): { rect: Rect; changed: boolean } | null {\n const rect: Rect = {\n x: this.yoga.getComputedLeft(),\n y: this.yoga.getComputedTop(),\n width: this.yoga.getComputedWidth(),\n height: this.yoga.getComputedHeight(),\n }\n const previous = this.lastRect\n const unchanged =\n previous !== null &&\n previous.x === rect.x &&\n previous.y === rect.y &&\n previous.width === rect.width &&\n previous.height === rect.height\n const changed = this.forceCommit || !unchanged\n this.forceCommit = false\n if (!changed && !this.hasMeasure) {\n return null\n }\n this.lastRect = rect\n return { rect, changed }\n }\n\n notifyCommit(rect: Rect): void {\n this.commitCallback?.(rect)\n }\n\n notifyLayout(rect: Rect): void {\n this.onLayoutCallback?.(rect)\n }\n\n free(): void {\n if (this.freed) {\n return\n }\n this.parent?.removeChild(this)\n // React unmounts parents before children (effect cleanup order), so a\n // container can be freed while its children are still linked — detach\n // them first or their own free() would touch freed wasm memory.\n for (const child of [...this.children]) {\n this.removeChild(child)\n }\n if (this.hasMeasure) {\n this.yoga.unsetMeasureFunc()\n this.hasMeasure = false\n }\n this.freed = true\n this.yoga.free()\n liveNodeCount -= 1\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Yoga, { Align, Direction, Display, Edge, FlexDirection, Gutter, Justify, MeasureMode, Overflow, PositionType, Wrap, type Node as YogaNode } from "yoga-layout";
|
|
2
|
+
import type { FlexAlignType, LayoutStyle, MeasureConstraintMode } from "../contracts";
|
|
3
|
+
export { Direction, Edge, Gutter, MeasureMode, Yoga };
|
|
4
|
+
export type { YogaNode };
|
|
5
|
+
export declare const FLEX_DIRECTION: Record<NonNullable<LayoutStyle["flexDirection"]>, FlexDirection>;
|
|
6
|
+
export declare const JUSTIFY: Record<NonNullable<LayoutStyle["justifyContent"]>, Justify>;
|
|
7
|
+
export declare const ALIGN: Record<"auto" | FlexAlignType | "space-between" | "space-around", Align>;
|
|
8
|
+
export declare const WRAP: Record<NonNullable<LayoutStyle["flexWrap"]>, Wrap>;
|
|
9
|
+
export declare const POSITION: Record<NonNullable<LayoutStyle["position"]>, PositionType>;
|
|
10
|
+
export declare const OVERFLOW: Record<NonNullable<LayoutStyle["overflow"]>, Overflow>;
|
|
11
|
+
export declare const DISPLAY: Record<NonNullable<LayoutStyle["display"]>, Display>;
|
|
12
|
+
export declare const MEASURE_MODE: Record<MeasureMode, MeasureConstraintMode>;
|
|
13
|
+
export declare const createYogaNode: () => YogaNode;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import Yoga, { Align, Direction, Display, Edge, FlexDirection, Gutter, Justify, MeasureMode, Overflow, PositionType, Wrap, } from "yoga-layout";
|
|
2
|
+
export { Direction, Edge, Gutter, MeasureMode, Yoga };
|
|
3
|
+
export const FLEX_DIRECTION = {
|
|
4
|
+
row: FlexDirection.Row,
|
|
5
|
+
"row-reverse": FlexDirection.RowReverse,
|
|
6
|
+
column: FlexDirection.Column,
|
|
7
|
+
"column-reverse": FlexDirection.ColumnReverse,
|
|
8
|
+
};
|
|
9
|
+
export const JUSTIFY = {
|
|
10
|
+
"flex-start": Justify.FlexStart,
|
|
11
|
+
"flex-end": Justify.FlexEnd,
|
|
12
|
+
center: Justify.Center,
|
|
13
|
+
"space-between": Justify.SpaceBetween,
|
|
14
|
+
"space-around": Justify.SpaceAround,
|
|
15
|
+
"space-evenly": Justify.SpaceEvenly,
|
|
16
|
+
};
|
|
17
|
+
export const ALIGN = {
|
|
18
|
+
auto: Align.Auto,
|
|
19
|
+
"flex-start": Align.FlexStart,
|
|
20
|
+
"flex-end": Align.FlexEnd,
|
|
21
|
+
center: Align.Center,
|
|
22
|
+
stretch: Align.Stretch,
|
|
23
|
+
baseline: Align.Baseline,
|
|
24
|
+
"space-between": Align.SpaceBetween,
|
|
25
|
+
"space-around": Align.SpaceAround,
|
|
26
|
+
};
|
|
27
|
+
export const WRAP = {
|
|
28
|
+
nowrap: Wrap.NoWrap,
|
|
29
|
+
wrap: Wrap.Wrap,
|
|
30
|
+
"wrap-reverse": Wrap.WrapReverse,
|
|
31
|
+
};
|
|
32
|
+
export const POSITION = {
|
|
33
|
+
absolute: PositionType.Absolute,
|
|
34
|
+
relative: PositionType.Relative,
|
|
35
|
+
static: PositionType.Static,
|
|
36
|
+
};
|
|
37
|
+
export const OVERFLOW = {
|
|
38
|
+
visible: Overflow.Visible,
|
|
39
|
+
hidden: Overflow.Hidden,
|
|
40
|
+
scroll: Overflow.Scroll,
|
|
41
|
+
};
|
|
42
|
+
export const DISPLAY = {
|
|
43
|
+
none: Display.None,
|
|
44
|
+
flex: Display.Flex,
|
|
45
|
+
};
|
|
46
|
+
export const MEASURE_MODE = {
|
|
47
|
+
[MeasureMode.Undefined]: "undefined",
|
|
48
|
+
[MeasureMode.Exactly]: "exactly",
|
|
49
|
+
[MeasureMode.AtMost]: "at-most",
|
|
50
|
+
};
|
|
51
|
+
export const createYogaNode = () => Yoga.Node.create();
|
|
52
|
+
//# sourceMappingURL=yoga.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yoga.js","sourceRoot":"","sources":["../../src/layout/yoga.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EACX,KAAK,EACL,SAAS,EACT,OAAO,EACP,IAAI,EACJ,aAAa,EACb,MAAM,EACN,OAAO,EACP,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,IAAI,GAEL,MAAM,aAAa,CAAA;AAOpB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;AAGrD,MAAM,CAAC,MAAM,cAAc,GAGvB;IACF,GAAG,EAAE,aAAa,CAAC,GAAG;IACtB,aAAa,EAAE,aAAa,CAAC,UAAU;IACvC,MAAM,EAAE,aAAa,CAAC,MAAM;IAC5B,gBAAgB,EAAE,aAAa,CAAC,aAAa;CAC9C,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAGhB;IACF,YAAY,EAAE,OAAO,CAAC,SAAS;IAC/B,UAAU,EAAE,OAAO,CAAC,OAAO;IAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;IACtB,eAAe,EAAE,OAAO,CAAC,YAAY;IACrC,cAAc,EAAE,OAAO,CAAC,WAAW;IACnC,cAAc,EAAE,OAAO,CAAC,WAAW;CACpC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAGd;IACF,IAAI,EAAE,KAAK,CAAC,IAAI;IAChB,YAAY,EAAE,KAAK,CAAC,SAAS;IAC7B,UAAU,EAAE,KAAK,CAAC,OAAO;IACzB,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,OAAO,EAAE,KAAK,CAAC,OAAO;IACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;IACxB,eAAe,EAAE,KAAK,CAAC,YAAY;IACnC,cAAc,EAAE,KAAK,CAAC,WAAW;CAClC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAuD;IACtE,MAAM,EAAE,IAAI,CAAC,MAAM;IACnB,IAAI,EAAE,IAAI,CAAC,IAAI;IACf,cAAc,EAAE,IAAI,CAAC,WAAW;CACjC,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAGjB;IACF,QAAQ,EAAE,YAAY,CAAC,QAAQ;IAC/B,QAAQ,EAAE,YAAY,CAAC,QAAQ;IAC/B,MAAM,EAAE,YAAY,CAAC,MAAM;CAC5B,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAGjB;IACF,OAAO,EAAE,QAAQ,CAAC,OAAO;IACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;CACxB,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAyD;IAC3E,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,IAAI,EAAE,OAAO,CAAC,IAAI;CACnB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAA+C;IACtE,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,WAAW;IACpC,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,SAAS;IAChC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS;CAChC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,GAAa,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA","sourcesContent":["import Yoga, {\n Align,\n Direction,\n Display,\n Edge,\n FlexDirection,\n Gutter,\n Justify,\n MeasureMode,\n Overflow,\n PositionType,\n Wrap,\n type Node as YogaNode,\n} from \"yoga-layout\"\nimport type {\n FlexAlignType,\n LayoutStyle,\n MeasureConstraintMode,\n} from \"../contracts\"\n\nexport { Direction, Edge, Gutter, MeasureMode, Yoga }\nexport type { YogaNode }\n\nexport const FLEX_DIRECTION: Record<\n NonNullable<LayoutStyle[\"flexDirection\"]>,\n FlexDirection\n> = {\n row: FlexDirection.Row,\n \"row-reverse\": FlexDirection.RowReverse,\n column: FlexDirection.Column,\n \"column-reverse\": FlexDirection.ColumnReverse,\n}\n\nexport const JUSTIFY: Record<\n NonNullable<LayoutStyle[\"justifyContent\"]>,\n Justify\n> = {\n \"flex-start\": Justify.FlexStart,\n \"flex-end\": Justify.FlexEnd,\n center: Justify.Center,\n \"space-between\": Justify.SpaceBetween,\n \"space-around\": Justify.SpaceAround,\n \"space-evenly\": Justify.SpaceEvenly,\n}\n\nexport const ALIGN: Record<\n \"auto\" | FlexAlignType | \"space-between\" | \"space-around\",\n Align\n> = {\n auto: Align.Auto,\n \"flex-start\": Align.FlexStart,\n \"flex-end\": Align.FlexEnd,\n center: Align.Center,\n stretch: Align.Stretch,\n baseline: Align.Baseline,\n \"space-between\": Align.SpaceBetween,\n \"space-around\": Align.SpaceAround,\n}\n\nexport const WRAP: Record<NonNullable<LayoutStyle[\"flexWrap\"]>, Wrap> = {\n nowrap: Wrap.NoWrap,\n wrap: Wrap.Wrap,\n \"wrap-reverse\": Wrap.WrapReverse,\n}\n\nexport const POSITION: Record<\n NonNullable<LayoutStyle[\"position\"]>,\n PositionType\n> = {\n absolute: PositionType.Absolute,\n relative: PositionType.Relative,\n static: PositionType.Static,\n}\n\nexport const OVERFLOW: Record<\n NonNullable<LayoutStyle[\"overflow\"]>,\n Overflow\n> = {\n visible: Overflow.Visible,\n hidden: Overflow.Hidden,\n scroll: Overflow.Scroll,\n}\n\nexport const DISPLAY: Record<NonNullable<LayoutStyle[\"display\"]>, Display> = {\n none: Display.None,\n flex: Display.Flex,\n}\n\nexport const MEASURE_MODE: Record<MeasureMode, MeasureConstraintMode> = {\n [MeasureMode.Undefined]: \"undefined\",\n [MeasureMode.Exactly]: \"exactly\",\n [MeasureMode.AtMost]: \"at-most\",\n}\n\nexport const createYogaNode = (): YogaNode => Yoga.Node.create()\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Modules the run-linux host provides to the bundle at runtime. */
|
|
2
|
+
export declare const HOST_MODULE_EXTERNALS: string[];
|
|
3
|
+
export declare const LINUX_PLATFORM = "linux";
|
|
4
|
+
export type MetroResolutionContext = {
|
|
5
|
+
resolveRequest: MetroResolver;
|
|
6
|
+
};
|
|
7
|
+
export type MetroResolution = {
|
|
8
|
+
type: string;
|
|
9
|
+
filePath?: string;
|
|
10
|
+
};
|
|
11
|
+
export type MetroResolver = (context: MetroResolutionContext, moduleName: string, platform: string | null) => MetroResolution;
|
|
12
|
+
export type MetroLikeConfig = {
|
|
13
|
+
projectRoot?: string;
|
|
14
|
+
resolver?: {
|
|
15
|
+
platforms?: readonly string[];
|
|
16
|
+
resolveRequest?: MetroResolver | null;
|
|
17
|
+
};
|
|
18
|
+
serializer?: {
|
|
19
|
+
getModulesRunBeforeMainModule?: (entryFilePath: string) => string[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export type LinuxPlatformOptions = {
|
|
23
|
+
/** Extra host-provided modules to keep out of the bundle. */
|
|
24
|
+
externals?: readonly string[];
|
|
25
|
+
/** Proxy directory override (default: node_modules/.react-native-gtkx). */
|
|
26
|
+
proxyDir?: string;
|
|
27
|
+
};
|
|
28
|
+
export type LinuxPlatformConfig<T extends MetroLikeConfig> = T & {
|
|
29
|
+
resolver: {
|
|
30
|
+
platforms: string[];
|
|
31
|
+
resolveRequest: MetroResolver;
|
|
32
|
+
};
|
|
33
|
+
serializer: {
|
|
34
|
+
getModulesRunBeforeMainModule: (entryFilePath: string) => string[];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Wraps a Metro config (RN's getDefaultConfig output) with everything the
|
|
39
|
+
* linux platform needs. Composes with an existing custom resolveRequest —
|
|
40
|
+
* non-linux platforms fall through to it untouched.
|
|
41
|
+
*/
|
|
42
|
+
export declare const withLinuxPlatform: <T extends MetroLikeConfig>(config: T, options?: LinuxPlatformOptions) => LinuxPlatformConfig<T>;
|