1 |
|
2 | import React, { Component } from 'react';
|
3 | import PropTypes from 'prop-types';
|
4 | import { processColor, requireNativeComponent, PointPropType, StyleSheet, View, ViewPropTypes } from 'react-native';
|
5 | const deprecatedPropType = require('react-native/Libraries/Utilities/deprecatedPropType.js');
|
6 |
|
7 | const 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 |
|
20 | type 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 |
|
27 | export 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 |
|
70 |
|
71 | const flatStyle = StyleSheet.flatten(style) || {};
|
72 | const borderRadius = flatStyle.borderRadius || 0;
|
73 |
|
74 |
|
75 |
|
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 |
|
103 | const NativeLinearGradient = requireNativeComponent('BVLinearGradient', null);
|