1 | import * as React from 'react';
|
2 | import { Platform, processColor, View } from 'react-native';
|
3 |
|
4 | import NativeLinearGradient from './NativeLinearGradient';
|
5 | import { NativeLinearGradientPoint } from './NativeLinearGradient.types';
|
6 |
|
7 | export type LinearGradientPoint = { x: number; y: number } | NativeLinearGradientPoint;
|
8 |
|
9 | export 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 | */
|
50 | export 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 |
|
74 | function _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 | }
|