Skip to content

Commit

Permalink
Merge pull request #17 from chramos/version3.0
Browse files Browse the repository at this point in the history
New lib version
  • Loading branch information
chramos authored Nov 13, 2020
2 parents 2516631 + 1fad1a9 commit 4c21555
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 32 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ SkeletonPlaceholder is a React Native library to easily create an amazing loadin

![](https://i.imgur.com/3aDeSTZ.gif)

<div style="background-color:#84d2ef80; padding: 20px; border-radius: 4px; color: #14485b">This package includes the dependency **react-native-linear-gradient**
<div style="background-color:#84d2ef80; padding: 20px; border-radius: 4px; color: #14485b">This package includes the dependency **@react-native-masked-view/masked-view**
</div>

### Installation

> Note: If your project already includes the **react-native-linear-gradient** you can skip the Step #1
> Note: If your project already includes the **@react-native-masked-view/masked-view** you can skip the Step #1

###### Step #1

Using yarn:

```bash
yarn add react-native-linear-gradient
yarn add @react-native-masked-view/masked-view
```

Using npm:

```bash
npm install react-native-linear-gradient --save
npm install @react-native-masked-view/masked-view --save
```

If you are running a **react-native** version below 0.60:

```bash
react-native link react-native-linear-gradient
react-native link @react-native-masked-view/masked-view
```

Otherwise:
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-skeleton-placeholder",
"version": "2.0.11",
"version": "3.0.0",
"description": "SkeletonPlaceholder is a React Native library to easily create an amazing loading effect.",
"main": "lib/SkeletonPlaceholder.js",
"scripts": {
Expand All @@ -20,14 +20,15 @@
"author": "Henrique Ramos <[email protected]> (https://github.com/chramos)",
"license": "ISC",
"devDependencies": {
"@react-native-masked-view/masked-view": "^0.2.0",
"@types/prop-types": "^15.7.3",
"@types/react": "^16.9.17",
"@types/react-native": "^0.63.17",
"react": "^16.13.1",
"react-native": "^0.63.2",
"typescript": "^4.0.2"
},
"peerDependencies": {
"react-native-linear-gradient": "^2.5.6"
"@react-native-masked-view/masked-view": ">=2.5.0",
"react": ">=0.14.8",
"react-native": ">=0.50.1"
}
}
95 changes: 72 additions & 23 deletions src/SkeletonPlaceholder.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import * as React from "react";
import { Animated, View, StyleSheet, Easing, ViewStyle } from "react-native";
import LinearGradient from "react-native-linear-gradient";
import {
Animated,
View,
StyleSheet,
Easing,
ViewStyle,
Dimensions,
} from "react-native";
import MaskedView from "@react-native-masked-view/masked-view";

const GRADIENT_START = { x: 0, y: 0 };
const GRADIENT_END = { x: 1, y: 0 };
const SCREEN_WIDTH = Dimensions.get("window").width;

interface SkeletonPlaceholderProps {
/**
Expand All @@ -30,12 +36,13 @@ export default function SkeletonPlaceholder({
speed = 800,
highlightColor = "#F2F8FC",
}: SkeletonPlaceholderProps): JSX.Element {
const [maskHeight, setMaskHeight] = React.useState<number>();
const animatedValue = React.useMemo(() => new Animated.Value(0), []);
const translateX = React.useMemo(
() =>
animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [-350, 350],
outputRange: [-SCREEN_WIDTH, SCREEN_WIDTH],
}),
[animatedValue]
);
Expand All @@ -49,18 +56,16 @@ export default function SkeletonPlaceholder({
useNativeDriver: true,
})
);
loop.start();
if (maskHeight) {
loop.start();
}
return () => loop.stop();
}, [animatedValue, speed]);
}, [animatedValue, speed, maskHeight]);

const absoluteTranslateStyle = React.useMemo(
() => ({ ...StyleSheet.absoluteFillObject, transform: [{ translateX }] }),
[translateX]
);
const gradientColors = React.useMemo(
() => [backgroundColor, highlightColor, backgroundColor],
[backgroundColor, highlightColor]
);
const viewStyle = React.useMemo<ViewStyle>(
() => ({ backgroundColor, overflow: "hidden" }),
[backgroundColor]
Expand All @@ -87,26 +92,70 @@ export default function SkeletonPlaceholder({
} else {
return (
<View key={index} style={styles.childContainer}>
<View style={[style, viewStyle]}>
<Animated.View style={absoluteTranslateStyle}>
<LinearGradient
colors={gradientColors}
start={GRADIENT_START}
end={GRADIENT_END}
style={styles.gradient}
/>
</Animated.View>
</View>
<View style={[style, viewStyle]} />
</View>
);
}
}
);
},
[viewStyle, absoluteTranslateStyle, gradientColors]
[viewStyle]
);

return <React.Fragment>{getChildren(children)}</React.Fragment>;
return React.useMemo(
() =>
maskHeight ? (
<MaskedView
style={{ height: maskHeight }}
maskElement={
<View
style={{
backgroundColor: "transparent",
}}
>
{getChildren(children)}
</View>
}
>
<View style={{ flexGrow: 1, backgroundColor }} />
<Animated.View
style={[
{
flexDirection: "row",
},
absoluteTranslateStyle,
]}
>
{Array.from({ length: SCREEN_WIDTH }).map((_, index) => {
const opacity = new Animated.Value(index);
return (
<Animated.View
key={index}
style={{
width: 1,
opacity: opacity.interpolate({
inputRange: [0, SCREEN_WIDTH / 2, SCREEN_WIDTH],
outputRange: [0, 1, 0],
}),

backgroundColor: highlightColor,
}}
/>
);
})}
</Animated.View>
</MaskedView>
) : (
<View
onLayout={(event) => {
setMaskHeight(event.nativeEvent.layout.height);
}}
>
{getChildren(children)}
</View>
),
[maskHeight]
);
}

interface SkeletonPlaceholderItem extends ViewStyle {
Expand Down
38 changes: 38 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@react-native-masked-view/masked-view@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.2.0.tgz#3309ada28dafd7ac1fead4eb99286acd43180b2a"
integrity sha512-OXYHN8lRvqLHPM2qB4wagcV1thCzR/PmFaJPOIsq+KU7PBmB0CY5DaC5WCPbyzGP8X9ehVmmK/yWlew3GJIgnQ==

"@types/prop-types@*", "@types/prop-types@^15.7.3":
version "15.7.3"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==

"@types/react-native@^0.63.17":
version "0.63.34"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.34.tgz#745270747308a09266eb061d9e1423d365670396"
integrity sha512-6syTIfUt+DY4mJBoO0Y5i4jsDg0I7v31XIPRgsJZAlHeMY9p9GehtGd4VpQKB/NgzLiGzx9ahJPE8w+0lt/WxA==
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@^16.9.17":
version "16.9.56"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.56.tgz#ea25847b53c5bec064933095fc366b1462e2adf0"
integrity sha512-gIkl4J44G/qxbuC6r2Xh+D3CGZpJ+NdWTItAPmZbR5mUS+JQ8Zvzpl0ea5qT/ZT3ZNTUcDKUVqV3xBE8wv/DyQ==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

csstype@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8"
integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==

typescript@^4.0.2:
version "4.0.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389"
integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==

0 comments on commit 4c21555

Please sign in to comment.