diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/UIManagerType.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/UIManagerType.kt index 912d8c68f7fd69..bc20c931c1bd05 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/UIManagerType.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/UIManagerType.kt @@ -9,16 +9,38 @@ package com.facebook.react.uimanager.common import androidx.annotation.IntDef +/** + * Annotation class that defines the type of UIManager being used in React Native. + * + * This annotation is used to distinguish between the legacy UIManager implementation and the newer + * Fabric renderer. It helps ensure type safety when working with UIManager-related code by + * restricting values to the defined constants. + * + * @see UIManagerType.LEGACY for legacy (Paper) UIManager + * @see UIManagerType.FABRIC for Fabric renderer + */ @Retention(AnnotationRetention.SOURCE) @Suppress("DEPRECATION") @IntDef(UIManagerType.DEFAULT, UIManagerType.LEGACY, UIManagerType.FABRIC) public annotation class UIManagerType { public companion object { + /** + * Default UIManager type. Equivalent to [LEGACY]. + * + * @deprecated Use [LEGACY] instead. + */ @Deprecated( "UIManagerType.DEFAULT will be deleted in the next release of React Native. Use [LEGACY] instead." ) public const val DEFAULT: Int = 1 + + /** Represents the legacy (Paper) UIManager implementation. */ public const val LEGACY: Int = 1 + + /** + * Represents the Fabric renderer, React Native's new rendering system that provides improved + * performance and better integration with the host platform. + */ public const val FABRIC: Int = 2 } } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/ViewUtil.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/ViewUtil.kt index 22bcb86a2ad250..22d34f6c63fb4b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/ViewUtil.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/ViewUtil.kt @@ -9,8 +9,23 @@ package com.facebook.react.uimanager.common import android.view.View +/** + * Utility object providing helper methods for working with React Native views. + * + * This object contains utilities for determining which UIManager (Legacy/Paper or Fabric) a view + * belongs to, based on view tags and surface IDs. These utilities are essential for routing events + * and operations to the correct UIManager implementation. + * + * @see UIManagerType + */ public object ViewUtil { + /** + * Constant representing the absence of a surface ID. + * + * This value (-1) is used as a placeholder when no surface ID is available, typically indicating + * that the view or event originated from the legacy (Paper) UIManager rather than Fabric. + */ public const val NO_SURFACE_ID: Int = -1 /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundImageLayer.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundImageLayer.kt index 1b1cd5d74017b4..8e5cc7d8c2a44b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundImageLayer.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundImageLayer.kt @@ -12,6 +12,16 @@ import android.graphics.Shader import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.ReadableType +/** + * Represents a single layer of a background image, typically containing a gradient. + * + * This class encapsulates gradient definitions (linear or radial) that can be applied as background + * layers to React Native views. It provides parsing from React Native bridge data and shader + * generation for rendering. + * + * @see LinearGradient + * @see RadialGradient + */ public class BackgroundImageLayer() { private lateinit var gradient: Gradient @@ -20,6 +30,16 @@ public class BackgroundImageLayer() { } public companion object { + /** + * Parses a ReadableMap into a BackgroundImageLayer. + * + * The map should contain gradient configuration including a "type" key specifying either + * "linear-gradient" or "radial-gradient". + * + * @param gradientMap The map containing gradient configuration + * @param context Android context for resource resolution + * @return A BackgroundImageLayer instance, or null if parsing fails + */ public fun parse(gradientMap: ReadableMap?, context: Context): BackgroundImageLayer? { if (gradientMap == null) { return null @@ -41,5 +61,12 @@ public class BackgroundImageLayer() { } } + /** + * Creates a shader for rendering this background layer. + * + * @param width The width of the area to fill + * @param height The height of the area to fill + * @return A Shader instance for rendering the gradient + */ public fun getShader(width: Float, height: Float): Shader = gradient.getShader(width, height) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundPosition.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundPosition.kt index 3febece11f8dec..a414fad9fe1cdd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundPosition.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundPosition.kt @@ -11,6 +11,17 @@ import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.ReadableType import com.facebook.react.uimanager.LengthPercentage +/** + * Represents the position of a background image within its container. + * + * This class models CSS-like background-position values, allowing specification of offsets from any + * edge (top, left, right, bottom). Each offset can be a length or percentage value. + * + * @property top Offset from the top edge, or null if not specified + * @property left Offset from the left edge, or null if not specified + * @property right Offset from the right edge, or null if not specified + * @property bottom Offset from the bottom edge, or null if not specified + */ internal class BackgroundPosition( public val top: LengthPercentage?, public val left: LengthPercentage?, @@ -18,6 +29,15 @@ internal class BackgroundPosition( public val bottom: LengthPercentage?, ) { public companion object { + /** + * Parses a ReadableMap into a BackgroundPosition. + * + * The map may contain "top", "left", "right", and/or "bottom" keys with length or percentage + * values. + * + * @param backgroundPositionMap The map containing position values + * @return A BackgroundPosition instance, or null if the map is null + */ public fun parse(backgroundPositionMap: ReadableMap?): BackgroundPosition? { if (backgroundPositionMap == null) return null diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundRepeat.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundRepeat.kt index 3ca757ed9ec145..511ed929fbb634 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundRepeat.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundRepeat.kt @@ -10,18 +10,45 @@ package com.facebook.react.uimanager.style import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.ReadableType +/** + * Enum representing the possible repeat behavior keywords for background images. + * + * These values correspond to CSS background-repeat keywords. + */ internal enum class BackgroundRepeatKeyword { + /** The image is repeated as much as needed to cover the background area. */ Repeat, + /** The image is repeated as much as possible without clipping, with space distributed evenly. */ Space, + /** The image is repeated as much as possible without clipping, scaling to fit evenly. */ Round, + /** The image is not repeated and only shown once. */ NoRepeat, } +/** + * Represents the background repeat behavior for both horizontal and vertical axes. + * + * This class models the CSS background-repeat property, specifying how background images should be + * repeated in each direction. + * + * @property x The repeat behavior for the horizontal axis + * @property y The repeat behavior for the vertical axis + */ internal class BackgroundRepeat( public val x: BackgroundRepeatKeyword, public val y: BackgroundRepeatKeyword, ) { public companion object { + /** + * Parses a ReadableMap into a BackgroundRepeat. + * + * The map should contain "x" and/or "y" keys with string values matching the + * BackgroundRepeatKeyword values. Missing values default to Repeat. + * + * @param backgroundRepeatMap The map containing repeat values + * @return A BackgroundRepeat instance, or null if the map is null + */ public fun parse(backgroundRepeatMap: ReadableMap?): BackgroundRepeat? { if (backgroundRepeatMap == null) return null diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundSize.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundSize.kt index f476c24baf57b6..aaeaa4d4e855de 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundSize.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BackgroundSize.kt @@ -12,15 +12,44 @@ import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.ReadableType import com.facebook.react.uimanager.LengthPercentage +/** + * Represents a background size value with horizontal (x) and vertical (y) length/percentage + * components. + * + * This class handles CSS-like background-size values where each dimension can be a length, + * percentage, or "auto". A null value for x or y indicates "auto" sizing for that dimension. + * + * @property x The horizontal size component, or null for "auto" + * @property y The vertical size component, or null for "auto" + */ internal class BackgroundSizeLengthPercentage( public val x: LengthPercentage?, public val y: LengthPercentage?, ) { + /** + * Checks if the horizontal dimension is set to auto. + * + * @return true if x is null (auto), false otherwise + */ public fun isXAuto(): Boolean = x == null + /** + * Checks if the vertical dimension is set to auto. + * + * @return true if y is null (auto), false otherwise + */ public fun isYAuto(): Boolean = y == null public companion object { + /** + * Parses a ReadableMap into a BackgroundSizeLengthPercentage. + * + * The map should contain "x" and/or "y" keys with values that are either numbers (treated as + * points), percentage strings (e.g., "50%"), or "auto". + * + * @param backgroundSizeMap The map containing x and y size values + * @return A BackgroundSizeLengthPercentage instance, or null if the map is null + */ public fun parse(backgroundSizeMap: ReadableMap?): BackgroundSizeLengthPercentage? { if (backgroundSizeMap == null) return null @@ -78,11 +107,32 @@ internal class BackgroundSizeLengthPercentage( } } +/** + * Sealed class representing CSS background-size property values. + * + * This class models the different ways a background size can be specified in CSS, currently + * supporting length/percentage/auto values for both dimensions. + * + * @see BackgroundSizeLengthPercentage + */ internal sealed class BackgroundSize { + /** + * Represents a background size specified using length, percentage, or auto values. + * + * @property lengthPercentage The parsed size values for x and y dimensions + */ public class LengthPercentageAuto(public val lengthPercentage: BackgroundSizeLengthPercentage) : BackgroundSize() public companion object { + /** + * Parses a Dynamic value into a BackgroundSize. + * + * Currently supports map values containing x/y dimensions. + * + * @param backgroundSizeValue The dynamic value to parse + * @return A BackgroundSize instance, or null if parsing fails + */ public fun parse(backgroundSizeValue: Dynamic?): BackgroundSize? { if (backgroundSizeValue == null) return null diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt index c39cb74bbb9a1f..d42df53d388435 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderColors.kt @@ -13,6 +13,17 @@ import android.util.LayoutDirection import androidx.annotation.ColorInt import com.facebook.react.modules.i18nmanager.I18nUtil +/** + * Represents resolved border colors for all four physical edges of a box. + * + * This data class contains the final computed color values after resolving logical properties based + * on layout direction. + * + * @property left Color for the left edge + * @property top Color for the top edge + * @property right Color for the right edge + * @property bottom Color for the bottom edge + */ internal data class ColorEdges( @param:ColorInt val left: Int = Color.BLACK, @param:ColorInt val top: Int = Color.BLACK, @@ -20,11 +31,33 @@ internal data class ColorEdges( @param:ColorInt val bottom: Int = Color.BLACK, ) +/** + * Represents border colors using logical edge properties. + * + * This inline value class stores colors for all logical edges (start, end, block-start, block-end, + * etc.) and resolves them to physical edges based on layout direction and RTL settings. + * + * @property edgeColors Array of colors indexed by [LogicalEdge] ordinal values + * @see LogicalEdge + * @see ColorEdges + */ @JvmInline internal value class BorderColors( @param:ColorInt val edgeColors: Array = arrayOfNulls(LogicalEdge.values().size) ) { + /** + * Resolves logical edge colors to physical edge colors based on layout direction. + * + * This method handles RTL layout direction and the doLeftAndRightSwapInRTL setting to correctly + * map logical properties (start, end, block-start, block-end) to physical edges (left, right, + * top, bottom). + * + * @param layoutDirection The resolved layout direction (LTR or RTL) + * @param context Android context for RTL swap preference + * @return ColorEdges with resolved physical edge colors + * @throws IllegalArgumentException if layoutDirection is not LTR or RTL + */ fun resolve(layoutDirection: Int, context: Context): ColorEdges { return when (layoutDirection) { LayoutDirection.LTR -> diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt index f7b46e1395cb1f..e478867b0d714b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BorderRadiusStyle.kt @@ -12,7 +12,12 @@ import android.util.LayoutDirection import com.facebook.react.modules.i18nmanager.I18nUtil import com.facebook.react.uimanager.LengthPercentage -/** Represents the collection of possible border radius style properties. */ +/** + * Enum representing all possible border radius style property names. + * + * This includes both physical corner properties (e.g., BORDER_TOP_LEFT_RADIUS) and logical corner + * properties (e.g., BORDER_START_START_RADIUS) that adapt to layout direction. + */ public enum class BorderRadiusProp { BORDER_RADIUS, BORDER_TOP_LEFT_RADIUS, @@ -29,7 +34,16 @@ public enum class BorderRadiusProp { BORDER_START_START_RADIUS, } -/** Represents all logical properties and shorthands for border radius. */ +/** + * Represents all logical and physical border radius properties and shorthands. + * + * This data class stores border radius values using both physical corner names (topLeft, topRight, + * etc.) and logical corner names (topStart, startStart, etc.) that adapt to layout direction. + * Values are stored as [LengthPercentage] to support both absolute and percentage-based radii. + * + * @see BorderRadiusProp + * @see ComputedBorderRadius + */ internal data class BorderRadiusStyle( var uniform: LengthPercentage? = null, var topLeft: LengthPercentage? = null, @@ -49,6 +63,12 @@ internal data class BorderRadiusStyle( properties.forEach { (k, v) -> set(k, v) } } + /** + * Sets a border radius property value. + * + * @param property The border radius property to set + * @param value The length/percentage value, or null to clear + */ fun set(property: BorderRadiusProp, value: LengthPercentage?) { when (property) { BorderRadiusProp.BORDER_RADIUS -> uniform = value @@ -67,6 +87,12 @@ internal data class BorderRadiusStyle( } } + /** + * Gets a border radius property value. + * + * @param property The border radius property to get + * @return The length/percentage value, or null if not set + */ fun get(property: BorderRadiusProp): LengthPercentage? { return when (property) { BorderRadiusProp.BORDER_RADIUS -> uniform @@ -85,6 +111,11 @@ internal data class BorderRadiusStyle( } } + /** + * Checks if any border radius property is set. + * + * @return true if at least one border radius is defined + */ fun hasRoundedBorders(): Boolean { return uniform != null || topLeft != null || @@ -101,6 +132,19 @@ internal data class BorderRadiusStyle( endEnd != null } + /** + * Resolves logical border radius properties to physical corners based on layout direction. + * + * This method converts logical properties (startStart, topEnd, etc.) to physical corners + * (topLeft, topRight, etc.) based on the layout direction and RTL settings. It also ensures + * corner radii do not overlap per the CSS specification. + * + * @param layoutDirection The resolved layout direction (LTR or RTL) + * @param context Android context for RTL configuration + * @param width The width of the element for percentage resolution + * @param height The height of the element for percentage resolution + * @return ComputedBorderRadius with resolved physical corner radii + */ fun resolve( layoutDirection: Int, context: Context, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BoxShadow.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BoxShadow.kt index e82e370571664c..68a883b7d43fa6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BoxShadow.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/BoxShadow.kt @@ -14,7 +14,19 @@ import com.facebook.react.bridge.JSApplicationCausedNativeException import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.ReadableType -/** Represents all logical properties and shorthands for border radius. */ +/** + * Represents a box shadow effect that can be applied to a React Native view. + * + * This data class models the CSS box-shadow property, including offset, blur, spread, color, and + * inset options. + * + * @property offsetX The horizontal offset of the shadow in pixels + * @property offsetY The vertical offset of the shadow in pixels + * @property color The color of the shadow, or null for default + * @property blurRadius The blur radius of the shadow, or null for no blur + * @property spreadDistance The spread distance of the shadow, or null for no spread + * @property inset Whether the shadow is inset (inner shadow), or null for outer shadow + */ public data class BoxShadow( val offsetX: Float, val offsetY: Float, @@ -24,6 +36,16 @@ public data class BoxShadow( val inset: Boolean? = null, ) { public companion object { + /** + * Parses a ReadableMap into a BoxShadow. + * + * The map must contain "offsetX" and "offsetY" keys. Optional keys include "color", + * "blurRadius", "spreadDistance", and "inset". + * + * @param boxShadow The map containing box shadow configuration + * @param context Android context for color resolution + * @return A BoxShadow instance, or null if required fields are missing + */ @JvmStatic public fun parse(boxShadow: ReadableMap?, context: Context): BoxShadow? { if (boxShadow == null || !(boxShadow.hasKey("offsetX") && boxShadow.hasKey("offsetY"))) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ColorStop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ColorStop.kt index 811ebda4b6d0d9..c7bdb8434c81fc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ColorStop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/ColorStop.kt @@ -14,18 +14,56 @@ import com.facebook.react.uimanager.LengthPercentageType import com.facebook.react.uimanager.PixelUtil import kotlin.math.ln -// ColorStop type is passed by user, so color and position both could be null. -// e.g. -// color is null in transition hint syntax: (red, 20%, green) -// position can be null too (red 20%, green, purple) +/** + * Represents a color stop in a gradient as specified by the user. + * + * Color stops define the colors and their positions within a gradient. Both color and position can + * be null to support CSS gradient syntax features like transition hints. + * + * Examples: + * - color is null in transition hint syntax: (red, 20%, green) + * - position can be null too: (red 20%, green, purple) + * + * @property color The color value at this stop, or null for transition hints + * @property position The position of this stop as a length or percentage, or null for auto + */ internal class ColorStop(var color: Int? = null, val position: LengthPercentage? = null) -// ProcessedColorStop type describes type after processing. -// Here both types are nullable to keep it convenient for the color stop fix up algorithm. -// Final Color stop will have both non-null, we check for non null after calling getFixedColorStop. +/** + * Represents a color stop after processing with resolved position. + * + * This class is used internally during the color stop fix-up algorithm. Both properties are + * nullable to accommodate intermediate states during processing, but will be non-null after + * [ColorStopUtils.getFixedColorStops] completes. + * + * @property color The resolved color value, or null during processing + * @property position The resolved position as a fraction (0.0 to 1.0), or null during processing + */ internal class ProcessedColorStop(var color: Int? = null, val position: Float? = null) +/** + * Utility object for processing gradient color stops according to CSS specification. + * + * This object implements the color stop fix-up algorithm as defined in the CSS Images Module Level + * 4 specification, handling position interpolation and transition hints. + * + * @see CSS Images Module + * Level 4 + */ internal object ColorStopUtils { + /** + * Processes a list of color stops into fixed color stops with resolved positions. + * + * This method implements the CSS color stop fix-up algorithm: + * 1. Sets first stop position to 0% and last to 100% if not specified + * 2. Ensures positions are monotonically increasing + * 3. Interpolates positions for stops without explicit positions + * 4. Processes transition hints by generating intermediate color stops + * + * @param colorStops The input color stops from user specification + * @param gradientLineLength The length of the gradient line in pixels + * @return A list of processed color stops with all positions resolved + */ fun getFixedColorStops( colorStops: List, gradientLineLength: Float, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/CornerRadii.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/CornerRadii.kt index 3135ff322368c2..b81231f707a4e1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/CornerRadii.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/style/CornerRadii.kt @@ -10,17 +10,37 @@ package com.facebook.react.uimanager.style import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.PixelUtil -/** Represents the resolved horizontal and vertical radii of the ellipse representing a corner. */ +/** + * Represents the resolved horizontal and vertical radii of the ellipse representing a corner. + * + * This data class stores the computed radius values for a single corner of a view's border. Each + * corner can have an elliptical shape with different horizontal and vertical radii. + * + * @property horizontal The horizontal radius of the corner ellipse in pixels + * @property vertical The vertical radius of the corner ellipse in pixels + */ public data class CornerRadii( val horizontal: Float = 0f, val vertical: Float = 0f, ) { + /** + * Creates CornerRadii by resolving a LengthPercentage value against reference dimensions. + * + * @param length The length/percentage value to resolve + * @param referenceWidth The reference width for percentage calculations + * @param referenceHeight The reference height for percentage calculations + */ public constructor( length: LengthPercentage, referenceWidth: Float, referenceHeight: Float, ) : this(horizontal = length.resolve(referenceWidth), vertical = length.resolve(referenceHeight)) + /** + * Converts the corner radii from density-independent pixels (DIP) to physical pixels. + * + * @return A new CornerRadii with values converted to pixels + */ public fun toPixelFromDIP(): CornerRadii { return CornerRadii(PixelUtil.toPixelFromDIP(horizontal), PixelUtil.toPixelFromDIP(vertical)) }