├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── example.gif
├── example
├── App.js
├── app.json
├── assets
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
├── babel.config.js
├── package.json
├── src
│ └── ShimmerPlaceholder.js
└── yarn.lock
├── facebook-load-data.gif
├── index.d.ts
├── lib
└── ShimmerPlaceholder.js
├── package.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 |
55 | # Bundle artifacts
56 | *.jsbundle
57 |
58 | # CocoaPods
59 | /ios/Pods/
60 |
61 | # Expo
62 | .expo/*
63 | web-build/
64 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 | example/
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.keystore
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | */fastlane/report.xml
52 | */fastlane/Preview.html
53 | */fastlane/screenshots
54 | example.gif
55 | facebook-load-data.gif
56 | LICENSE
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 tomzaku
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | React Native Shimmer Placeholder
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Placeholder for both IOS and Android
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 | ## Get Started
22 | 
23 |
24 | ### Installation
25 |
26 | `npm i react-native-shimmer-placeholder --save`
27 |
28 | or
29 |
30 | `yarn add react-native-shimmer-placeholder`
31 |
32 |
33 | ### Usage
34 |
35 | #### Simple
36 |
37 | For `expo`
38 | ``` jsx
39 | import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
40 | import { LinearGradient } from 'expo-linear-gradient';
41 |
42 | const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient)
43 |
44 |
45 |
46 |
47 | Wow, awesome here.
48 |
49 |
50 | ```
51 |
52 | or
53 |
54 | ``` jsx
55 | import ShimmerPlaceHolder from 'react-native-shimmer-placeholder'
56 | import { LinearGradient } from 'expo-linear-gradient';
57 |
58 |
59 |
60 |
61 |
62 | Wow, awesome here.
63 |
64 |
65 | ```
66 |
67 | For `react-native-linear-gradient`
68 | ``` jsx
69 | import LinearGradient from 'react-native-linear-gradient';
70 | import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
71 |
72 | const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient)
73 |
74 | ...
75 |
76 |
77 | ```
78 | or
79 | ```jsx
80 | import LinearGradient from 'react-native-linear-gradient';
81 | import ShimmerPlaceHolder from 'react-native-shimmer-placeholder'
82 |
83 | ...
84 |
85 |
88 | ```
89 |
90 | #### Connect more components
91 |
92 |
93 |
94 |
95 |
96 | ```jsx
97 | import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
98 | import LinearGradient from 'react-native-linear-gradient';
99 |
100 | const ShimmerPlaceholder = createShimmerPlaceholder(LinearGradient)
101 | const FacebookContent = () => {
102 |
103 | // Handle animation
104 | const avatarRef = React.createRef()
105 | const firstLineRef = React.createRef()
106 | const secondLineRef = React.createRef()
107 | const thirdLineRef = React.createRef()
108 |
109 | React.useEffect(() => {
110 | const facebookAnimated = Animated.stagger(
111 | 400,
112 | [
113 | avatarRef.current.getAnimated(),
114 | Animated.parallel([
115 | firstLineRef.current.getAnimated(),
116 | secondLineRef.current.getAnimated(),
117 | thirdLineRef.current.getAnimated()
118 | ])
119 | ]
120 | );
121 | Animated.loop(facebookAnimated).start();
122 | }, [])
123 |
124 | return (
125 |
126 |
127 |
131 |
132 |
136 |
140 |
144 |
145 |
146 |
147 | )
148 | }
149 | ```
150 |
151 | More Detail see [this](https://github.com/tomzaku/react-native-shimmer-placeholder/blob/master/example/App.js)
152 |
153 | ### Props
154 |
155 | | Prop | Description | Type | Default |
156 | | ---------------------------- | ------------------------------------------------------------------------------------------------------ | --------- | ------------------------------------------------- |
157 | | **`LinearGradient`** | Linear Gradient components ('react-native-linear-gradient' or 'expo-linear-gradient') | Component | undefined |
158 | | **`visible`** | Visible child components | boolean | false |
159 | | **`style`** | Container Style | Style | `{backgroundColor: '#ebebeb',overflow: 'hidden'}` |
160 | | **`shimmerStyle`** | Shimmer Style only | Style | {} |
161 | | **`contentStyle`** | Content Style when visible | Style | {} |
162 | | **`location`** | Locations of shimmer | number[] | *[0.3, 0.5, 0.7]* |
163 | | **`width`** | Width of row | number | 200 |
164 | | **`duration`** | Duration of shimmer over a row | number | 1000 |
165 | | **`height`** | Height of row | number | 15 |
166 | | **`shimmerWidthPercent`** | Percent of shimmer width | number | 1.0 |
167 | | **`isReversed`** | Reverse direction of animation | boolean | `false` |
168 | | **`stopAutoRun`** | Stop running shimmer animation at beginning | boolean | `false` |
169 | | **`isInteraction`** | Defines whether or not the shimmer animation creates an interaction handle on the `InteractionManager` | boolean | `true` |
170 | | **`shimmerColors`** | Colors of the shimmer. | string[] | *['#ebebeb', '#c5c5c5', '#ebebeb']* |
171 | | **`containerProps`** | Props passed to the outermost View | ViewProps | undefined |
172 | | **`shimmerContainerProps`** | Props passed to the View which contains the loading animation | ViewProps | undefined |
173 | | **`childrenContainerProps`** | Props passed to the View which contains the children | ViewProps | undefined |
174 |
175 | ### Methods
176 | | Method | Description | Type |
177 | | ----------------- | --------------------------- | -------- |
178 | | **`getAnimated`** | get Animated of Placeholder | Animated |
179 |
180 | ### Helpers
181 |
182 | `createShimmerPlaceholder`
183 |
184 | ```
185 | /**
186 | * To create ShimmerPlaceholder by Linear Gradient. Only useful when you use 3rd party,
187 | * For example: react-native-linear-gradient
188 | * @param {Linear Gradient Component} LinearGradient - 'expo-linear-gradient' by default
189 | *
190 | * @example
191 | *
192 | * import LinearGradient from 'react-native-linear-gradient';
193 | * import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
194 | *
195 | * const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient)
196 | *
197 | * ...
198 | *
199 | *
200 | */
201 | ```
202 |
203 | ### Contribute
204 |
205 | Welcome help me to build this awesome lib.
206 |
207 | ### License
208 |
209 | [MIT](https://github.com/tomzaku/react-native-shimmer-placeholder/blob/master/LICENSE)
210 |
--------------------------------------------------------------------------------
/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomzaku/react-native-shimmer-placeholder/578a2ec95dc84cf22842291b145d4240aa490c66/example.gif
--------------------------------------------------------------------------------
/example/App.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import React, { PureComponent, Component } from 'react';
4 | import { View, Text, StyleSheet, Animated, Image, ScrollView, FlatList } from 'react-native';
5 | import { LinearGradient } from 'expo-linear-gradient';
6 | import ShimmerPlaceholder from './src/ShimmerPlaceholder'
7 |
8 | const FacebookContent = ({ isReversed, shimmerColors, hasData, hasBorder, randomWidth }) => {
9 | // Handle visible
10 | const [visible, setVisible] = React.useState(false)
11 | const [avatarVisible, setAvatarVisible] = React.useState(false)
12 | React.useEffect(() => {
13 | setTimeout(() => {
14 | hasData && setVisible(true)
15 | }, 2000)
16 | }, [])
17 |
18 | // Handle animation
19 | const avatarRef = React.createRef()
20 | const firstLineRef = React.createRef()
21 | const secondLineRef = React.createRef()
22 | const thirdLineRef = React.createRef()
23 |
24 | React.useEffect(() => {
25 | const facebookAnimated = Animated.stagger(400, [avatarRef.current.getAnimated(), Animated.parallel([
26 | firstLineRef.current.getAnimated(),
27 | secondLineRef.current.getAnimated(),
28 | thirdLineRef.current.getAnimated()
29 | ])])
30 | Animated.loop(facebookAnimated).start();
31 | }, [])
32 |
33 | return (
34 |
35 |
36 |
46 | {hasData && setAvatarVisible(true)}
50 | />}
51 |
52 |
53 |
63 |
64 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy
65 |
66 |
67 |
76 |
85 |
86 |
87 |
88 | )
89 | }
90 |
91 |
92 |
93 | export default () => {
94 | const [visible, setVisible] = React.useState(false)
95 | const [avatarVisible, setAvatarVisible] = React.useState(false)
96 | React.useEffect(() => {
97 | setTimeout(() => {
98 | setVisible(true)
99 | }, 2000)
100 | }, [])
101 | return (
102 |
103 | React Native Shimmer Placeholder
104 | Simple
105 |
108 | Avatar
109 |
115 | setAvatarVisible(true)}
119 | />
120 |
121 | Load text data
122 |
127 |
128 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy
129 |
130 |
131 |
136 |
141 |
142 | Facebook
143 |
144 | Facebook - color
145 |
146 | Facebook - load data
147 |
148 | Facebook - Reverse
149 |
150 |
151 |
152 | )
153 | }
154 |
155 | const styles = StyleSheet.create({
156 | container: {
157 | flex: 1,
158 | padding: 16,
159 | marginTop: 60,
160 |
161 | },
162 | title: {
163 | fontSize: 20,
164 | marginBottom: 12,
165 | fontWeight: "600",
166 | textAlign: "center",
167 | },
168 | sessionTitle: {
169 | fontSize: 16,
170 | marginTop: 20,
171 | marginBottom: 6,
172 | fontWeight: "600"
173 | }
174 | });
175 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "expoShimmer",
4 | "slug": "expoShimmer",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "splash": {
9 | "image": "./assets/splash.png",
10 | "resizeMode": "contain",
11 | "backgroundColor": "#ffffff"
12 | },
13 | "updates": {
14 | "fallbackToCacheTimeout": 0
15 | },
16 | "assetBundlePatterns": [
17 | "**/*"
18 | ],
19 | "ios": {
20 | "supportsTablet": true
21 | },
22 | "web": {
23 | "favicon": "./assets/favicon.png"
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/example/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomzaku/react-native-shimmer-placeholder/578a2ec95dc84cf22842291b145d4240aa490c66/example/assets/favicon.png
--------------------------------------------------------------------------------
/example/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomzaku/react-native-shimmer-placeholder/578a2ec95dc84cf22842291b145d4240aa490c66/example/assets/icon.png
--------------------------------------------------------------------------------
/example/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomzaku/react-native-shimmer-placeholder/578a2ec95dc84cf22842291b145d4240aa490c66/example/assets/splash.png
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "expo": "~38.0.8",
12 | "expo-linear-gradient": "~8.2.1",
13 | "expo-status-bar": "^1.0.2",
14 | "react": "~16.11.0",
15 | "react-dom": "~16.11.0",
16 | "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
17 | "react-native-web": "~0.11.7"
18 | },
19 | "devDependencies": {
20 | "@babel/core": "^7.8.6",
21 | "babel-preset-expo": "~8.1.0"
22 | },
23 | "private": true
24 | }
25 |
--------------------------------------------------------------------------------
/example/src/ShimmerPlaceholder.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import { Animated, Platform, StyleSheet, View } from "react-native";
3 |
4 | const getOutputRange = (width, isReversed) => isReversed ? [width, -width] : [-width, width]
5 |
6 | class ShimmerPlaceholder extends PureComponent {
7 | state = {
8 | beginShimmerPosition: new Animated.Value(-1)
9 | }
10 | getAnimated = () => {
11 | const { delay, duration, isInteraction } = this.props
12 | return Animated.loop(Animated.timing(this.state.beginShimmerPosition, {
13 | toValue: 1,
14 | delay,
15 | duration,
16 | useNativeDriver: true,
17 | isInteraction
18 | }))
19 | }
20 | animatedValue = this.getAnimated()
21 |
22 | render() {
23 | return (
24 |
25 | )
26 | }
27 | }
28 |
29 | ShimmerPlaceholder.defaultProps = {
30 | delay: 0,
31 | duration: 1000,
32 | isInteraction: true
33 | }
34 |
35 | const BasedShimmerPlaceholder = (props) => {
36 | const {
37 | width = 200,
38 | height = 15,
39 | duration = 1000,
40 | delay = 0,
41 | shimmerColors = ["#ebebeb", "#c5c5c5", "#ebebeb"],
42 | isReversed = false,
43 | stopAutoRun = false,
44 | visible,
45 | location = [0.3, 0.5, 0.7],
46 | style,
47 | contentStyle,
48 | shimmerStyle,
49 | isInteraction = true,
50 | LinearGradient = global.Expo
51 | ? global.Expo.LinearGradient
52 | : View,
53 | children,
54 | animatedValue,
55 | beginShimmerPosition,
56 | shimmerWidthPercent = 1,
57 | } = props
58 |
59 | const linearTranslate = beginShimmerPosition.interpolate({
60 | inputRange: [-1, 1],
61 | outputRange: getOutputRange(width, isReversed)
62 | });
63 |
64 | React.useEffect(() => {
65 | if (!stopAutoRun) {
66 | animatedValue.start()
67 | }
68 | return () => {
69 | animatedValue.stop()
70 | }
71 | }, [stopAutoRun])
72 |
73 | React.useEffect(() => {
74 | if (visible) {
75 | animatedValue.stop()
76 | }
77 | if (!visible && !stopAutoRun) {
78 | animatedValue.start()
79 | }
80 | }, [visible, stopAutoRun])
81 |
82 | return (
83 |
86 | {/* Force render children to restrict rendering twice */}
87 | {children}
88 | {
89 | !visible && (
90 |
91 |
94 |
107 |
108 |
109 |
110 | )
111 | }
112 |
113 | )
114 | }
115 |
116 | const styles = StyleSheet.create({
117 | container: {
118 | overflow: "hidden"
119 | },
120 |
121 | });
122 |
123 | /**
124 | * To create ShimmerPlaceholder by Linear Gradient. Only useful when you use 3rd party,
125 | * For example: react-native-linear-gradient
126 | * @param {Linear Gradient Component} LinearGradient - 'expo-linear-gradient' by default
127 | *
128 | * @example
129 | *
130 | * import LinearGradient from 'react-native-linear-gradient';
131 | * import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
132 | *
133 | * const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient)
134 | *
135 | * ...
136 | *
137 | *
138 | */
139 | export const createShimmerPlaceholder = (LinearGradient = global.Expo
140 | ? global.Expo.LinearGradient
141 | : View) => React.forwardRef((props, ref) => )
142 |
143 | export default ShimmerPlaceholder
--------------------------------------------------------------------------------
/facebook-load-data.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomzaku/react-native-shimmer-placeholder/578a2ec95dc84cf22842291b145d4240aa490c66/facebook-load-data.gif
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'react-native-shimmer-placeholder' {
2 |
3 | import * as React from 'react';
4 | import { Animated, ViewProps } from 'react-native';
5 |
6 | export interface ShimmerPlaceholderProps {
7 | width?: number | string;
8 | height?: number | string;
9 | shimmerWidthPercent?: number;
10 | duration?: number;
11 | delay?: number;
12 | shimmerColors?: string[];
13 | location?: number[];
14 | isReversed?: boolean;
15 | stopAutoRun?: boolean;
16 | visible?: boolean;
17 | children?: any;
18 | style?: any;
19 | shimmerStyle?: any;
20 | contentStyle?: any;
21 | isInteraction?: boolean;
22 | LinearGradient?: React.ComponentClass;
23 | containerProps?: ViewProps
24 | shimmerContainerProps?: ViewProps
25 | childrenContainerProps?: ViewProps
26 | }
27 |
28 | class ShimmerPlaceholder extends React.Component {
29 | getAnimated(): Animated.CompositeAnimation;
30 | }
31 |
32 | export const createShimmerPlaceholder = (LinearGradient?: React.ComponentClass) => ShimmerPlaceholder
33 |
34 | export default ShimmerPlaceholder
35 | }
--------------------------------------------------------------------------------
/lib/ShimmerPlaceholder.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from "react";
2 | import { Animated, Platform, StyleSheet, View } from "react-native";
3 |
4 | const getOutputRange = (width, isReversed) =>
5 | isReversed ? [width, -width] : [-width, width];
6 |
7 | class ShimmerPlaceholder extends PureComponent {
8 | state = {
9 | beginShimmerPosition: new Animated.Value(-1),
10 | };
11 | getAnimated = () => {
12 | const { delay, duration, isInteraction } = this.props;
13 | return Animated.loop(
14 | Animated.timing(this.state.beginShimmerPosition, {
15 | toValue: 1,
16 | delay,
17 | duration,
18 | useNativeDriver: Platform.OS !== "web",
19 | isInteraction,
20 | })
21 | );
22 | };
23 | animatedValue = this.getAnimated();
24 |
25 | render() {
26 | return (
27 |
32 | );
33 | }
34 | }
35 |
36 | ShimmerPlaceholder.defaultProps = {
37 | delay: 0,
38 | duration: 1000,
39 | isInteraction: true,
40 | };
41 |
42 | const BasedShimmerPlaceholder = (props) => {
43 | const {
44 | width = 200,
45 | height = 15,
46 | shimmerColors = ["#ebebeb", "#c5c5c5", "#ebebeb"],
47 | isReversed = false,
48 | stopAutoRun = false,
49 | visible,
50 | location = [0.3, 0.5, 0.7],
51 | style,
52 | contentStyle,
53 | shimmerStyle,
54 | LinearGradient = View,
55 | children,
56 | animatedValue,
57 | beginShimmerPosition,
58 | shimmerWidthPercent = 1,
59 | containerProps,
60 | shimmerContainerProps,
61 | childrenContainerProps,
62 | } = props;
63 |
64 | const linearTranslate = beginShimmerPosition.interpolate({
65 | inputRange: [-1, 1],
66 | outputRange: getOutputRange(width, isReversed),
67 | });
68 |
69 | React.useEffect(() => {
70 | if (!stopAutoRun) {
71 | animatedValue.start();
72 | }
73 | return () => {
74 | animatedValue.stop();
75 | };
76 | }, [stopAutoRun]);
77 |
78 | React.useEffect(() => {
79 | if (visible) {
80 | animatedValue.stop();
81 | }
82 | if (!visible && !stopAutoRun) {
83 | animatedValue.start();
84 | }
85 | }, [visible, stopAutoRun]);
86 |
87 | return (
88 |
97 | {/* Force render children to restrict rendering twice */}
98 |
105 | {children}
106 |
107 | {!visible && (
108 |
112 |
115 |
128 |
129 |
130 | )}
131 |
132 | );
133 | };
134 |
135 | const styles = StyleSheet.create({
136 | container: {
137 | overflow: "hidden",
138 | },
139 | });
140 |
141 | /**
142 | * To create ShimmerPlaceholder by Linear Gradient. Only useful when you use 3rd party,
143 | * For example: react-native-linear-gradient
144 | * @param {Linear Gradient Component} LinearGradient - 'expo-linear-gradient' by default
145 | *
146 | * @example
147 | *
148 | * import LinearGradient from 'react-native-linear-gradient';
149 | * import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder'
150 | *
151 | * const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient)
152 | *
153 | * ...
154 | *
155 | *
156 | */
157 | export const createShimmerPlaceholder = (LinearGradient = View) =>
158 | React.forwardRef((props, ref) => (
159 |
160 | ));
161 |
162 | export default ShimmerPlaceholder;
163 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-shimmer-placeholder",
3 | "version": "2.0.8",
4 | "author": "Zaku",
5 | "bugs": {
6 | "url": "https://github.com/tomzaku/react-native-shimmer-placeholder/issues"
7 | },
8 | "directories": {
9 | "example": "example"
10 | },
11 | "homepage": "https://github.com/tomzaku/react-native-shimmer-placeholder#readme",
12 | "keywords": [
13 | "loading",
14 | "placeholder",
15 | "react-native",
16 | "shimmer"
17 | ],
18 | "license": "MIT",
19 | "main": "./lib/ShimmerPlaceholder.js",
20 | "peerDependencies": {
21 | "prop-types": ">=15.6.0",
22 | "react-native-linear-gradient": ">=2.4.0"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git+https://github.com/tomzaku/react-native-shimmer-placeholder.git"
27 | },
28 | "scripts": {
29 | "test": "echo \"Error: no test specified\" "
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------