Skip to content

Commit fa3cc8e

Browse files
committed
chore: update example
1 parent 75cc839 commit fa3cc8e

File tree

7 files changed

+113
-27
lines changed

7 files changed

+113
-27
lines changed

example/app/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function App() {
1919
return (
2020
<ScrollView
2121
style={styles.container}
22-
contentContainerStyle={{ paddingTop: top, paddingBottom: bottom }}
22+
contentContainerStyle={{ paddingTop: top, paddingBottom: bottom + 16 }}
2323
>
2424
<Stack.Screen options={{ headerShown: false }} />
2525
<View style={styles.row}>

example/components/blocks/Blocks.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export function Blocks({ horizontal }: { horizontal?: boolean }) {
5454
<View
5555
key={`column-${index}`}
5656
style={[
57-
{ flexDirection: 'row' },
57+
styles.container,
5858
index % 2 === 0 ? styles.offsetHorizontal : {},
5959
]}
6060
>

example/components/blocks/ImageBlock.tsx

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import React, { ComponentProps, useState } from 'react';
2-
import {
3-
ActivityIndicator,
4-
Image,
5-
ImageSourcePropType,
6-
StyleSheet,
7-
Text,
8-
View,
9-
} from 'react-native';
2+
import { Image, ImageSourcePropType, StyleSheet, View } from 'react-native';
103
import { LazyChild } from 'react-native-lazy-scrollview';
114
import { SQUARE_SIZE } from '../../constants';
5+
import { Skeleton } from '../loaders/Skeleton';
126

137
interface Props extends Omit<ComponentProps<typeof LazyChild>, 'children'> {
148
source: ImageSourcePropType;
@@ -44,17 +38,11 @@ export function ImageBlock({ source, ...rest }: Props) {
4438
{...rest}
4539
>
4640
<View style={styles.contentContainer}>
47-
{triggered ? (
41+
<Skeleton show={!triggered}>
4842
<Image source={source} style={styles.image} />
49-
) : (
50-
<ActivityIndicator />
51-
)}
43+
</Skeleton>
5244
{!isVisible && rest.percentVisibleThreshold ? (
53-
<View style={styles.percentTextWrapper}>
54-
<Text style={styles.percentText}>{`${
55-
rest.percentVisibleThreshold * 100
56-
} not visible`}</Text>
57-
</View>
45+
<View style={styles.percentTextWrapper}></View>
5846
) : null}
5947
</View>
6048
</LazyChild>
@@ -94,10 +82,4 @@ const styles = StyleSheet.create({
9482
justifyContent: 'center',
9583
alignItems: 'center',
9684
},
97-
percentText: {
98-
color: 'red',
99-
fontSize: 16,
100-
padding: 8,
101-
textAlign: 'center',
102-
},
10385
});
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React, { ReactElement } from 'react';
2+
import { View, StyleSheet, LayoutRectangle } from 'react-native';
3+
import MaskedView from '@react-native-masked-view/masked-view';
4+
import { LinearGradient } from 'expo-linear-gradient';
5+
import Reanimated, {
6+
useSharedValue,
7+
withRepeat,
8+
useAnimatedStyle,
9+
withTiming,
10+
interpolate,
11+
} from 'react-native-reanimated';
12+
13+
interface SkeletonProps {
14+
background?: string;
15+
highlight?: string;
16+
children: ReactElement;
17+
show?: boolean;
18+
}
19+
20+
const BaseSkeleton: React.FC<SkeletonProps> = ({
21+
children,
22+
background = '#636e72',
23+
highlight = '#b2bec3',
24+
}) => {
25+
const [layout, setLayout] = React.useState<LayoutRectangle>();
26+
const shared = useSharedValue(0);
27+
28+
const animStyle = useAnimatedStyle(() => {
29+
const x = interpolate(
30+
shared.value,
31+
[0, 1],
32+
[layout ? -layout.width : 0, layout ? layout.width : 0]
33+
);
34+
return {
35+
transform: [{ translateX: x }],
36+
};
37+
});
38+
39+
React.useEffect(() => {
40+
shared.value = withRepeat(withTiming(1, { duration: 1000 }), Infinity);
41+
// eslint-disable-next-line react-hooks/exhaustive-deps
42+
}, []);
43+
44+
if (!layout) {
45+
return (
46+
<View onLayout={(event) => setLayout(event.nativeEvent.layout)}>
47+
{children}
48+
</View>
49+
);
50+
}
51+
52+
return (
53+
<MaskedView
54+
maskElement={children}
55+
style={{ width: layout.width, height: layout.height }}
56+
>
57+
<View style={[styles.container, { backgroundColor: background }]} />
58+
<Reanimated.View style={[StyleSheet.absoluteFill, animStyle]}>
59+
<MaskedView
60+
style={StyleSheet.absoluteFill}
61+
maskElement={
62+
<LinearGradient
63+
start={{ x: 0, y: 0 }}
64+
end={{ x: 1, y: 0 }}
65+
style={StyleSheet.absoluteFill}
66+
colors={['transparent', highlight, 'transparent']}
67+
/>
68+
}
69+
>
70+
<View
71+
style={[StyleSheet.absoluteFill, { backgroundColor: highlight }]}
72+
/>
73+
</MaskedView>
74+
</Reanimated.View>
75+
</MaskedView>
76+
);
77+
};
78+
79+
export const Skeleton = ({ children, show, ...rest }: SkeletonProps) => {
80+
if (!show) {
81+
return children;
82+
}
83+
84+
return <BaseSkeleton {...rest}>{children}</BaseSkeleton>;
85+
};
86+
87+
const styles = StyleSheet.create({
88+
container: {
89+
flexGrow: 1,
90+
overflow: 'hidden',
91+
},
92+
});

example/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const VERTICAL = {
4040
title: 'Vertical Lazy ScrollView',
4141
color: '#1e90ff',
4242
description:
43-
'LazyScrollView with vertical orientation. Offset is set to -50, so threshold triggers will happen 50 points before the top and bottom edges of the scrollview container. Visibility triggers will use the top and bottom edge of the scrollview container.',
43+
'LazyScrollView with vertical orientation. Offset is set to -50. For this example, this means the LazyChild will show a Skeleton until it is 50 points from the top or bottom of the scrollview container (threshold callbacks) and will have a 50% opacity until it is fully visible (visibility callbacks).',
4444
image: require('./assets/vertical.png'),
4545
};
4646

@@ -49,7 +49,7 @@ export const HORIZONTAL = {
4949
title: 'Horizontal Lazy ScrollView',
5050
color: '#7bed9f',
5151
description:
52-
'LazyScrollView with horizontal orientation. Offset is set to -50, so threshold triggers will happen 50 points before the left and right edges of the scrollview container. Visibility triggers will use the left and right edge of the scrollview container.',
52+
'LazyScrollView with horizontal orientation. Offset is set to -50. For these examples, this means the LazyChild will show a Skeleton until it is 50 points from the left or right of the scrollview container (threshold callbacks) and will have a 50% opacity until it is fully visible (visibility callbacks).',
5353
image: require('./assets/horizontal.png'),
5454
};
5555

example/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
"web": "expo start --web"
1010
},
1111
"dependencies": {
12+
"@react-native-masked-view/masked-view": "0.3.1",
1213
"expo": "^51.0.37",
1314
"expo-constants": "~16.0.2",
15+
"expo-linear-gradient": "~13.0.2",
1416
"expo-linking": "~6.3.1",
1517
"expo-router": "~3.5.23",
1618
"expo-status-bar": "~1.12.1",

example/yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,6 +2120,11 @@
21202120
prompts "^2.4.2"
21212121
semver "^7.5.2"
21222122

2123+
"@react-native-masked-view/[email protected]":
2124+
version "0.3.1"
2125+
resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.3.1.tgz#5bd76f17004a6ccbcec03856893777ee91f23d29"
2126+
integrity sha512-uVm8U6nwFIlUd1iDIB5cS+lDadApKR+l8k4k84d9hn+GN4lzAIJhUZ9syYX7c022MxNgAlbxoFLt0pqKoyaAGg==
2127+
21232128
"@react-native/[email protected]":
21242129
version "0.74.87"
21252130
resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.87.tgz#7dda64e48db14597e19e15f679e31abbb1c1fb4d"
@@ -4632,6 +4637,11 @@ expo-keep-awake@~13.0.2:
46324637
resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz#5ef31311a339671eec9921b934fdd90ab9652b0e"
46334638
integrity sha512-kKiwkVg/bY0AJ5q1Pxnm/GvpeB6hbNJhcFsoOWDh2NlpibhCLaHL826KHUM+WsnJRbVRxJ+K9vbPRHEMvFpVyw==
46344639

4640+
expo-linear-gradient@~13.0.2:
4641+
version "13.0.2"
4642+
resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-13.0.2.tgz#21bd7bc7c71ef4f7c089521daa16db729d2aec5f"
4643+
integrity sha512-EDcILUjRKu4P1rtWcwciN6CSyGtH7Bq4ll3oTRV7h3h8oSzSilH1g6z7kTAMlacPBKvMnkkWOGzW6KtgMKEiTg==
4644+
46354645
expo-linking@~6.3.1:
46364646
version "6.3.1"
46374647
resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-6.3.1.tgz#05aef8a42bd310391d0b00644be40d80ece038d9"

0 commit comments

Comments
 (0)