This commit is contained in:
Yamozha
2021-04-02 02:24:13 +03:00
parent c23950b545
commit 7256d79e2c
31493 changed files with 3036630 additions and 0 deletions

3
node_modules/expo-linear-gradient/.babelrc generated vendored Normal file
View File

@ -0,0 +1,3 @@
{
"presets": ["babel-preset-expo"]
}

2
node_modules/expo-linear-gradient/.eslintrc.js generated vendored Normal file
View File

@ -0,0 +1,2 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');

43
node_modules/expo-linear-gradient/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,43 @@
# Changelog
## Unpublished
### 🛠 Breaking changes
### 🎉 New features
### 🐛 Bug fixes
## 8.4.0 — 2020-11-25
### 🐛 Bug fixes
- Revert to class component. ([#11111](https://github.com/expo/expo/pull/11111) by [@EvanBacon](https://github.com/EvanBacon))
## 8.3.1 — 2020-09-23
### 🐛 Bug fixes
- Added `children` property to `LinearGradient` component ([#10227](https://github.com/expo/expo/pull/10227) by [@sjchmiela](https://github.com/sjchmiela))
## 8.3.0 — 2020-08-18
_This version does not introduce any user-facing changes._
## 8.2.2 — 2020-07-29
### 🎉 New features
- Remove `prop-types` ([#8681](https://github.com/expo/expo/pull/8681) by [@EvanBacon](https://github.com/EvanBacon))
### 🐛 Bug fixes
- Renamed type export `LinearGradienPoint` to `LinearGradientPoint`. ([#8673](https://github.com/expo/expo/pull/8673) by [@EvanBacon](https://github.com/EvanBacon))
## 8.2.1 — 2020-05-29
_This version does not introduce any user-facing changes._
## 8.2.0 — 2020-05-27
_This version does not introduce any user-facing changes._

34
node_modules/expo-linear-gradient/README.md generated vendored Normal file
View File

@ -0,0 +1,34 @@
# expo-linear-gradient
Provides a React component that renders a gradient view.
# API documentation
- [Documentation for the master branch](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/sdk/linear-gradient.md)
- [Documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/linear-gradient/)
# Installation in managed Expo projects
For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.io/versions/latest/sdk/linear-gradient/).
# Installation in bare React Native projects
For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
### Add the package to your npm dependencies
```
expo install expo-linear-gradient
```
### Configure for iOS
Run `npx pod-install` after installing the npm package.
### Configure for Android
No additional set up necessary.
# Contributing
Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).

61
node_modules/expo-linear-gradient/android/build.gradle generated vendored Normal file
View File

@ -0,0 +1,61 @@
apply plugin: 'com.android.library'
apply plugin: 'maven'
group = 'host.exp.exponent'
version = '8.4.0'
// Simple helper that allows the root project to override versions declared by this library.
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
// Upload android library to maven with javadoc and android sources
configurations {
deployerJars
}
// Creating sources with comments
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
// Put the androidSources and javadoc to the artifacts
artifacts {
archives androidSourcesJar
}
uploadArchives {
repositories {
mavenDeployer {
configuration = configurations.deployerJars
repository(url: mavenLocal().url)
}
}
}
android {
compileSdkVersion safeExtGet("compileSdkVersion", 29)
defaultConfig {
minSdkVersion safeExtGet("minSdkVersion", 21)
targetSdkVersion safeExtGet("targetSdkVersion", 29)
versionCode 16
versionName "8.4.0"
}
lintOptions {
abortOnError false
}
}
if (new File(rootProject.projectDir.parentFile, 'package.json').exists()) {
apply from: project(":unimodules-core").file("../unimodules-core.gradle")
} else {
throw new GradleException(
"'unimodules-core.gradle' was not found in the usual React Native dependency location. " +
"This package can only be used in such projects. Are you sure you've installed the dependencies properly?")
}
dependencies {
unimodule "unimodules-core"
}

View File

@ -0,0 +1,5 @@
<manifest package="expo.modules.lineargradient">
</manifest>

View File

@ -0,0 +1,60 @@
package expo.modules.lineargradient;
import android.content.Context;
import org.unimodules.core.ViewManager;
import org.unimodules.core.interfaces.ExpoProp;
import java.util.ArrayList;
public class LinearGradientManager extends ViewManager<LinearGradientView> {
public static final String VIEW_CLASS_NAME = "ExpoLinearGradient";
public static final String PROP_COLORS = "colors";
public static final String PROP_LOCATIONS = "locations";
public static final String PROP_START_POS = "startPoint";
public static final String PROP_END_POS = "endPoint";
public static final String PROP_BORDER_RADII = "borderRadii";
@Override
public String getName() {
return VIEW_CLASS_NAME;
}
@Override
public LinearGradientView createViewInstance(Context context) {
return new LinearGradientView(context);
}
@Override
public ViewManagerType getViewManagerType() {
return ViewManagerType.SIMPLE;
}
@ExpoProp(name = PROP_COLORS)
public void setColors(LinearGradientView view, final ArrayList<Double> colors) {
view.setColors(colors);
}
@ExpoProp(name = PROP_LOCATIONS)
public void setLocations(LinearGradientView view, final ArrayList<Double> locations) {
if (locations != null) {
view.setLocations(locations);
}
}
@ExpoProp(name = PROP_START_POS)
public void setStartPosition(LinearGradientView view, final ArrayList<Double> startPos) {
view.setStartPosition(startPos);
}
@ExpoProp(name = PROP_END_POS)
public void setEndPosition(LinearGradientView view, final ArrayList<Double> endPos) {
view.setEndPosition(endPos);
}
// temporary solution until following issue is resolved:
// https://github.com/facebook/react-native/issues/3198
@ExpoProp(name = PROP_BORDER_RADII)
public void setBorderRadii(LinearGradientView view, final ArrayList<Double> borderRadii) {
view.setBorderRadii(borderRadii);
}
}

View File

@ -0,0 +1,16 @@
package expo.modules.lineargradient;
import android.content.Context;
import java.util.Collections;
import java.util.List;
import org.unimodules.core.BasePackage;
import org.unimodules.core.ViewManager;
public class LinearGradientPackage extends BasePackage {
@Override
public List<ViewManager> createViewManagers(Context context) {
return Collections.singletonList((ViewManager) new LinearGradientManager());
}
}

View File

@ -0,0 +1,128 @@
package expo.modules.lineargradient;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.TypedValue;
import android.view.View;
public class LinearGradientView extends View {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPathForBorderRadius;
private RectF mTempRectForBorderRadius;
private float[] mLocations;
private float[] mStartPos = {0, 0};
private float[] mEndPos = {0, 1};
private int[] mColors;
private int[] mSize = {0, 0};
private float[] mBorderRadii = {0, 0, 0, 0, 0, 0, 0, 0};
public LinearGradientView(Context context) {
super(context);
}
public void setStartPosition(final ArrayList<Double> startPos) {
mStartPos = new float[]{startPos.get(0).floatValue(), startPos.get(1).floatValue()};
drawGradient();
}
public void setEndPosition(final ArrayList<Double> endPos) {
mEndPos = new float[]{endPos.get(0).floatValue(), endPos.get(1).floatValue()};
drawGradient();
}
public void setColors(final ArrayList<Double> colors) {
int[] _colors = new int[colors.size()];
for (int i=0; i < _colors.length; i++)
{
_colors[i] = colors.get(i).intValue();
}
mColors = _colors;
drawGradient();
}
public void setLocations(final ArrayList<Double> locations) {
float[] _locations = new float[locations.size()];
for (int i=0; i < _locations.length; i++)
{
_locations[i] = locations.get(i).floatValue();
}
mLocations = _locations;
drawGradient();
}
public void setBorderRadii(final ArrayList<Double> borderRadii) {
float[] _radii = new float[borderRadii.size()];
for (int i=0; i < _radii.length; i++)
{
_radii[i] = toPixelFromDIP(borderRadii.get(i).floatValue());
}
mBorderRadii = _radii;
updatePath();
drawGradient();
}
// Copied from RN PixelUtil
// We might want to expose display metrics on @unimodules/core somewhere to avoid
// having code similar to this littered throughout modules
private float toPixelFromDIP(float value) {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
value,
getContext().getResources().getDisplayMetrics()
);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mSize = new int[]{w, h};
updatePath();
drawGradient();
}
private void drawGradient() {
// guard against crashes happening while multiple properties are updated
if (mColors == null || (mLocations != null && mColors.length != mLocations.length))
return;
LinearGradient mShader = new LinearGradient(
mStartPos[0] * mSize[0],
mStartPos[1] * mSize[1],
mEndPos[0] * mSize[0],
mEndPos[1] * mSize[1],
mColors,
mLocations,
Shader.TileMode.CLAMP);
mPaint.setShader(mShader);
invalidate();
}
private void updatePath() {
if (mPathForBorderRadius == null) {
mPathForBorderRadius = new Path();
mTempRectForBorderRadius = new RectF();
}
mPathForBorderRadius.reset();
mTempRectForBorderRadius.set(0f, 0f, (float) mSize[0], (float) mSize[1]);
mPathForBorderRadius.addRoundRect(
mTempRectForBorderRadius,
mBorderRadii,
Path.Direction.CW);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPathForBorderRadius == null) {
canvas.drawPaint(mPaint);
} else {
canvas.drawPath(mPathForBorderRadius, mPaint);
}
}
}

View File

@ -0,0 +1,50 @@
import * as React from 'react';
import { View } from 'react-native';
import { NativeLinearGradientPoint } from './NativeLinearGradient.types';
export declare type LinearGradientPoint = {
x: number;
y: number;
} | NativeLinearGradientPoint;
export declare type LinearGradientProps = {
/**
* An array of colors that represent stops in the gradient. At least two colors are required
* (for a single-color background, use the `style.backgroundColor` prop on a `View` component).
*/
colors: string[];
/**
* An array that contains `number`s ranging from 0 to 1, inclusive, and is the same length as the `colors` property.
* Each number indicates a color-stop location where each respective color should be located.
*
* For example, `[0.5, 0.8]` would render:
* - the first color, solid, from the beginning of the gradient view to 50% through (the middle);
* - a gradient from the first color to the second from the 50% point to the 80% point; and
* - the second color, solid, from the 80% point to the end of the gradient view.
*
* The color-stop locations must be ascending from least to greatest.
*/
locations?: number[] | null;
/**
* An object `{ x: number; y: number }` or array `[x, y]` that represents the point
* at which the gradient starts, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.
*
* For example, `{ x: 0.1, y: 0.2 }` means that the gradient will start `10%` from the left and `20%` from the top.
*
* **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the starting position.
*/
start?: LinearGradientPoint | null;
/**
* An object `{ x: number; y: number }` or array `[x, y]` that represents the point
* at which the gradient ends, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.
*
* For example, `{ x: 0.1, y: 0.2 }` means that the gradient will end `10%` from the left and `20%` from the bottom.
*
* **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the end position.
*/
end?: LinearGradientPoint | null;
} & React.ComponentProps<typeof View>;
/**
* Renders a native view that transitions between multiple colors in a linear direction.
*/
export declare class LinearGradient extends React.Component<LinearGradientProps> {
render(): JSX.Element;
}

View File

@ -0,0 +1,31 @@
import * as React from 'react';
import { Platform, processColor } from 'react-native';
import NativeLinearGradient from './NativeLinearGradient';
/**
* Renders a native view that transitions between multiple colors in a linear direction.
*/
export class LinearGradient extends React.Component {
render() {
const { colors, locations, start, end, ...props } = this.props;
let resolvedLocations = locations;
if (locations && colors.length !== locations.length) {
console.warn('LinearGradient colors and locations props should be arrays of the same length');
resolvedLocations = locations.slice(0, colors.length);
}
return (React.createElement(NativeLinearGradient, Object.assign({}, props, { colors: Platform.select({
web: colors,
default: colors.map(processColor),
}), locations: resolvedLocations, startPoint: _normalizePoint(start), endPoint: _normalizePoint(end) })));
}
}
function _normalizePoint(point) {
if (!point) {
return undefined;
}
if (Array.isArray(point) && point.length !== 2) {
console.warn('start and end props for LinearGradient must be of the format [x,y] or {x, y}');
return undefined;
}
return Array.isArray(point) ? point : [point.x, point.y];
}
//# sourceMappingURL=LinearGradient.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"LinearGradient.js","sourceRoot":"","sources":["../src/LinearGradient.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAQ,MAAM,cAAc,CAAC;AAE5D,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AA2C1D;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK,CAAC,SAA8B;IACtE,MAAM;QACJ,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC/D,IAAI,iBAAiB,GAAG,SAAS,CAAC;QAClC,IAAI,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE;YACnD,OAAO,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;YAC9F,iBAAiB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;SACvD;QAED,OAAO,CACL,oBAAC,oBAAoB,oBACf,KAAK,IACT,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;gBACtB,GAAG,EAAE,MAAa;gBAClB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;aAClC,CAAC,EACF,SAAS,EAAE,iBAAiB,EAC5B,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,EAClC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,IAC9B,CACH,CAAC;IACJ,CAAC;CACF;AAED,SAAS,eAAe,CACtB,KAA6C;IAE7C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9C,OAAO,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;QAC7F,OAAO,SAAS,CAAC;KAClB;IAED,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import * as React from 'react';\nimport { Platform, processColor, View } from 'react-native';\n\nimport NativeLinearGradient from './NativeLinearGradient';\nimport { NativeLinearGradientPoint } from './NativeLinearGradient.types';\n\nexport type LinearGradientPoint = { x: number; y: number } | NativeLinearGradientPoint;\n\nexport type LinearGradientProps = {\n /**\n * An array of colors that represent stops in the gradient. At least two colors are required\n * (for a single-color background, use the `style.backgroundColor` prop on a `View` component).\n */\n colors: string[];\n /**\n * An array that contains `number`s ranging from 0 to 1, inclusive, and is the same length as the `colors` property.\n * Each number indicates a color-stop location where each respective color should be located.\n *\n * For example, `[0.5, 0.8]` would render:\n * - the first color, solid, from the beginning of the gradient view to 50% through (the middle);\n * - a gradient from the first color to the second from the 50% point to the 80% point; and\n * - the second color, solid, from the 80% point to the end of the gradient view.\n *\n * The color-stop locations must be ascending from least to greatest.\n */\n locations?: number[] | null;\n /**\n * An object `{ x: number; y: number }` or array `[x, y]` that represents the point\n * at which the gradient starts, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.\n *\n * For example, `{ x: 0.1, y: 0.2 }` means that the gradient will start `10%` from the left and `20%` from the top.\n *\n * **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the starting position.\n */\n start?: LinearGradientPoint | null;\n /**\n * An object `{ x: number; y: number }` or array `[x, y]` that represents the point\n * at which the gradient ends, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.\n *\n * For example, `{ x: 0.1, y: 0.2 }` means that the gradient will end `10%` from the left and `20%` from the bottom.\n *\n * **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the end position.\n */\n end?: LinearGradientPoint | null;\n} & React.ComponentProps<typeof View>;\n\n/**\n * Renders a native view that transitions between multiple colors in a linear direction.\n */\nexport class LinearGradient extends React.Component<LinearGradientProps> {\n render() {\n const { colors, locations, start, end, ...props } = this.props;\n let resolvedLocations = locations;\n if (locations && colors.length !== locations.length) {\n console.warn('LinearGradient colors and locations props should be arrays of the same length');\n resolvedLocations = locations.slice(0, colors.length);\n }\n\n return (\n <NativeLinearGradient\n {...props}\n colors={Platform.select({\n web: colors as any,\n default: colors.map(processColor),\n })}\n locations={resolvedLocations}\n startPoint={_normalizePoint(start)}\n endPoint={_normalizePoint(end)}\n />\n );\n }\n}\n\nfunction _normalizePoint(\n point: LinearGradientPoint | null | undefined\n): [number, number] | undefined {\n if (!point) {\n return undefined;\n }\n\n if (Array.isArray(point) && point.length !== 2) {\n console.warn('start and end props for LinearGradient must be of the format [x,y] or {x, y}');\n return undefined;\n }\n\n return Array.isArray(point) ? point : [point.x, point.y];\n}\n"]}

View File

@ -0,0 +1,3 @@
import * as React from 'react';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
export default function NativeLinearGradient({ colors, locations, startPoint, endPoint, children, style, ...props }: NativeLinearGradientProps): React.ReactElement;

View File

@ -0,0 +1,26 @@
import { requireNativeViewManager } from '@unimodules/core';
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
export default function NativeLinearGradient({ colors, locations, startPoint, endPoint, children, style, ...props }) {
// TODO: revisit whether we need to inherit the container's borderRadius since this issue has
// been resolved: https://github.com/facebook/react-native/issues/3198
const flatStyle = StyleSheet.flatten(style) ?? {};
const borderRadius = flatStyle.borderRadius ?? 0;
// This is the format from:
// https://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF,%20float[],%20android.graphics.Path.Direction)
const borderRadiiPerCorner = [
flatStyle.borderTopLeftRadius ?? borderRadius,
flatStyle.borderTopLeftRadius ?? borderRadius,
flatStyle.borderTopRightRadius ?? borderRadius,
flatStyle.borderTopRightRadius ?? borderRadius,
flatStyle.borderBottomRightRadius ?? borderRadius,
flatStyle.borderBottomRightRadius ?? borderRadius,
flatStyle.borderBottomLeftRadius ?? borderRadius,
flatStyle.borderBottomLeftRadius ?? borderRadius,
];
return (React.createElement(View, Object.assign({}, props, { style: style }),
React.createElement(BaseNativeLinearGradient, { style: StyleSheet.absoluteFill, colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations, borderRadii: borderRadiiPerCorner }),
children));
}
const BaseNativeLinearGradient = requireNativeViewManager('ExpoLinearGradient');
//# sourceMappingURL=NativeLinearGradient.android.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"NativeLinearGradient.android.js","sourceRoot":"","sources":["../src/NativeLinearGradient.android.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIhD,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAC3C,MAAM,EACN,SAAS,EACT,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACkB;IAC1B,6FAA6F;IAC7F,sEAAsE;IACtE,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,IAAI,CAAC,CAAC;IAEjD,2BAA2B;IAC3B,wJAAwJ;IACxJ,MAAM,oBAAoB,GAAG;QAC3B,SAAS,CAAC,mBAAmB,IAAI,YAAY;QAC7C,SAAS,CAAC,mBAAmB,IAAI,YAAY;QAC7C,SAAS,CAAC,oBAAoB,IAAI,YAAY;QAC9C,SAAS,CAAC,oBAAoB,IAAI,YAAY;QAC9C,SAAS,CAAC,uBAAuB,IAAI,YAAY;QACjD,SAAS,CAAC,uBAAuB,IAAI,YAAY;QACjD,SAAS,CAAC,sBAAsB,IAAI,YAAY;QAChD,SAAS,CAAC,sBAAsB,IAAI,YAAY;KACjD,CAAC;IAEF,OAAO,CACL,oBAAC,IAAI,oBAAK,KAAK,IAAE,KAAK,EAAE,KAAK;QAC3B,oBAAC,wBAAwB,IACvB,KAAK,EAAE,UAAU,CAAC,YAAY,EAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,oBAAoB,GACjC;QACD,QAAQ,CACJ,CACR,CAAC;AACJ,CAAC;AAED,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,CAAC","sourcesContent":["import { requireNativeViewManager } from '@unimodules/core';\nimport * as React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { NativeLinearGradientProps } from './NativeLinearGradient.types';\n\nexport default function NativeLinearGradient({\n colors,\n locations,\n startPoint,\n endPoint,\n children,\n style,\n ...props\n}: NativeLinearGradientProps): React.ReactElement {\n // TODO: revisit whether we need to inherit the container's borderRadius since this issue has\n // been resolved: https://github.com/facebook/react-native/issues/3198\n const flatStyle = StyleSheet.flatten(style) ?? {};\n const borderRadius = flatStyle.borderRadius ?? 0;\n\n // This is the format from:\n // https://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF,%20float[],%20android.graphics.Path.Direction)\n const borderRadiiPerCorner = [\n flatStyle.borderTopLeftRadius ?? borderRadius,\n flatStyle.borderTopLeftRadius ?? borderRadius,\n flatStyle.borderTopRightRadius ?? borderRadius,\n flatStyle.borderTopRightRadius ?? borderRadius,\n flatStyle.borderBottomRightRadius ?? borderRadius,\n flatStyle.borderBottomRightRadius ?? borderRadius,\n flatStyle.borderBottomLeftRadius ?? borderRadius,\n flatStyle.borderBottomLeftRadius ?? borderRadius,\n ];\n\n return (\n <View {...props} style={style}>\n <BaseNativeLinearGradient\n style={StyleSheet.absoluteFill}\n colors={colors}\n startPoint={startPoint}\n endPoint={endPoint}\n locations={locations}\n borderRadii={borderRadiiPerCorner}\n />\n {children}\n </View>\n );\n}\n\nconst BaseNativeLinearGradient = requireNativeViewManager('ExpoLinearGradient');\n"]}

View File

@ -0,0 +1,3 @@
import * as React from 'react';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
export default function NativeLinearGradient(props: NativeLinearGradientProps): React.ReactElement;

View File

@ -0,0 +1,4 @@
import * as React from 'react';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
declare const NativeLinearGradient: React.FC<NativeLinearGradientProps>;
export default NativeLinearGradient;

View File

@ -0,0 +1,4 @@
import { requireNativeViewManager } from '@unimodules/core';
const NativeLinearGradient = requireNativeViewManager('ExpoLinearGradient');
export default NativeLinearGradient;
//# sourceMappingURL=NativeLinearGradient.ios.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"NativeLinearGradient.ios.js","sourceRoot":"","sources":["../src/NativeLinearGradient.ios.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAK5D,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,oBAAoB,CAEzE,CAAC;AAEF,eAAe,oBAAoB,CAAC","sourcesContent":["import { requireNativeViewManager } from '@unimodules/core';\nimport * as React from 'react';\n\nimport { NativeLinearGradientProps } from './NativeLinearGradient.types';\n\nconst NativeLinearGradient = requireNativeViewManager('ExpoLinearGradient') as React.FC<\n NativeLinearGradientProps\n>;\n\nexport default NativeLinearGradient;\n"]}

View File

@ -0,0 +1,10 @@
import * as React from 'react';
import { View } from 'react-native';
// This is a shim view for platforms that aren't supported by Expo.
// The component and prop types should match all of the other platform variations.
export default function NativeLinearGradient(props) {
const { colors, locations, startPoint, endPoint, ...viewProps } = props;
console.warn('LinearGradient is not available on this platform');
return React.createElement(View, Object.assign({}, viewProps));
}
//# sourceMappingURL=NativeLinearGradient.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"NativeLinearGradient.js","sourceRoot":"","sources":["../src/NativeLinearGradient.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIpC,mEAAmE;AACnE,kFAAkF;AAClF,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,KAAgC;IAC3E,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IACxE,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACjE,OAAO,oBAAC,IAAI,oBAAM,SAAiB,EAAI,CAAC;AAC1C,CAAC","sourcesContent":["import * as React from 'react';\nimport { View } from 'react-native';\n\nimport { NativeLinearGradientProps } from './NativeLinearGradient.types';\n\n// This is a shim view for platforms that aren't supported by Expo.\n// The component and prop types should match all of the other platform variations.\nexport default function NativeLinearGradient(props: NativeLinearGradientProps): React.ReactElement {\n const { colors, locations, startPoint, endPoint, ...viewProps } = props;\n console.warn('LinearGradient is not available on this platform');\n return <View {...(viewProps as any)} />;\n}\n"]}

View File

@ -0,0 +1,9 @@
import * as React from 'react';
import { View } from 'react-native';
export declare type NativeLinearGradientProps = React.ComponentProps<typeof View> & React.PropsWithChildren<{
colors: number[];
locations?: number[] | null;
startPoint?: NativeLinearGradientPoint | null;
endPoint?: NativeLinearGradientPoint | null;
}>;
export declare type NativeLinearGradientPoint = [number, number];

View File

@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=NativeLinearGradient.types.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"NativeLinearGradient.types.js","sourceRoot":"","sources":["../src/NativeLinearGradient.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { View } from 'react-native';\n\nexport type NativeLinearGradientProps = React.ComponentProps<typeof View> &\n React.PropsWithChildren<{\n colors: number[];\n locations?: number[] | null;\n startPoint?: NativeLinearGradientPoint | null;\n endPoint?: NativeLinearGradientPoint | null;\n }>;\n\nexport type NativeLinearGradientPoint = [number, number];\n"]}

View File

@ -0,0 +1,3 @@
import * as React from 'react';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
export default function NativeLinearGradient({ colors, locations, startPoint, endPoint, ...props }: NativeLinearGradientProps): React.ReactElement;

View File

@ -0,0 +1,73 @@
import * as React from 'react';
import { View } from 'react-native';
import normalizeColor from 'react-native-web/src/modules/normalizeColor';
export default function NativeLinearGradient({ colors, locations, startPoint, endPoint, ...props }) {
const [layout, setLayout] = React.useState(null);
const [gradientColors, setGradientColors] = React.useState([]);
const [pseudoAngle, setPseudoAngle] = React.useState(0);
const { width = 1, height = 1 } = layout ?? {};
React.useEffect(() => {
const getControlPoints = () => {
let correctedStartPoint = [0, 0];
if (Array.isArray(startPoint)) {
correctedStartPoint = [
startPoint[0] != null ? startPoint[0] : 0.0,
startPoint[1] != null ? startPoint[1] : 0.0,
];
}
let correctedEndPoint = [0.0, 1.0];
if (Array.isArray(endPoint)) {
correctedEndPoint = [
endPoint[0] != null ? endPoint[0] : 0.0,
endPoint[1] != null ? endPoint[1] : 1.0,
];
}
return [correctedStartPoint, correctedEndPoint];
};
const [start, end] = getControlPoints();
start[0] *= width;
end[0] *= width;
start[1] *= height;
end[1] *= height;
const py = end[1] - start[1];
const px = end[0] - start[0];
setPseudoAngle(90 + (Math.atan2(py, px) * 180) / Math.PI);
}, [width, height, startPoint, endPoint]);
React.useEffect(() => {
const nextGradientColors = colors.map((color, index) => {
const hexColor = normalizeColor(color);
let output = hexColor;
if (locations && locations[index]) {
const location = Math.max(0, Math.min(1, locations[index]));
// Convert 0...1 to 0...100
const percentage = location * 100;
output += ` ${percentage}%`;
}
return output;
});
setGradientColors(nextGradientColors);
}, [colors, locations]);
const colorStyle = gradientColors.join(',');
const backgroundImage = `linear-gradient(${pseudoAngle}deg, ${colorStyle})`;
// TODO(Bacon): In the future we could consider adding `backgroundRepeat: "no-repeat"`. For more
// browser support.
return (React.createElement(View, Object.assign({}, props, { style: [
props.style,
// @ts-ignore: [ts] Property 'backgroundImage' does not exist on type 'ViewStyle'.
{ backgroundImage },
], onLayout: event => {
const { x, y, width, height } = event.nativeEvent.layout;
const oldLayout = layout ?? { x: 0, y: 0, width: 1, height: 1 };
// don't set new layout state unless the layout has actually changed
if (x !== oldLayout.x ||
y !== oldLayout.y ||
width !== oldLayout.width ||
height !== oldLayout.height) {
setLayout({ x, y, width, height });
}
if (props.onLayout) {
props.onLayout(event);
}
} })));
}
//# sourceMappingURL=NativeLinearGradient.web.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,21 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
Pod::Spec.new do |s|
s.name = 'EXLinearGradient'
s.version = package['version']
s.summary = package['description']
s.description = package['description']
s.license = package['license']
s.author = package['author']
s.homepage = package['homepage']
s.platform = :ios, '10.0'
s.source = { git: 'https://github.com/expo/expo.git' }
s.source_files = 'EXLinearGradient/**/*.{h,m}'
s.preserve_paths = 'EXLinearGradient/**/*.{h,m}'
s.requires_arc = true
s.dependency 'UMCore'
end

View File

@ -0,0 +1,14 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import <UIKit/UIKit.h>
#import <UMCore/UMModuleRegistry.h>
#import <UMCore/UMAppLifecycleListener.h>
@interface EXLinearGradient : UIView
- (void)setColors:(NSArray *)colorStrings;
- (void)setLocations:(NSArray *)locations;
- (void)setStartPoint:(CGPoint)start;
- (void)setEndPoint:(CGPoint)end;
@end

View File

@ -0,0 +1,53 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import <EXLinearGradient/EXLinearGradient.h>
#import <EXLinearGradient/EXLinearGradientLayer.h>
#import <UIKit/UIKit.h>
#import <UMCore/UMModuleRegistry.h>
#import <UMCore/UMAppLifecycleListener.h>
#import <UMCore/UMUtilities.h>
@interface EXLinearGradient ()
@end
@implementation EXLinearGradient
+ (Class)layerClass
{
return [EXLinearGradientLayer class];
}
- (EXLinearGradientLayer *)gradientLayer
{
return (EXLinearGradientLayer *)self.layer;
}
- (void)setColors:(NSArray *)colorStrings
{
NSMutableArray *colors = [NSMutableArray arrayWithCapacity:colorStrings.count];
for (NSString *colorString in colorStrings) {
UIColor *convertedColor = [UMUtilities UIColor:colorString];
if (convertedColor) {
[colors addObject:convertedColor];
}
}
self.gradientLayer.colors = colors;
}
- (void)setStartPoint:(CGPoint)start
{
self.gradientLayer.startPoint = start;
}
- (void)setEndPoint:(CGPoint)end
{
self.gradientLayer.endPoint = end;
}
- (void)setLocations:(NSArray *)locations
{
self.gradientLayer.locations = locations;
}
@end

View File

@ -0,0 +1,14 @@
// Copyright 2018-present 650 Industries. All rights reserved.
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
@interface EXLinearGradientLayer : CALayer
@property (nullable, nonatomic, copy) NSArray<UIColor *> *colors;
@property (nullable, nonatomic, copy) NSArray<NSNumber *> *locations;
@property (nonatomic) CGPoint startPoint;
@property (nonatomic) CGPoint endPoint;
@end

View File

@ -0,0 +1,110 @@
// Copyright 2018-present 650 Industries. All rights reserved.
#import <EXLinearGradient/EXLinearGradientLayer.h>
@implementation EXLinearGradientLayer
- (instancetype)init
{
self = [super init];
if (self) {
self.needsDisplayOnBoundsChange = YES;
self.masksToBounds = YES;
_startPoint = CGPointMake(0.5, 0.0);
_endPoint = CGPointMake(0.5, 1.0);
}
return self;
}
- (void)setColors:(NSArray<id> *)colors
{
_colors = colors;
[self setNeedsDisplay];
}
- (void)setLocations:(NSArray<NSNumber *> *)locations
{
_locations = locations;
[self setNeedsDisplay];
}
- (void)setStartPoint:(CGPoint)startPoint
{
_startPoint = startPoint;
[self setNeedsDisplay];
}
- (void)setEndPoint:(CGPoint)endPoint
{
_endPoint = endPoint;
[self setNeedsDisplay];
}
- (void)display {
[super display];
BOOL hasAlpha = NO;
for (NSInteger i = 0; i < self.colors.count; i++) {
hasAlpha = hasAlpha || CGColorGetAlpha(self.colors[i].CGColor) < 1.0;
}
UIGraphicsBeginImageContextWithOptions(self.bounds.size, !hasAlpha, 0.0);
CGContextRef ref = UIGraphicsGetCurrentContext();
[self drawInContext:ref];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
self.contents = (__bridge id _Nullable)(image.CGImage);
self.contentsScale = image.scale;
UIGraphicsEndImageContext();
}
- (void)drawInContext:(CGContextRef)ctx
{
[super drawInContext:ctx];
CGContextSaveGState(ctx);
CGSize size = self.bounds.size;
if (!self.colors || self.colors.count == 0 || size.width == 0.0 || size.height == 0.0)
return;
CGFloat *locations = nil;
locations = malloc(sizeof(CGFloat) * self.colors.count);
for (NSInteger i = 0; i < self.colors.count; i++) {
if (self.locations.count > i) {
locations[i] = self.locations[i].floatValue;
} else {
locations[i] = (1.0 / (self.colors.count - 1)) * i;
}
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSMutableArray *colors = [[NSMutableArray alloc] initWithCapacity:self.colors.count];
for (UIColor *color in self.colors) {
[colors addObject:(id)color.CGColor];
}
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)colors, locations);
free(locations);
CGPoint start = self.startPoint, end = self.endPoint;
CGContextDrawLinearGradient(ctx, gradient,
CGPointMake(start.x * size.width, start.y * size.height),
CGPointMake(end.x * size.width, end.y * size.height),
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
CGContextRestoreGState(ctx);
}
@end

View File

@ -0,0 +1,8 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import <UMCore/UMViewManager.h>
#import <UMCore/UMExportedModule.h>
@interface EXLinearGradientManager : UMViewManager
@end

View File

@ -0,0 +1,45 @@
// Copyright 2015-present 650 Industries. All rights reserved.
#import <EXLinearGradient/EXLinearGradientManager.h>
#import <EXLinearGradient/EXLinearGradient.h>
#import <UMCore/UMUIManager.h>
@interface EXLinearGradientManager ()
@end
@implementation EXLinearGradientManager
UM_EXPORT_MODULE(ExpoLinearGradientManager);
- (NSString *)viewName
{
return @"ExpoLinearGradient";
}
- (UIView *)view
{
return [[EXLinearGradient alloc] init];
}
UM_VIEW_PROPERTY(colors, NSArray *, EXLinearGradient) {
[view setColors:value];
}
// NOTE: startPoint and endPoint assume that the value is an array with exactly two floats
UM_VIEW_PROPERTY(startPoint, NSArray *, EXLinearGradient) {
CGPoint point = CGPointMake([[value objectAtIndex:0] floatValue], [[value objectAtIndex:1] floatValue]);
[view setStartPoint:point];
}
UM_VIEW_PROPERTY(endPoint, NSArray *, EXLinearGradient) {
CGPoint point = CGPointMake([[value objectAtIndex:0] floatValue], [[value objectAtIndex:1] floatValue]);
[view setEndPoint:point];
}
UM_VIEW_PROPERTY(locations, NSArray *, EXLinearGradient) {
[view setLocations:value];
}
@end

46
node_modules/expo-linear-gradient/package.json generated vendored Normal file
View File

@ -0,0 +1,46 @@
{
"name": "expo-linear-gradient",
"version": "8.4.0",
"description": "Provides a React component that renders a gradient view.",
"main": "build/LinearGradient.js",
"types": "build/LinearGradient.d.ts",
"sideEffects": false,
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
"lint": "expo-module lint",
"test": "expo-module test",
"prepare": "expo-module prepare",
"prepublishOnly": "expo-module prepublishOnly",
"expo-module": "expo-module"
},
"keywords": [
"react-native",
"expo",
"gradient"
],
"jest": {
"preset": "expo-module-scripts/enzyme"
},
"repository": {
"type": "git",
"url": "https://github.com/expo/expo.git",
"directory": "packages/expo-linear-gradient"
},
"bugs": {
"url": "https://github.com/expo/expo/issues"
},
"author": "650 Industries, Inc.",
"license": "MIT",
"homepage": "https://docs.expo.io/versions/latest/sdk/linear-gradient/",
"unimodulePeerDependencies": {
"@unimodules/core": "*"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
},
"devDependencies": {
"expo-module-scripts": "~1.2.0"
}
}

View File

@ -0,0 +1,87 @@
import * as React from 'react';
import { Platform, processColor, View } from 'react-native';
import NativeLinearGradient from './NativeLinearGradient';
import { NativeLinearGradientPoint } from './NativeLinearGradient.types';
export type LinearGradientPoint = { x: number; y: number } | NativeLinearGradientPoint;
export type LinearGradientProps = {
/**
* An array of colors that represent stops in the gradient. At least two colors are required
* (for a single-color background, use the `style.backgroundColor` prop on a `View` component).
*/
colors: string[];
/**
* An array that contains `number`s ranging from 0 to 1, inclusive, and is the same length as the `colors` property.
* Each number indicates a color-stop location where each respective color should be located.
*
* For example, `[0.5, 0.8]` would render:
* - the first color, solid, from the beginning of the gradient view to 50% through (the middle);
* - a gradient from the first color to the second from the 50% point to the 80% point; and
* - the second color, solid, from the 80% point to the end of the gradient view.
*
* The color-stop locations must be ascending from least to greatest.
*/
locations?: number[] | null;
/**
* An object `{ x: number; y: number }` or array `[x, y]` that represents the point
* at which the gradient starts, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.
*
* For example, `{ x: 0.1, y: 0.2 }` means that the gradient will start `10%` from the left and `20%` from the top.
*
* **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the starting position.
*/
start?: LinearGradientPoint | null;
/**
* An object `{ x: number; y: number }` or array `[x, y]` that represents the point
* at which the gradient ends, as a fraction of the overall size of the gradient ranging from 0 to 1, inclusive.
*
* For example, `{ x: 0.1, y: 0.2 }` means that the gradient will end `10%` from the left and `20%` from the bottom.
*
* **On web**, this only changes the angle of the gradient because CSS gradients don't support changing the end position.
*/
end?: LinearGradientPoint | null;
} & React.ComponentProps<typeof View>;
/**
* Renders a native view that transitions between multiple colors in a linear direction.
*/
export class LinearGradient extends React.Component<LinearGradientProps> {
render() {
const { colors, locations, start, end, ...props } = this.props;
let resolvedLocations = locations;
if (locations && colors.length !== locations.length) {
console.warn('LinearGradient colors and locations props should be arrays of the same length');
resolvedLocations = locations.slice(0, colors.length);
}
return (
<NativeLinearGradient
{...props}
colors={Platform.select({
web: colors as any,
default: colors.map(processColor),
})}
locations={resolvedLocations}
startPoint={_normalizePoint(start)}
endPoint={_normalizePoint(end)}
/>
);
}
}
function _normalizePoint(
point: LinearGradientPoint | null | undefined
): [number, number] | undefined {
if (!point) {
return undefined;
}
if (Array.isArray(point) && point.length !== 2) {
console.warn('start and end props for LinearGradient must be of the format [x,y] or {x, y}');
return undefined;
}
return Array.isArray(point) ? point : [point.x, point.y];
}

View File

@ -0,0 +1,49 @@
import { requireNativeViewManager } from '@unimodules/core';
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
export default function NativeLinearGradient({
colors,
locations,
startPoint,
endPoint,
children,
style,
...props
}: NativeLinearGradientProps): React.ReactElement {
// TODO: revisit whether we need to inherit the container's borderRadius since this issue has
// been resolved: https://github.com/facebook/react-native/issues/3198
const flatStyle = StyleSheet.flatten(style) ?? {};
const borderRadius = flatStyle.borderRadius ?? 0;
// This is the format from:
// https://developer.android.com/reference/android/graphics/Path.html#addRoundRect(android.graphics.RectF,%20float[],%20android.graphics.Path.Direction)
const borderRadiiPerCorner = [
flatStyle.borderTopLeftRadius ?? borderRadius,
flatStyle.borderTopLeftRadius ?? borderRadius,
flatStyle.borderTopRightRadius ?? borderRadius,
flatStyle.borderTopRightRadius ?? borderRadius,
flatStyle.borderBottomRightRadius ?? borderRadius,
flatStyle.borderBottomRightRadius ?? borderRadius,
flatStyle.borderBottomLeftRadius ?? borderRadius,
flatStyle.borderBottomLeftRadius ?? borderRadius,
];
return (
<View {...props} style={style}>
<BaseNativeLinearGradient
style={StyleSheet.absoluteFill}
colors={colors}
startPoint={startPoint}
endPoint={endPoint}
locations={locations}
borderRadii={borderRadiiPerCorner}
/>
{children}
</View>
);
}
const BaseNativeLinearGradient = requireNativeViewManager('ExpoLinearGradient');

View File

@ -0,0 +1,10 @@
import { requireNativeViewManager } from '@unimodules/core';
import * as React from 'react';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
const NativeLinearGradient = requireNativeViewManager('ExpoLinearGradient') as React.FC<
NativeLinearGradientProps
>;
export default NativeLinearGradient;

View File

@ -0,0 +1,12 @@
import * as React from 'react';
import { View } from 'react-native';
import { NativeLinearGradientProps } from './NativeLinearGradient.types';
// This is a shim view for platforms that aren't supported by Expo.
// The component and prop types should match all of the other platform variations.
export default function NativeLinearGradient(props: NativeLinearGradientProps): React.ReactElement {
const { colors, locations, startPoint, endPoint, ...viewProps } = props;
console.warn('LinearGradient is not available on this platform');
return <View {...(viewProps as any)} />;
}

View File

@ -0,0 +1,12 @@
import * as React from 'react';
import { View } from 'react-native';
export type NativeLinearGradientProps = React.ComponentProps<typeof View> &
React.PropsWithChildren<{
colors: number[];
locations?: number[] | null;
startPoint?: NativeLinearGradientPoint | null;
endPoint?: NativeLinearGradientPoint | null;
}>;
export type NativeLinearGradientPoint = [number, number];

View File

@ -0,0 +1,96 @@
import * as React from 'react';
import { LayoutRectangle, View } from 'react-native';
import normalizeColor from 'react-native-web/src/modules/normalizeColor';
import { NativeLinearGradientPoint, NativeLinearGradientProps } from './NativeLinearGradient.types';
export default function NativeLinearGradient({
colors,
locations,
startPoint,
endPoint,
...props
}: NativeLinearGradientProps): React.ReactElement {
const [layout, setLayout] = React.useState<LayoutRectangle | null>(null);
const [gradientColors, setGradientColors] = React.useState<string[]>([]);
const [pseudoAngle, setPseudoAngle] = React.useState<number>(0);
const { width = 1, height = 1 } = layout ?? {};
React.useEffect(() => {
const getControlPoints = (): NativeLinearGradientPoint[] => {
let correctedStartPoint: NativeLinearGradientPoint = [0, 0];
if (Array.isArray(startPoint)) {
correctedStartPoint = [
startPoint[0] != null ? startPoint[0] : 0.0,
startPoint[1] != null ? startPoint[1] : 0.0,
];
}
let correctedEndPoint: NativeLinearGradientPoint = [0.0, 1.0];
if (Array.isArray(endPoint)) {
correctedEndPoint = [
endPoint[0] != null ? endPoint[0] : 0.0,
endPoint[1] != null ? endPoint[1] : 1.0,
];
}
return [correctedStartPoint, correctedEndPoint];
};
const [start, end] = getControlPoints();
start[0] *= width;
end[0] *= width;
start[1] *= height;
end[1] *= height;
const py = end[1] - start[1];
const px = end[0] - start[0];
setPseudoAngle(90 + (Math.atan2(py, px) * 180) / Math.PI);
}, [width, height, startPoint, endPoint]);
React.useEffect(() => {
const nextGradientColors = colors.map((color: number, index: number): string => {
const hexColor = normalizeColor(color);
let output = hexColor;
if (locations && locations[index]) {
const location = Math.max(0, Math.min(1, locations[index]));
// Convert 0...1 to 0...100
const percentage = location * 100;
output += ` ${percentage}%`;
}
return output;
});
setGradientColors(nextGradientColors);
}, [colors, locations]);
const colorStyle = gradientColors.join(',');
const backgroundImage = `linear-gradient(${pseudoAngle}deg, ${colorStyle})`;
// TODO(Bacon): In the future we could consider adding `backgroundRepeat: "no-repeat"`. For more
// browser support.
return (
<View
{...props}
style={[
props.style,
// @ts-ignore: [ts] Property 'backgroundImage' does not exist on type 'ViewStyle'.
{ backgroundImage },
]}
onLayout={event => {
const { x, y, width, height } = event.nativeEvent.layout;
const oldLayout = layout ?? { x: 0, y: 0, width: 1, height: 1 };
// don't set new layout state unless the layout has actually changed
if (
x !== oldLayout.x ||
y !== oldLayout.y ||
width !== oldLayout.width ||
height !== oldLayout.height
) {
setLayout({ x, y, width, height });
}
if (props.onLayout) {
props.onLayout(event);
}
}}
/>
);
}

9
node_modules/expo-linear-gradient/tsconfig.json generated vendored Normal file
View File

@ -0,0 +1,9 @@
// @generated by expo-module-scripts
{
"extends": "expo-module-scripts/tsconfig.base",
"compilerOptions": {
"outDir": "./build"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}

4
node_modules/expo-linear-gradient/unimodule.json generated vendored Normal file
View File

@ -0,0 +1,4 @@
{
"name": "expo-linear-gradient",
"platforms": ["ios", "android"]
}