One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Gradients

React Native backgroundImage and native SwiftUI gradients

React Native views use the React Native 0.87 backgroundImage style prop for linear gradients:

import { View } from 'react-native'
<View
style={{
backgroundImage: [
{
type: 'linear-gradient',
direction: 'to bottom',
colorStops: [
{ color: 'rgba(0,0,0,1)', positions: ['0%'] },
{ color: 'rgba(0,0,0,0)', positions: ['100%'] },
],
},
],
}}
/>

One’s own EdgeFade overlay mode paints this exact shape, sampling its edge curve into gradient stops. See packages/one/src/platform/effects/EdgeFade.native.tsx for the prior art. The stable backgroundImage key needs React Native 0.87; 0.86 only processes the experimental alias.

For a SwiftUI view tree, One.iOS.LinearGradient calls SwiftUI’s LinearGradient(colors:startPoint:endPoint:). Give it sRGB colors as #RRGGBB or #RRGGBBAA strings. startPoint and endPoint are normalized { x, y } coordinates, defaulting to top center and bottom center. Like a native shape, it fills its React Native layout box:

<One.iOS.LinearGradient
colors={['#FF3311', '#1144DD']}
startPoint={{ x: 0.5, y: 0 }}
endPoint={{ x: 0.5, y: 1 }}
style={{ width: 280, height: 150 }}
/>

An empty colors array leaves the layout box transparent. A single color fills the box uniformly. This is a SwiftUI gradient; its interpolation can look different from React Native’s backgroundImage even with the same endpoint colors. Without an accessibilityLabel, the gradient is decorative and omitted from the accessibility tree. Supply a label when the colors convey meaning.

One.iOS.RadialGradient calls SwiftUI’s RadialGradient(colors:center:startRadius:endRadius:). Its center is a normalized { x, y } point (default { x: 0.5, y: 0.5 }), while radii are points in the view’s layout box. endRadius is required; startRadius defaults to 0. The same sRGB hex color and accessibility rules apply:

<One.iOS.RadialGradient
colors={['#FF3311', '#1144DD']}
center={{ x: 0.5, y: 0.5 }}
startRadius={0}
endRadius={80}
style={{ width: 280, height: 150 }}
/>

The iOS 27 proof exercises center movement, both radii, reversed colors, single and three-color arrays, alpha, and empty colors. Explicit color stops and arbitrary SwiftUI Color values are not bound by these views.

One.iOS.AngularGradient calls SwiftUI’s AngularGradient(colors:center:angle:). center uses the same normalized { x, y } point as RadialGradient. angle uses the existing SwiftUI angle shape { radians } and defaults to zero. The initializer sweeps colors around a full circle:

<One.iOS.AngularGradient
colors={['#FF3311', '#1144DD']}
center={{ x: 0.5, y: 0.5 }}
angle={{ radians: Math.PI / 2 }}
style={{ width: 280, height: 150 }}
/>

The partial-arc startAngle/endAngle initializer and explicit color stops are not bound. The same sRGB hex and decorative-unless-labeled accessibility rules apply.

The iOS 27 proof exercises a half-turn angle, a moved center, reversed colors, single and three-color arrays, alpha over a yellow underlay, and transparent empty input. Other iOS versions remain unproven.

One.iOS.EllipticalGradient calls SwiftUI’s EllipticalGradient(colors:center:startRadiusFraction:endRadiusFraction:). Its normalized center defaults to { x: 0.5, y: 0.5 }. The two radii are fractions of the unit circle stretched into the view’s layout box; they default to 0 and 0.5:

<One.iOS.EllipticalGradient
colors={['#FF3311', '#1144DD']}
center={{ x: 0.5, y: 0.5 }}
startRadiusFraction={0}
endRadiusFraction={0.5}
style={{ width: 280, height: 150 }}
/>

The same sRGB hex and decorative-unless-labeled accessibility rules apply. Explicit gradient stops and arbitrary SwiftUI Color values are not bound.

The iOS 27 iPhone 17 Pro proof covers both radius fractions, center movement, reversed colors, one and three colors, alpha over a yellow underlay, and transparent empty input. Off-axis pixel samples confirm the elliptical contour. Other iOS versions remain unproven.

One.iOS.MeshGradient calls SwiftUI’s MeshGradient(width:height:points:colors:background:smoothsColors:colorSpace:). It requires iOS 18 or newer. meshWidth and meshHeight count vertices, so points and colors each contain meshWidth × meshHeight entries in row order. The names keep grid dimensions separate from the view’s layout dimensions. Each point is a normalized { x, y } coordinate; colors and the optional background use sRGB #RRGGBB or #RRGGBBAA strings:

<One.iOS.MeshGradient
meshWidth={2}
meshHeight={2}
points={[{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }]}
colors={['#FF0000', '#00FF00', '#0000FF', '#FFFF00']}
background="#00000000"
smoothsColors
colorSpace="device"
style={{ width: 280, height: 180 }}
/>

background defaults to clear, smoothsColors to true, and colorSpace to device; perceptual is the other native interpolation method. An unlabeled mesh is decorative for accessibility. The Bezier-point and resolved-color initializers are not bound.

The iOS 27 iPhone 17 Pro proof covers 2×2 and 3×3 grids, vertex colors and movement, the background outside an inset mesh, smooth versus unsmoothed interpolation, and device versus perceptual color spaces. Other iOS versions, Bezier-point meshes, and resolved-color inputs remain unproven.

Edit this page on GitHub.