diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.kt
index 77258f28c59b..cf67f6beb0c7 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.kt
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/LayoutShadowNode.kt
@@ -95,7 +95,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.WIDTH)
public open fun setWidth(width: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -113,7 +113,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.MIN_WIDTH)
public open fun setMinWidth(minWidth: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -142,7 +142,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.MAX_WIDTH)
public open fun setMaxWidth(maxWidth: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -159,7 +159,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.HEIGHT)
public open fun setHeight(height: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -177,7 +177,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.MIN_HEIGHT)
public open fun setMinHeight(minHeight: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -194,7 +194,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.MAX_HEIGHT)
public open fun setMaxHeight(maxHeight: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -212,7 +212,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@Override
@ReactProp(name = ViewProps.FLEX, defaultFloat = 0f)
public override fun setFlex(flex: Float) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
super.setFlex(flex)
@@ -221,7 +221,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@Override
@ReactProp(name = ViewProps.FLEX_GROW, defaultFloat = 0f)
public override fun setFlexGrow(flexGrow: Float) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
super.setFlexGrow(flexGrow)
@@ -229,7 +229,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.ROW_GAP)
public open fun setRowGap(rowGap: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -247,7 +247,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.COLUMN_GAP)
public open fun setColumnGap(columnGap: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -265,7 +265,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.GAP)
public open fun setGap(gap: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -284,7 +284,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@Override
@ReactProp(name = ViewProps.FLEX_SHRINK, defaultFloat = 0f)
public override fun setFlexShrink(flexShrink: Float) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
super.setFlexShrink(flexShrink)
@@ -292,7 +292,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.FLEX_BASIS)
public open fun setFlexBasis(flexBasis: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -315,7 +315,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.FLEX_DIRECTION)
public open fun setFlexDirection(flexDirection: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -338,7 +338,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.FLEX_WRAP)
public open fun setFlexWrap(flexWrap: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -360,7 +360,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.ALIGN_SELF)
public open fun setAlignSelf(alignSelf: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -387,7 +387,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.ALIGN_ITEMS)
public open fun setAlignItems(alignItems: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -414,7 +414,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.ALIGN_CONTENT)
public open fun setAlignContent(alignContent: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -442,7 +442,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.JUSTIFY_CONTENT)
public open fun setJustifyContent(justifyContent: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -467,7 +467,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.OVERFLOW)
public open fun setOverflow(overflow: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
if (overflow == null) {
@@ -488,7 +488,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.DISPLAY)
public open fun setDisplay(display: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -575,7 +575,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
]
)
public open fun setMargins(index: Int, margin: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -609,7 +609,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
]
)
public open fun setPaddings(index: Int, padding: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -641,7 +641,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
defaultFloat = Float.NaN,
)
public open fun setBorderWidths(index: Int, borderWidth: Float) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
val spacingType = maybeTransformLeftRightToStartEnd(ViewProps.BORDER_SPACING_TYPES[index])
@@ -660,7 +660,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
]
)
public open fun setPositionValues(index: Int, position: Dynamic) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
@@ -688,7 +688,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
}
private fun maybeTransformLeftRightToStartEnd(spacingType: Int): Int {
- if (!I18nUtil.getInstance().doLeftAndRightSwapInRTL(themedContext)) {
+ if (!I18nUtil.instance.doLeftAndRightSwapInRTL(getThemedContext())) {
return spacingType
}
@@ -701,7 +701,7 @@ public open class LayoutShadowNode : ReactShadowNodeImpl() {
@ReactProp(name = ViewProps.POSITION)
public open fun setPosition(position: String?) {
- if (isVirtual) {
+ if (isVirtual()) {
return
}
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java
deleted file mode 100644
index e145fbce55a8..000000000000
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-package com.facebook.react.uimanager;
-
-import androidx.annotation.Nullable;
-import com.facebook.react.common.annotations.internal.LegacyArchitecture;
-import com.facebook.yoga.YogaAlign;
-import com.facebook.yoga.YogaBaselineFunction;
-import com.facebook.yoga.YogaDirection;
-import com.facebook.yoga.YogaDisplay;
-import com.facebook.yoga.YogaFlexDirection;
-import com.facebook.yoga.YogaJustify;
-import com.facebook.yoga.YogaMeasureFunction;
-import com.facebook.yoga.YogaNode;
-import com.facebook.yoga.YogaOverflow;
-import com.facebook.yoga.YogaPositionType;
-import com.facebook.yoga.YogaValue;
-import com.facebook.yoga.YogaWrap;
-
-/**
- * Base node class for representing virtual tree of React nodes. Shadow nodes are used primarily for
- * layouting therefore it extends {@link YogaNode} to allow that. They also help with handling
- * Common base subclass of {@link YogaNode} for all layout nodes for react-based view. It extends
- * {@link YogaNode} by adding additional capabilities.
- *
- *
Instances of this class receive property updates from JS via @{link UIManagerModule}.
- * Subclasses may use {@link #updateShadowNode} to persist some of the updated fields in the node
- * instance that corresponds to a particular view type.
- *
- *
Subclasses of {@link ReactShadowNode} should be created only from {@link ViewManager} that
- * corresponds to a certain type of native view. They will be updated and accessed only from JS
- * thread. Subclasses of {@link ViewManager} may choose to use base class {@link ReactShadowNode} or
- * custom subclass of it if necessary.
- *
- *
The primary use-case for {@link ReactShadowNode} nodes is to calculate layouting. Although
- * this might be extended. For some examples please refer to ARTGroupYogaNode or ReactTextYogaNode.
- *
- *
This class allows for the native view hierarchy to not be an exact copy of the hierarchy
- * received from JS by keeping track of both JS children (e.g. {@link #getChildCount()} and
- * separately native children (e.g. {@link #getNativeChildCount()}).
- */
-@LegacyArchitecture
-@Deprecated(
- since = "This class is part of Legacy Architecture and will be removed in a future release")
-public interface ReactShadowNode {
-
- /**
- * Nodes that return {@code true} will be treated as "virtual" nodes. That is, nodes that are not
- * mapped into native views or Yoga nodes (e.g. nested text node). By default this method returns
- * {@code false}.
- */
- boolean isVirtual();
-
- /**
- * Nodes that return {@code true} will be treated as a root view for the virtual nodes tree. It
- * means that all of its descendants will be "virtual" nodes. Good example is {@code InputText}
- * view that may have children {@code Text} nodes but this whole hierarchy will be mapped to a
- * single android {@link EditText} view.
- */
- boolean isVirtualAnchor();
-
- /**
- * Nodes that return {@code true} will not manage (and and remove) child Yoga nodes. For example
- * {@link ReactTextInputShadowNode} or {@link ReactTextShadowNode} have child nodes, which do not
- * want Yoga to lay out, so in the eyes of Yoga it is a leaf node. Override this method in
- * subclass to enforce this requirement.
- */
- boolean isYogaLeafNode();
-
- /**
- * When constructing the native tree, nodes that return {@code true} will be treated as leaves.
- * Instead of adding this view's native children as subviews of it, they will be added as subviews
- * of an ancestor. In other words, this view wants to support native children but it cannot host
- * them itself (e.g. it isn't a ViewGroup).
- */
- boolean hoistNativeChildren();
-
- String getViewClass();
-
- boolean hasUpdates();
-
- void markUpdateSeen();
-
- void markUpdated();
-
- boolean hasUnseenUpdates();
-
- void dirty();
-
- boolean isDirty();
-
- void addChildAt(T child, int i);
-
- T removeChildAt(int i);
-
- int getChildCount();
-
- T getChildAt(int i);
-
- int indexOf(T child);
-
- void removeAndDisposeAllChildren();
-
- /**
- * This method will be called by {@link UIManagerModule} once per batch, before calculating
- * layout. Will be only called for nodes that are marked as updated with {@link #markUpdated()} or
- * require layouting (marked with {@link #dirty()}).
- */
- void onBeforeLayout(NativeViewHierarchyOptimizer nativeViewHierarchyOptimizer);
-
- void updateProperties(ReactStylesDiffMap props);
-
- void onAfterUpdateTransaction();
-
- /**
- * Called after layout step at the end of the UI batch from {@link UIManagerModule}. May be used
- * to enqueue additional ui operations for the native view. Will only be called on nodes marked as
- * updated either with {@link #dirty()} or {@link #markUpdated()}.
- *
- * @param uiViewOperationQueue interface for enqueueing UI operations
- */
- void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue);
-
- /* package */ boolean dispatchUpdatesWillChangeLayout(float absoluteX, float absoluteY);
-
- /* package */ void dispatchUpdates(
- float absoluteX,
- float absoluteY,
- UIViewOperationQueue uiViewOperationQueue,
- NativeViewHierarchyOptimizer nativeViewHierarchyOptimizer);
-
- int getReactTag();
-
- void setReactTag(int reactTag);
-
- int getRootTag();
-
- void setRootTag(int rootTag);
-
- void setViewClassName(String viewClassName);
-
- @Nullable
- T getParent();
-
- // Returns the node that is responsible for laying out this node.
- @Nullable
- T getLayoutParent();
-
- void setLayoutParent(@Nullable T layoutParent);
-
- /**
- * Get the {@link ThemedReactContext} associated with this {@link ReactShadowNode}. This will
- * never change during the lifetime of a {@link ReactShadowNode} instance, but different instances
- * can have different contexts; don't cache any calculations based on theme values globally.
- */
- ThemedReactContext getThemedContext();
-
- void setThemedContext(ThemedReactContext themedContext);
-
- boolean shouldNotifyOnLayout();
-
- void calculateLayout();
-
- void calculateLayout(float width, float height);
-
- boolean hasNewLayout();
-
- void markLayoutSeen();
-
- /**
- * Adds a child that the native view hierarchy will have at this index in the native view
- * corresponding to this node.
- */
- void addNativeChildAt(T child, int nativeIndex);
-
- T removeNativeChildAt(int i);
-
- void removeAllNativeChildren();
-
- int getNativeChildCount();
-
- int indexOfNativeChild(T nativeChild);
-
- @Nullable
- T getNativeParent();
-
- /**
- * Sets whether this node only contributes to the layout of its children without doing any drawing
- * or functionality itself.
- */
- void setIsLayoutOnly(boolean isLayoutOnly);
-
- boolean isLayoutOnly();
-
- int getTotalNativeChildren();
-
- boolean isDescendantOf(T ancestorNode);
-
- /**
- * @return a {@link String} representation of the Yoga hierarchy of this {@link ReactShadowNode}
- */
- String getHierarchyInfo();
-
- /*
- * In some cases we need a way to specify some environmental data to shadow node
- * to improve layout (or do something similar), so {@code localData} serves these needs.
- * For example, any stateful embedded native views may benefit from this.
- * Have in mind that this data is not supposed to interfere with the state of
- * the shadow node.
- * Please respect one-directional data flow of React.
- * Use {@link UIManagerModule#setViewLocalData} to set this property
- * (to provide local/environmental data for a shadow node) from the main thread.
- */
- void setLocalData(Object data);
-
- /**
- * Returns the offset within the native children owned by all layout-only nodes in the subtree
- * rooted at this node for the given child. Put another way, this returns the number of native
- * nodes (nodes not optimized out of the native tree) that are a) to the left (visited before by a
- * DFS) of the given child in the subtree rooted at this node and b) do not have a native parent
- * in this subtree (which means that the given child will be a sibling of theirs in the final
- * native hierarchy since they'll get attached to the same native parent).
- *
- * Basically, a view might have children that have been optimized away. Since those children
- * will then add their native children to this view, we now have ranges of native children that
- * correspond to single unoptimized children. The purpose of this method is to return the index
- * within the native children that corresponds to the **start** of the native children that belong
- * to the given child. Also, note that all of the children of a view might be optimized away, so
- * this could return the same value for multiple different children.
- *
- *
Example. Native children are represented by (N) where N is the no-opt child they came from.
- * If no children are optimized away it'd look like this: (0) (1) (2) (3) ... (n)
- *
- *
In case some children are optimized away, it might look like this: (0) (1) (1) (1) (3) (3)
- * (4)
- *
- *
In that case: getNativeOffsetForChild(Node 0) => 0 getNativeOffsetForChild(Node 1) => 1
- * getNativeOffsetForChild(Node 2) => 4 getNativeOffsetForChild(Node 3) => 4
- *
- *
getNativeOffsetForChild(Node 4) => 6
- */
- int getNativeOffsetForChild(T child);
-
- float getLayoutX();
-
- float getLayoutY();
-
- float getLayoutWidth();
-
- float getLayoutHeight();
-
- /**
- * @return the x position of the corresponding view on the screen, rounded to pixels
- */
- int getScreenX();
-
- /**
- * @return the y position of the corresponding view on the screen, rounded to pixels
- */
- int getScreenY();
-
- /**
- * @return width corrected for rounding to pixels.
- */
- int getScreenWidth();
-
- /**
- * @return height corrected for rounding to pixels.
- */
- int getScreenHeight();
-
- YogaDirection getLayoutDirection();
-
- void setLayoutDirection(YogaDirection direction);
-
- YogaValue getStyleWidth();
-
- void setStyleWidth(float widthPx);
-
- void setStyleWidthPercent(float percent);
-
- void setStyleWidthAuto();
-
- void setStyleMinWidth(float widthPx);
-
- void setStyleMinWidthPercent(float percent);
-
- void setStyleMaxWidth(float widthPx);
-
- void setStyleMaxWidthPercent(float percent);
-
- YogaValue getStyleHeight();
-
- float getFlex();
-
- void setStyleHeight(float heightPx);
-
- void setStyleHeightPercent(float percent);
-
- void setStyleHeightAuto();
-
- void setStyleMinHeight(float widthPx);
-
- void setStyleMinHeightPercent(float percent);
-
- void setStyleMaxHeight(float widthPx);
-
- void setStyleMaxHeightPercent(float percent);
-
- void setFlex(float flex);
-
- void setFlexGrow(float flexGrow);
-
- void setRowGap(float rowGap);
-
- void setRowGapPercent(float percent);
-
- void setColumnGap(float columnGap);
-
- void setColumnGapPercent(float percent);
-
- void setGap(float gap);
-
- void setGapPercent(float percent);
-
- void setFlexShrink(float flexShrink);
-
- void setFlexBasis(float flexBasis);
-
- void setFlexBasisAuto();
-
- void setFlexBasisPercent(float percent);
-
- void setStyleAspectRatio(float aspectRatio);
-
- void setFlexDirection(YogaFlexDirection flexDirection);
-
- void setFlexWrap(YogaWrap wrap);
-
- void setAlignSelf(YogaAlign alignSelf);
-
- void setAlignItems(YogaAlign alignItems);
-
- void setAlignContent(YogaAlign alignContent);
-
- void setJustifyContent(YogaJustify justifyContent);
-
- void setOverflow(YogaOverflow overflow);
-
- void setDisplay(YogaDisplay display);
-
- void setMargin(int spacingType, float margin);
-
- void setMarginPercent(int spacingType, float percent);
-
- void setMarginAuto(int spacingType);
-
- float getPadding(int spacingType);
-
- YogaValue getStylePadding(int spacingType);
-
- void setDefaultPadding(int spacingType, float padding);
-
- void setPadding(int spacingType, float padding);
-
- void setPaddingPercent(int spacingType, float percent);
-
- void setBorder(int spacingType, float borderWidth);
-
- void setPosition(int spacingType, float position);
-
- void setPositionPercent(int spacingType, float percent);
-
- void setPositionType(YogaPositionType positionType);
-
- void setShouldNotifyOnLayout(boolean shouldNotifyOnLayout);
-
- void setBaselineFunction(YogaBaselineFunction baselineFunction);
-
- void setMeasureFunction(YogaMeasureFunction measureFunction);
-
- boolean isMeasureDefined();
-
- void dispose();
-
- void setMeasureSpecs(int widthMeasureSpec, int heightMeasureSpec);
-
- Integer getWidthMeasureSpec();
-
- Integer getHeightMeasureSpec();
-
- @Nullable
- Iterable extends ReactShadowNode> calculateLayoutOnChildren();
-}
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.kt
new file mode 100644
index 000000000000..a374e1c63610
--- /dev/null
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNode.kt
@@ -0,0 +1,484 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.facebook.react.uimanager
+
+import com.facebook.react.common.annotations.internal.LegacyArchitecture
+import com.facebook.yoga.YogaAlign
+import com.facebook.yoga.YogaBaselineFunction
+import com.facebook.yoga.YogaDirection
+import com.facebook.yoga.YogaDisplay
+import com.facebook.yoga.YogaFlexDirection
+import com.facebook.yoga.YogaJustify
+import com.facebook.yoga.YogaMeasureFunction
+import com.facebook.yoga.YogaNode
+import com.facebook.yoga.YogaOverflow
+import com.facebook.yoga.YogaPositionType
+import com.facebook.yoga.YogaValue
+import com.facebook.yoga.YogaWrap
+
+/**
+ * Base node class for representing virtual tree of React nodes. Shadow nodes are used primarily for
+ * layouting therefore it extends [YogaNode] to allow that. They also help with handling Common base
+ * subclass of [YogaNode] for all layout nodes for react-based view. It extends [YogaNode] by adding
+ * additional capabilities.
+ *
+ * Instances of this class receive property updates from JS via @{link UIManagerModule}. Subclasses
+ * may use [updateShadowNode] to persist some of the updated fields in the node instance that
+ * corresponds to a particular view type.
+ *
+ * Subclasses of [ReactShadowNode] should be created only from [ViewManager] that corresponds to a
+ * certain type of native view. They will be updated and accessed only from JS thread. Subclasses of
+ * [ViewManager] may choose to use base class [ReactShadowNode] or custom subclass of it if
+ * necessary.
+ *
+ * The primary use-case for [ReactShadowNode] nodes is to calculate layouting. Although this might
+ * be extended. For some examples please refer to ARTGroupYogaNode or ReactTextYogaNode.
+ *
+ * This class allows for the native view hierarchy to not be an exact copy of the hierarchy received
+ * from JS by keeping track of both JS children (e.g. [getChildCount]) and separately native
+ * children (e.g. [getNativeChildCount]).
+ */
+@LegacyArchitecture
+@Deprecated("This class is part of Legacy Architecture and will be removed in a future release")
+public interface ReactShadowNode> {
+
+ /**
+ * Nodes that return `true` will be treated as "virtual" nodes. That is, nodes that are not mapped
+ * into native views or Yoga nodes (e.g. nested text node). By default this method returns
+ * `false`.
+ */
+ public fun isVirtual(): Boolean
+
+ /**
+ * Nodes that return `true` will be treated as a root view for the virtual nodes tree. It means
+ * that all of its descendants will be "virtual" nodes. Good example is `InputText` view that may
+ * have children `Text` nodes but this whole hierarchy will be mapped to a single android
+ * [EditText] view.
+ */
+ public fun isVirtualAnchor(): Boolean
+
+ /**
+ * Nodes that return `true` will not manage (and and remove) child Yoga nodes. For example
+ * [ReactTextInputShadowNode] or [ReactTextShadowNode] have child nodes, which do not want Yoga to
+ * lay out, so in the eyes of Yoga it is a leaf node. Override this method in subclass to enforce
+ * this requirement.
+ */
+ public fun isYogaLeafNode(): Boolean
+
+ /**
+ * When constructing the native tree, nodes that return `true` will be treated as leaves. Instead
+ * of adding this view's native children as subviews of it, they will be added as subviews of an
+ * ancestor. In other words, this view wants to support native children but it cannot host them
+ * itself (e.g. it isn't a ViewGroup).
+ */
+ public fun hoistNativeChildren(): Boolean
+
+ /** Returns the view class name for this shadow node. */
+ public fun getViewClass(): String
+
+ /** Returns whether this node has pending updates. */
+ public fun hasUpdates(): Boolean
+
+ /** Marks all updates on this node as seen. */
+ public fun markUpdateSeen()
+
+ /** Marks this node as having been updated. */
+ public fun markUpdated()
+
+ /** Returns whether this node has updates that have not yet been seen. */
+ public fun hasUnseenUpdates(): Boolean
+
+ /** Marks this node as dirty, requiring layout recalculation. */
+ public fun dirty()
+
+ /** Returns whether this node is currently marked as dirty. */
+ public fun isDirty(): Boolean
+
+ /** Adds a child node at the specified index. */
+ public fun addChildAt(child: T, i: Int)
+
+ /** Removes and returns the child node at the specified index. */
+ public fun removeChildAt(i: Int): T
+
+ /** Returns the number of children this node has. */
+ public fun getChildCount(): Int
+
+ /** Returns the child node at the specified index. */
+ public fun getChildAt(i: Int): T
+
+ /** Returns the index of the specified child node, or -1 if not found. */
+ public fun indexOf(child: T): Int
+
+ /** Removes and disposes all children of this node. */
+ public fun removeAndDisposeAllChildren()
+
+ /**
+ * This method will be called by [UIManagerModule] once per batch, before calculating layout. Will
+ * be only called for nodes that are marked as updated with [markUpdated] or require layouting
+ * (marked with [dirty]).
+ */
+ public fun onBeforeLayout(nativeViewHierarchyOptimizer: NativeViewHierarchyOptimizer)
+
+ /** Updates the properties of this shadow node from the given props diff map. */
+ public fun updateProperties(props: ReactStylesDiffMap)
+
+ /** Called after a property update transaction has completed. */
+ public fun onAfterUpdateTransaction()
+
+ /**
+ * Called after layout step at the end of the UI batch from [UIManagerModule]. May be used to
+ * enqueue additional ui operations for the native view. Will only be called on nodes marked as
+ * updated either with [dirty] or [markUpdated].
+ *
+ * @param uiViewOperationQueue interface for enqueueing UI operations
+ */
+ public fun onCollectExtraUpdates(uiViewOperationQueue: UIViewOperationQueue)
+
+ /** Returns whether dispatching updates will change the layout at the given absolute position. */
+ public fun dispatchUpdatesWillChangeLayout(absoluteX: Float, absoluteY: Float): Boolean
+
+ /** Dispatches updates for this node at the given absolute position. */
+ public fun dispatchUpdates(
+ absoluteX: Float,
+ absoluteY: Float,
+ uiViewOperationQueue: UIViewOperationQueue,
+ nativeViewHierarchyOptimizer: NativeViewHierarchyOptimizer,
+ )
+
+ /** Returns the React tag identifier for this node. */
+ public fun getReactTag(): Int
+
+ /** Sets the React tag identifier for this node. */
+ public fun setReactTag(reactTag: Int)
+
+ /** Returns the root tag identifier for this node. */
+ public fun getRootTag(): Int
+
+ /** Sets the root tag identifier for this node. */
+ public fun setRootTag(rootTag: Int)
+
+ /** Sets the view class name for this shadow node. */
+ public fun setViewClassName(viewClassName: String)
+
+ /** Returns the parent node, or null if this is a root node. */
+ public fun getParent(): T?
+
+ /** Returns the node that is responsible for laying out this node. */
+ public fun getLayoutParent(): T?
+
+ /** Sets the node that is responsible for laying out this node. */
+ public fun setLayoutParent(layoutParent: T?)
+
+ /**
+ * Get the [ThemedReactContext] associated with this [ReactShadowNode]. This will never change
+ * during the lifetime of a [ReactShadowNode] instance, but different instances can have different
+ * contexts; don't cache any calculations based on theme values globally.
+ */
+ public fun getThemedContext(): ThemedReactContext
+
+ /** Sets the [ThemedReactContext] associated with this [ReactShadowNode]. */
+ public fun setThemedContext(themedContext: ThemedReactContext)
+
+ /** Returns whether this node should notify on layout changes. */
+ public fun shouldNotifyOnLayout(): Boolean
+
+ /** Calculates the layout for this node. */
+ public fun calculateLayout()
+
+ /** Calculates the layout for this node with the given width and height constraints. */
+ public fun calculateLayout(width: Float, height: Float)
+
+ /** Returns whether this node has a new layout that has not yet been seen. */
+ public fun hasNewLayout(): Boolean
+
+ /** Marks the current layout as having been seen. */
+ public fun markLayoutSeen()
+
+ /**
+ * Adds a child that the native view hierarchy will have at this index in the native view
+ * corresponding to this node.
+ */
+ public fun addNativeChildAt(child: T, nativeIndex: Int)
+
+ /** Removes and returns the native child at the specified index. */
+ public fun removeNativeChildAt(i: Int): T
+
+ /** Removes all native children from this node. */
+ public fun removeAllNativeChildren()
+
+ /** Returns the number of native children this node has. */
+ public fun getNativeChildCount(): Int
+
+ /** Returns the index of the specified native child node. */
+ public fun indexOfNativeChild(nativeChild: T): Int
+
+ /** Returns the native parent node, or null if there is none. */
+ public fun getNativeParent(): T?
+
+ /**
+ * Sets whether this node only contributes to the layout of its children without doing any drawing
+ * or functionality itself.
+ */
+ public fun setIsLayoutOnly(isLayoutOnly: Boolean)
+
+ /** Returns whether this node is layout-only. */
+ public fun isLayoutOnly(): Boolean
+
+ /** Returns the total number of native children in the subtree rooted at this node. */
+ public fun getTotalNativeChildren(): Int
+
+ /** Returns whether this node is a descendant of the given ancestor node. */
+ public fun isDescendantOf(ancestorNode: T): Boolean
+
+ /** Returns a [String] representation of the Yoga hierarchy of this [ReactShadowNode]. */
+ public fun getHierarchyInfo(): String
+
+ /**
+ * In some cases we need a way to specify some environmental data to shadow node to improve layout
+ * (or do something similar), so `localData` serves these needs. For example, any stateful
+ * embedded native views may benefit from this. Have in mind that this data is not supposed to
+ * interfere with the state of the shadow node. Please respect one-directional data flow of React.
+ * Use [UIManagerModule.setViewLocalData] to set this property (to provide local/environmental
+ * data for a shadow node) from the main thread.
+ */
+ public fun setLocalData(data: Any?)
+
+ /**
+ * Returns the offset within the native children owned by all layout-only nodes in the subtree
+ * rooted at this node for the given child. Put another way, this returns the number of native
+ * nodes (nodes not optimized out of the native tree) that are a) to the left (visited before by a
+ * DFS) of the given child in the subtree rooted at this node and b) do not have a native parent
+ * in this subtree (which means that the given child will be a sibling of theirs in the final
+ * native hierarchy since they'll get attached to the same native parent).
+ *
+ * Basically, a view might have children that have been optimized away. Since those children will
+ * then add their native children to this view, we now have ranges of native children that
+ * correspond to single unoptimized children. The purpose of this method is to return the index
+ * within the native children that corresponds to the **start** of the native children that belong
+ * to the given child. Also, note that all of the children of a view might be optimized away, so
+ * this could return the same value for multiple different children.
+ *
+ * Example. Native children are represented by (N) where N is the no-opt child they came from. If
+ * no children are optimized away it'd look like this: (0) (1) (2) (3) ... (n)
+ *
+ * In case some children are optimized away, it might look like this: (0) (1) (1) (1) (3) (3) (4)
+ *
+ * In that case: getNativeOffsetForChild(Node 0) => 0 getNativeOffsetForChild(Node 1) => 1
+ * getNativeOffsetForChild(Node 2) => 4 getNativeOffsetForChild(Node 3) => 4
+ *
+ * getNativeOffsetForChild(Node 4) => 6
+ */
+ public fun getNativeOffsetForChild(child: T): Int
+
+ /** Returns the layout X position of this node. */
+ public fun getLayoutX(): Float
+
+ /** Returns the layout Y position of this node. */
+ public fun getLayoutY(): Float
+
+ /** Returns the layout width of this node. */
+ public fun getLayoutWidth(): Float
+
+ /** Returns the layout height of this node. */
+ public fun getLayoutHeight(): Float
+
+ /** Returns the x position of the corresponding view on the screen, rounded to pixels. */
+ public fun getScreenX(): Int
+
+ /** Returns the y position of the corresponding view on the screen, rounded to pixels. */
+ public fun getScreenY(): Int
+
+ /** Returns the width corrected for rounding to pixels. */
+ public fun getScreenWidth(): Int
+
+ /** Returns the height corrected for rounding to pixels. */
+ public fun getScreenHeight(): Int
+
+ /** Returns the layout direction for this node. */
+ public fun getLayoutDirection(): YogaDirection
+
+ /** Sets the layout direction for this node. */
+ public fun setLayoutDirection(direction: YogaDirection)
+
+ /** Returns the style width value for this node. */
+ public fun getStyleWidth(): YogaValue
+
+ /** Sets the style width in pixels. */
+ public fun setStyleWidth(widthPx: Float)
+
+ /** Sets the style width as a percentage. */
+ public fun setStyleWidthPercent(percent: Float)
+
+ /** Sets the style width to auto. */
+ public fun setStyleWidthAuto()
+
+ /** Sets the minimum style width in pixels. */
+ public fun setStyleMinWidth(widthPx: Float)
+
+ /** Sets the minimum style width as a percentage. */
+ public fun setStyleMinWidthPercent(percent: Float)
+
+ /** Sets the maximum style width in pixels. */
+ public fun setStyleMaxWidth(widthPx: Float)
+
+ /** Sets the maximum style width as a percentage. */
+ public fun setStyleMaxWidthPercent(percent: Float)
+
+ /** Returns the style height value for this node. */
+ public fun getStyleHeight(): YogaValue
+
+ /** Returns the flex value for this node. */
+ public fun getFlex(): Float
+
+ /** Sets the style height in pixels. */
+ public fun setStyleHeight(heightPx: Float)
+
+ /** Sets the style height as a percentage. */
+ public fun setStyleHeightPercent(percent: Float)
+
+ /** Sets the style height to auto. */
+ public fun setStyleHeightAuto()
+
+ /** Sets the minimum style height in pixels. */
+ public fun setStyleMinHeight(widthPx: Float)
+
+ /** Sets the minimum style height as a percentage. */
+ public fun setStyleMinHeightPercent(percent: Float)
+
+ /** Sets the maximum style height in pixels. */
+ public fun setStyleMaxHeight(widthPx: Float)
+
+ /** Sets the maximum style height as a percentage. */
+ public fun setStyleMaxHeightPercent(percent: Float)
+
+ /** Sets the flex value for this node. */
+ public fun setFlex(flex: Float)
+
+ /** Sets the flex grow value for this node. */
+ public fun setFlexGrow(flexGrow: Float)
+
+ /** Sets the row gap in pixels. */
+ public fun setRowGap(rowGap: Float)
+
+ /** Sets the row gap as a percentage. */
+ public fun setRowGapPercent(percent: Float)
+
+ /** Sets the column gap in pixels. */
+ public fun setColumnGap(columnGap: Float)
+
+ /** Sets the column gap as a percentage. */
+ public fun setColumnGapPercent(percent: Float)
+
+ /** Sets the gap in pixels (applies to both row and column). */
+ public fun setGap(gap: Float)
+
+ /** Sets the gap as a percentage (applies to both row and column). */
+ public fun setGapPercent(percent: Float)
+
+ /** Sets the flex shrink value for this node. */
+ public fun setFlexShrink(flexShrink: Float)
+
+ /** Sets the flex basis value in pixels. */
+ public fun setFlexBasis(flexBasis: Float)
+
+ /** Sets the flex basis to auto. */
+ public fun setFlexBasisAuto()
+
+ /** Sets the flex basis as a percentage. */
+ public fun setFlexBasisPercent(percent: Float)
+
+ /** Sets the style aspect ratio for this node. */
+ public fun setStyleAspectRatio(aspectRatio: Float)
+
+ /** Sets the flex direction for this node. */
+ public fun setFlexDirection(flexDirection: YogaFlexDirection)
+
+ /** Sets the flex wrap mode for this node. */
+ public fun setFlexWrap(wrap: YogaWrap)
+
+ /** Sets the align-self value for this node. */
+ public fun setAlignSelf(alignSelf: YogaAlign)
+
+ /** Sets the align-items value for this node. */
+ public fun setAlignItems(alignItems: YogaAlign)
+
+ /** Sets the align-content value for this node. */
+ public fun setAlignContent(alignContent: YogaAlign)
+
+ /** Sets the justify-content value for this node. */
+ public fun setJustifyContent(justifyContent: YogaJustify)
+
+ /** Sets the overflow mode for this node. */
+ public fun setOverflow(overflow: YogaOverflow)
+
+ /** Sets the display mode for this node. */
+ public fun setDisplay(display: YogaDisplay)
+
+ /** Sets the margin for the given spacing type in pixels. */
+ public fun setMargin(spacingType: Int, margin: Float)
+
+ /** Sets the margin for the given spacing type as a percentage. */
+ public fun setMarginPercent(spacingType: Int, percent: Float)
+
+ /** Sets the margin for the given spacing type to auto. */
+ public fun setMarginAuto(spacingType: Int)
+
+ /** Returns the padding for the given spacing type. */
+ public fun getPadding(spacingType: Int): Float
+
+ /** Returns the style padding value for the given spacing type. */
+ public fun getStylePadding(spacingType: Int): YogaValue
+
+ /** Sets the default padding for the given spacing type in pixels. */
+ public fun setDefaultPadding(spacingType: Int, padding: Float)
+
+ /** Sets the padding for the given spacing type in pixels. */
+ public fun setPadding(spacingType: Int, padding: Float)
+
+ /** Sets the padding for the given spacing type as a percentage. */
+ public fun setPaddingPercent(spacingType: Int, percent: Float)
+
+ /** Sets the border width for the given spacing type. */
+ public fun setBorder(spacingType: Int, borderWidth: Float)
+
+ /** Sets the position for the given spacing type in pixels. */
+ public fun setPosition(spacingType: Int, position: Float)
+
+ /** Sets the position for the given spacing type as a percentage. */
+ public fun setPositionPercent(spacingType: Int, percent: Float)
+
+ /** Sets the position type for this node. */
+ public fun setPositionType(positionType: YogaPositionType)
+
+ /** Sets whether this node should notify on layout changes. */
+ public fun setShouldNotifyOnLayout(shouldNotifyOnLayout: Boolean)
+
+ /** Sets the baseline function for this node. */
+ public fun setBaselineFunction(baselineFunction: YogaBaselineFunction)
+
+ /** Sets the measure function for this node. */
+ public fun setMeasureFunction(measureFunction: YogaMeasureFunction)
+
+ /** Returns whether a measure function is defined for this node. */
+ public fun isMeasureDefined(): Boolean
+
+ /** Disposes this node and releases associated resources. */
+ public fun dispose()
+
+ /** Sets the measure specs for width and height. */
+ public fun setMeasureSpecs(widthMeasureSpec: Int, heightMeasureSpec: Int)
+
+ /** Returns the width measure spec, or null if not set. */
+ public fun getWidthMeasureSpec(): Int?
+
+ /** Returns the height measure spec, or null if not set. */
+ public fun getHeightMeasureSpec(): Int?
+
+ /** Calculates layout on children and returns the iterable of children, or null. */
+ public fun calculateLayoutOnChildren(): Iterable<@JvmWildcard ReactShadowNode<*>>?
+}
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java
index 766c5e9995b3..540a018fedb0 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactShadowNodeImpl.java
@@ -1077,7 +1077,8 @@ public Integer getHeightMeasureSpec() {
}
@Override
- public @Nullable Iterable extends ReactShadowNode> calculateLayoutOnChildren() {
+ @SuppressWarnings("rawtypes")
+ public @Nullable Iterable calculateLayoutOnChildren() {
return isVirtualAnchor()
?
// All of the descendants are virtual so none of them are involved in layout.
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ShadowNodeRegistry.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ShadowNodeRegistry.kt
index 57cdf5085b59..894935f7af42 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ShadowNodeRegistry.kt
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ShadowNodeRegistry.kt
@@ -33,7 +33,7 @@ internal class ShadowNodeRegistry {
fun addRootNode(node: ReactShadowNode<*>) {
threadAsserter.assertNow()
- val tag = node.reactTag
+ val tag = node.getReactTag()
tagsToCSSNodes.put(tag, node)
rootTags.put(tag, true)
}
@@ -55,7 +55,7 @@ internal class ShadowNodeRegistry {
fun addNode(node: ReactShadowNode<*>) {
threadAsserter.assertNow()
- tagsToCSSNodes.put(node.reactTag, node)
+ tagsToCSSNodes.put(node.getReactTag(), node)
}
fun removeNode(tag: Int) {
diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt
index ad0798d673ca..3ebfa0e75363 100644
--- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt
+++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManagersPropertyCache.kt
@@ -77,7 +77,7 @@ internal object ViewManagersPropertyCache {
fun updateShadowNodeProp(nodeToUpdate: ReactShadowNode<*>, value: Any?) {
try {
- val resolved = getValueOrDefault(value, nodeToUpdate.themedContext)
+ val resolved = getValueOrDefault(value, nodeToUpdate.getThemedContext())
if (index == null) {
setter.invoke(nodeToUpdate, resolved)
} else {
@@ -86,7 +86,7 @@ internal object ViewManagersPropertyCache {
} catch (t: Throwable) {
FLog.e(ViewManager::class.java, "Error while updating prop $propName", t)
throw JSApplicationIllegalArgumentException(
- "Error while updating property '$propName' in shadow node of type: ${nodeToUpdate.viewClass}",
+ "Error while updating property '$propName' in shadow node of type: ${nodeToUpdate.getViewClass()}",
t,
)
}