Skip to content

Commit 1973c90

Browse files
authored
Merge pull request #269 from flexbox/fix/bootcamp25
fix: 🐛 SkeletonList now with animated
2 parents 05e176c + 8d533d7 commit 1973c90

File tree

10 files changed

+103
-16484
lines changed

10 files changed

+103
-16484
lines changed

challenges/data/02.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ If you want to display some images on your `Card`, you can use this placeholder
142142

143143
### Advanced
144144

145-
- [ ] Display a nice animated placeholder during loading with [rn-placeholder](https://github.com/mfrachet/rn-placeholder)
145+
- [ ] Display a nice animated placeholder during loading by choosing one of these approaches:
146+
- Option 1: Use [rn-placeholder](https://github.com/mfrachet/rn-placeholder) for quick implementation
147+
- ⚠️ If using npm, install with: `npm install rn-placeholder --legacy-peer-deps` (required due to outdated peer dependencies)
148+
- Option 2: Use [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) to create your own animated placeholder, similar to our [`SkeletonListReanimated`](https://raw.githubusercontent.com/flexbox/react-native-bootcamp/main/hackathon/spacecraft/src/components/SkeletonListReanimated.tsx) component
149+
146150
- [ ] Add a "Pull to Refresh" functionality to your FlatList with `onRefresh`
147151

148152
### Debugging

challenges/foundation/02.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ It is always a good idea to **create small components to your project**. In our
124124

125125
- [ ] Create a new component that takes a title props `<Header title="SpaceCraft"/>`
126126

127-
**🔭 Hint:** Have a look a the section Patterns if you don't know how to create a React component.
127+
**🔭 Hint:** Have a look a the section [Snippets]("https://davidl.fr/workshop/snippets") if you don't know how to create a React component.
128128

129129
## 👽 Bonus
130130

challenges/foundation/05.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export { ScreenContainer, Offline, Card };
5151

5252
#### `import`
5353

54-
From the another component, to import the files
54+
To import a component from another file, you can use the following syntax:
5555

5656
```javascript
5757
// with `export default Card`

hackathon/spacecraft/src/components/SkeletonList.stories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
};
66

77
export const _SkeletonList = () => {
8-
return <SkeletonList />;
8+
return <SkeletonList numberItems={10} />;
99
};
1010

1111
export const _SkeletonListSingle = () => {

hackathon/spacecraft/src/components/SkeletonList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ export const SkeletonList = ({ numberItems = 10 }: SkeletonListProps) => {
2828
}
2929

3030
return <View>{items}</View>;
31-
};
31+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { SkeletonListReanimated } from "@/components/SkeletonListReanimated";
2+
3+
export default {
4+
title: "SkeletonListReanimated",
5+
};
6+
7+
export const _SkeletonListReanimated = () => {
8+
return <SkeletonListReanimated numberItems={10} />;
9+
};
10+
11+
export const _SkeletonListReanimatedSingle = () => {
12+
return <SkeletonListReanimated numberItems={1} />;
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { StyleSheet, View } from "react-native";
2+
import Animated, {
3+
useAnimatedStyle,
4+
withRepeat,
5+
withSequence,
6+
withTiming,
7+
} from "react-native-reanimated";
8+
9+
interface SkeletonListProps {
10+
numberItems?: number;
11+
}
12+
13+
export const SkeletonListReanimated = ({ numberItems = 10 }: SkeletonListProps) => {
14+
const items = [];
15+
16+
const animatedStyle = useAnimatedStyle(() => {
17+
return {
18+
opacity: withRepeat(
19+
withSequence(
20+
withTiming(0.3, { duration: 800 }),
21+
withTiming(0.7, { duration: 800 }),
22+
),
23+
-1,
24+
true,
25+
),
26+
};
27+
});
28+
29+
for (let i = 0; i < numberItems; i++) {
30+
items.push(
31+
<View
32+
key={`skeleton-${i}`}
33+
style={styles.itemContainer}
34+
>
35+
<Animated.View style={[styles.media, animatedStyle]} />
36+
<View style={styles.content}>
37+
<Animated.View
38+
style={[styles.line, styles.longLine, animatedStyle]}
39+
/>
40+
<Animated.View
41+
style={[styles.line, styles.shortLine, animatedStyle]}
42+
/>
43+
</View>
44+
</View>,
45+
);
46+
}
47+
48+
return <View>{items}</View>;
49+
};
50+
51+
const styles = StyleSheet.create({
52+
content: {
53+
flex: 1,
54+
},
55+
itemContainer: {
56+
alignItems: "center",
57+
flexDirection: "row",
58+
marginBottom: 12,
59+
},
60+
line: {
61+
backgroundColor: "#e1e1e1",
62+
borderRadius: 4,
63+
height: 12,
64+
marginVertical: 4,
65+
},
66+
longLine: {
67+
width: "90%",
68+
},
69+
media: {
70+
backgroundColor: "#e1e1e1",
71+
borderRadius: 20,
72+
height: 40,
73+
marginRight: 12,
74+
width: 40,
75+
},
76+
shortLine: {
77+
width: "80%",
78+
},
79+
});

hackathon/spacecraft/src/screens/PilotScreen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { PeopleProps } from "api/types";
22

33
import { PeopleItem } from "@/components/PeopleItem";
44
import { ScreenContainer } from "@/components/ScreenContainer";
5-
import { SkeletonList } from "@/components/SkeletonList";
5+
import { SkeletonList } from "@/components/SkeletonListReanimated";
66
import { usePilot } from "@/hooks/usePilot";
77
import { FlatList } from "react-native";
88
import { Button } from "react-native-paper";

0 commit comments

Comments
 (0)