Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,33 @@ 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?,
public val right: LengthPercentage?,
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,51 @@ 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,
@param:ColorInt val right: Int = Color.BLACK,
@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<Int?> = arrayOfNulls<Int?>(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 ->
Expand Down
Loading
Loading