UNPKG

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