UNPKG

3.4 kBJavaScriptView Raw
1// @flow
2import React, { Component } from 'react';
3import PropTypes from 'prop-types';
4import { processColor, requireNativeComponent, PointPropType, StyleSheet, View, ViewPropTypes } from 'react-native';
5const deprecatedPropType = require('react-native/Libraries/Utilities/deprecatedPropType.js');
6
7const convertPoint = (name, point) => {
8 if (Array.isArray(point)) {
9 console.warn(
10 `LinearGradient '${name}' property shoule be an object with fields 'x' and 'y', ` +
11 'Array type is deprecated.'
12 );
13 }
14 if (point !== null && typeof point === 'object') {
15 return [point.x, point.y];
16 }
17 return point;
18};
19
20type PropsType = {
21 start?: Array<number> | {x: number, y: number};
22 end?: Array<number> | {x: number, y: number};
23 colors: Array<string>;
24 locations?: Array<number>;
25} & typeof(View);
26
27export default class LinearGradient extends Component {
28 static propTypes = {
29 start: PropTypes.oneOfType([
30 PointPropType,
31 deprecatedPropType(
32 PropTypes.arrayOf(PropTypes.number),
33 'Use point object with {x, y} instead.'
34 )
35 ]),
36 end: PropTypes.oneOfType([
37 PointPropType,
38 deprecatedPropType(
39 PropTypes.arrayOf(PropTypes.number),
40 'Use point object with {x, y} instead.'
41 )
42 ]),
43 colors: PropTypes.arrayOf(PropTypes.string).isRequired,
44 locations: PropTypes.arrayOf(PropTypes.number),
45 ...ViewPropTypes,
46 };
47 props: PropsType;
48 gradientRef: any;
49
50 setNativeProps(props: PropsType) {
51 this.gradientRef.setNativeProps(props);
52 }
53
54 render() {
55 const {
56 children,
57 colors,
58 end,
59 locations,
60 start,
61 style,
62 ...otherProps
63 } = this.props;
64
65 if ((colors && locations) && (colors.length !== locations.length)) {
66 console.warn('LinearGradient colors and locations props should be arrays of the same length');
67 }
68
69 // inherit container borderRadius until this issue is resolved:
70 // https://github.com/facebook/react-native/issues/3198
71 const flatStyle = StyleSheet.flatten(style) || {};
72 const borderRadius = flatStyle.borderRadius || 0;
73
74 // this is the format taken by:
75 // http://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF, float[], android.graphics.Path.Direction)
76 const borderRadiiPerCorner = [
77 flatStyle.borderTopLeftRadius || borderRadius,
78 flatStyle.borderTopLeftRadius || borderRadius,
79 flatStyle.borderTopRightRadius || borderRadius,
80 flatStyle.borderTopRightRadius || borderRadius,
81 flatStyle.borderBottomRightRadius || borderRadius,
82 flatStyle.borderBottomRightRadius || borderRadius,
83 flatStyle.borderBottomLeftRadius || borderRadius,
84 flatStyle.borderBottomLeftRadius || borderRadius
85 ];
86
87 return (
88 <View ref={(component) => { this.gradientRef = component; }} {...otherProps} style={style}>
89 <NativeLinearGradient
90 style={{position: 'absolute', top: 0, left: 0, bottom: 0, right: 0}}
91 colors={colors.map(processColor)}
92 startPoint={convertPoint('start', start)}
93 endPoint={convertPoint('end', end)}
94 locations={locations ? locations.slice(0, colors.length) : null}
95 borderRadii={borderRadiiPerCorner}
96 />
97 { children }
98 </View>
99 );
100 }
101}
102
103const NativeLinearGradient = requireNativeComponent('BVLinearGradient', null);