Skip to content

Commit 5aa79b9

Browse files
committed
feat: calc support
1 parent 7ee5275 commit 5aa79b9

File tree

30 files changed

+1835
-211
lines changed

30 files changed

+1835
-211
lines changed

packages/react-native/React/Fabric/Surface/RCTFabricSurface.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ - (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize viewp
214214
if (!isnan(viewportOffset.x) && !isnan(viewportOffset.y)) {
215215
layoutContext.viewportOffset = RCTPointFromCGPoint(viewportOffset);
216216
}
217-
217+
layoutContext.viewportSize = layoutConstraints.maximumSize;
218+
218219
_surfaceHandler->constraintLayout(layoutConstraints, layoutContext);
219220
}
220221

@@ -236,6 +237,8 @@ - (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximu
236237
layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize);
237238
layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize);
238239

240+
layoutContext.viewportSize = layoutConstraints.maximumSize;
241+
239242
return RCTCGSizeFromSize(_surfaceHandler->measure(layoutConstraints, layoutContext));
240243
}
241244

packages/react-native/React/Views/RCTLayout.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue)
8787
case YGUnitFitContent:
8888
case YGUnitStretch:
8989
return baseFloatValue;
90+
case YGUnitDynamic:
91+
return RCTCoreGraphicsFloatFromYogaFloat(YGUndefined);
9092
}
9193
}
9294

packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaUnit.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public enum YogaUnit {
1616
AUTO(3),
1717
MAX_CONTENT(4),
1818
FIT_CONTENT(5),
19-
STRETCH(6);
19+
STRETCH(6),
20+
DYNAMIC(7);
2021

2122
private final int mIntValue;
2223

@@ -37,6 +38,7 @@ public static YogaUnit fromInt(int value) {
3738
case 4: return MAX_CONTENT;
3839
case 5: return FIT_CONTENT;
3940
case 6: return STRETCH;
41+
case 7: return DYNAMIC;
4042
default: throw new IllegalArgumentException("Unknown enum value: " + value);
4143
}
4244
}

packages/react-native/ReactAndroid/src/main/jni/react/fabric/SurfaceHandlerBinding.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void SurfaceHandlerBinding::setLayoutConstraints(
6060
context.swapLeftAndRightInRTL = (doLeftAndRightSwapInRTL != 0u);
6161
context.pointScaleFactor = pixelDensity;
6262
context.viewportOffset = {.x = offsetX, .y = offsetY};
63+
context.viewportSize = {.width = maxWidth, .height = maxHeight};
6364
context.fontSizeMultiplier = fontScale;
6465

6566
surfaceHandler_.constraintLayout(constraints, context);

packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode(
143143
}
144144

145145
if (fragment.props) {
146-
updateYogaProps();
146+
auto& sourceProps =
147+
static_cast<const YogaStylableProps&>(*sourceShadowNode.getProps());
148+
updateYogaProps(sourceProps.calcExpressions);
147149
}
148150

149151
if (fragment.children) {
@@ -375,15 +377,18 @@ void YogaLayoutableShadowNode::updateYogaChildren() {
375377
yogaNode_.setDirty(!isClean);
376378
}
377379

378-
void YogaLayoutableShadowNode::updateYogaProps() {
380+
void YogaLayoutableShadowNode::updateYogaProps(
381+
const CalcExpressions& previousCalcExpressions) {
379382
ensureUnsealed();
380383

381384
auto& props = static_cast<const YogaStylableProps&>(*props_);
382385
auto styleResult = applyAliasedProps(props.yogaStyle, props);
383386

384387
// Resetting `dirty` flag only if `yogaStyle` portion of `Props` was
385-
// changed.
386-
if (!YGNodeIsDirty(&yogaNode_) && (styleResult != yogaNode_.style())) {
388+
// changed or calc expressions changed.
389+
if (!YGNodeIsDirty(&yogaNode_) &&
390+
(props.calcExpressions != previousCalcExpressions ||
391+
styleResult != yogaNode_.style())) {
387392
yogaNode_.setDirty(true);
388393
}
389394

@@ -888,6 +893,30 @@ YogaLayoutableShadowNode& YogaLayoutableShadowNode::shadowNodeFromContext(
888893
*static_cast<ShadowNode*>(YGNodeGetContext(yogaNode)));
889894
}
890895

896+
YGValue YogaLayoutableShadowNode::yogaNodeCalcValueResolver(
897+
YGNodeConstRef yogaNode,
898+
YGValueDynamicID id,
899+
YGValueDynamicContext context) {
900+
if (!yogaNode) {
901+
return {};
902+
}
903+
904+
auto& node = shadowNodeFromContext(yogaNode);
905+
auto& props = static_cast<const YogaStylableProps&>(*node.props_);
906+
auto key = static_cast<CalcExpressionPropertyID>(id);
907+
if (!props.calcExpressions.contains(key)) {
908+
return {};
909+
}
910+
911+
auto& calc = props.calcExpressions.at(key);
912+
return YGValue(
913+
calc.resolve(
914+
context.referenceLength,
915+
threadLocalLayoutContext.viewportSize.width,
916+
threadLocalLayoutContext.viewportSize.height),
917+
YGUnitPoint);
918+
};
919+
891920
yoga::Config& YogaLayoutableShadowNode::initializeYogaConfig(
892921
yoga::Config& config,
893922
YGConfigConstRef previousConfig) {

packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
5353

5454
void updateYogaChildren();
5555

56-
void updateYogaProps();
56+
void updateYogaProps(const CalcExpressions& previousCalcExpressions = {});
5757

5858
/*
5959
* Sets layoutable size of node.
@@ -82,6 +82,11 @@ class YogaLayoutableShadowNode : public LayoutableShadowNode {
8282

8383
Rect getContentBounds() const;
8484

85+
static YGValue yogaNodeCalcValueResolver(
86+
YGNodeConstRef yogaNode,
87+
YGValueDynamicID id,
88+
YGValueDynamicContext context);
89+
8590
protected:
8691
/**
8792
* Subclasses which provide MeasurableYogaNode may override to signal that a

0 commit comments

Comments
 (0)