1import * as React from 'react'; 2import { Platform, processColor, ViewProps } from 'react-native'; 3 4import NativeLinearGradient from './NativeLinearGradient'; 5import { NativeLinearGradientPoint } from './NativeLinearGradient.types'; 6 7// @needsAudit 8/** 9 * An object `{ x: number; y: number }` or array `[x, y]` that represents the point 10 * at which the gradient starts or ends, as a fraction of the overall size of the gradient ranging 11 * from `0` to `1`, inclusive. 12 */ 13export type LinearGradientPoint = 14 | { 15 /** 16 * A number ranging from `0` to `1`, representing the position of gradient transformation. 17 */ 18 x: number; 19 /** 20 * A number ranging from `0` to `1`, representing the position of gradient transformation. 21 */ 22 y: number; 23 } 24 | NativeLinearGradientPoint; 25 26// @needsAudit 27export type LinearGradientProps = ViewProps & { 28 /** 29 * An array of colors that represent stops in the gradient. At least two colors are required 30 * (for a single-color background, use the `style.backgroundColor` prop on a `View` component). 31 */ 32 colors: string[]; 33 /** 34 * An array that contains `number`s ranging from `0` to `1`, inclusive, and is the same length as the `colors` property. 35 * Each number indicates a color-stop location where each respective color should be located. 36 * If not specified, the colors will be distributed evenly across the gradient. 37 * 38 * For example, `[0.5, 0.8]` would render: 39 * - the first color, solid, from the beginning of the gradient view to 50% through (the middle); 40 * - a gradient from the first color to the second from the 50% point to the 80% point; and 41 * - the second color, solid, from the 80% point to the end of the gradient view. 42 * 43 * > The color-stop locations must be ascending from least to greatest. 44 * @default [] 45 */ 46 locations?: number[] | null; 47 /** 48 * For example, `{ x: 0.1, y: 0.2 }` means that the gradient will start `10%` from the left and `20%` from the top. 49 * 50 * **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the starting position. 51 * @default { x: 0.5, y: 0.0 } 52 */ 53 start?: LinearGradientPoint | null; 54 /** 55 * For example, `{ x: 0.1, y: 0.2 }` means that the gradient will end `10%` from the left and `20%` from the bottom. 56 * 57 * **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the end position. 58 * @default { x: 0.5, y: 1.0 } 59 */ 60 end?: LinearGradientPoint | null; 61}; 62 63/** 64 * Renders a native view that transitions between multiple colors in a linear direction. 65 */ 66export class LinearGradient extends React.Component<LinearGradientProps> { 67 render() { 68 const { colors, locations, start, end, ...props } = this.props; 69 let resolvedLocations = locations; 70 if (locations && colors.length !== locations.length) { 71 console.warn('LinearGradient colors and locations props should be arrays of the same length'); 72 resolvedLocations = locations.slice(0, colors.length); 73 } 74 75 return ( 76 <NativeLinearGradient 77 {...props} 78 colors={Platform.select({ 79 web: colors as any, 80 default: colors.map(processColor), 81 })} 82 locations={resolvedLocations} 83 startPoint={_normalizePoint(start)} 84 endPoint={_normalizePoint(end)} 85 /> 86 ); 87 } 88} 89 90function _normalizePoint( 91 point: LinearGradientPoint | null | undefined 92): NativeLinearGradientPoint | undefined { 93 if (!point) { 94 return undefined; 95 } 96 97 if (Array.isArray(point) && point.length !== 2) { 98 console.warn('start and end props for LinearGradient must be of the format [x,y] or {x, y}'); 99 return undefined; 100 } 101 102 return Array.isArray(point) ? point : [point.x, point.y]; 103} 104