@legendapp/list 2.0.0-next.2 → 2.0.0-next.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/{dist/animated.d.mts → animated.d.mts} +10 -3
  2. package/{dist/animated.d.ts → animated.d.ts} +10 -3
  3. package/{dist/animated.js → animated.js} +2 -2
  4. package/{dist/animated.mjs → animated.mjs} +2 -2
  5. package/{dist/index.d.mts → index.d.mts} +86 -167
  6. package/{dist/index.d.ts → index.d.ts} +86 -167
  7. package/{dist/index.js → index.js} +1594 -1098
  8. package/{dist/index.mjs → index.mjs} +1596 -1100
  9. package/keyboard-controller.d.mts +148 -0
  10. package/keyboard-controller.d.ts +148 -0
  11. package/{dist/keyboard-controller.js → keyboard-controller.js} +4 -4
  12. package/{dist/keyboard-controller.mjs → keyboard-controller.mjs} +4 -4
  13. package/package.json +34 -88
  14. package/{dist/reanimated.d.mts → reanimated.d.mts} +2 -2
  15. package/{dist/reanimated.d.ts → reanimated.d.ts} +2 -2
  16. package/reanimated.js +60 -0
  17. package/reanimated.mjs +53 -0
  18. package/.claude/settings.local.json +0 -8
  19. package/.cursor/rules/changelog.mdc +0 -60
  20. package/.github/FUNDING.yml +0 -15
  21. package/.gitignore +0 -5
  22. package/.prettierrc.json +0 -5
  23. package/.vscode/settings.json +0 -14
  24. package/CLAUDE.md +0 -126
  25. package/biome.json +0 -46
  26. package/bun.lock +0 -1289
  27. package/bunfig.toml +0 -2
  28. package/dist/CHANGELOG.md +0 -119
  29. package/dist/LICENSE +0 -21
  30. package/dist/README.md +0 -139
  31. package/dist/keyboard-controller.d.mts +0 -261
  32. package/dist/keyboard-controller.d.ts +0 -261
  33. package/dist/package.json +0 -35
  34. package/dist/reanimated.js +0 -58
  35. package/dist/reanimated.mjs +0 -51
  36. package/example/README.md +0 -40
  37. package/example/api/data/genres.json +0 -23
  38. package/example/api/data/playlist/10402-10749.json +0 -1
  39. package/example/api/data/playlist/10402-10770.json +0 -1
  40. package/example/api/data/playlist/10402-37.json +0 -1
  41. package/example/api/data/playlist/10749-10752.json +0 -1
  42. package/example/api/data/playlist/10749-10770.json +0 -1
  43. package/example/api/data/playlist/10749-37.json +0 -1
  44. package/example/api/data/playlist/10749-878.json +0 -1
  45. package/example/api/data/playlist/10751-10402.json +0 -1
  46. package/example/api/data/playlist/10751-10752.json +0 -1
  47. package/example/api/data/playlist/10751-37.json +0 -1
  48. package/example/api/data/playlist/10751-53.json +0 -1
  49. package/example/api/data/playlist/10751-878.json +0 -1
  50. package/example/api/data/playlist/10751-9648.json +0 -1
  51. package/example/api/data/playlist/10752-37.json +0 -1
  52. package/example/api/data/playlist/12-10402.json +0 -1
  53. package/example/api/data/playlist/12-10749.json +0 -1
  54. package/example/api/data/playlist/12-18.json +0 -1
  55. package/example/api/data/playlist/12-27.json +0 -1
  56. package/example/api/data/playlist/12-35.json +0 -1
  57. package/example/api/data/playlist/14-36.json +0 -1
  58. package/example/api/data/playlist/14-878.json +0 -1
  59. package/example/api/data/playlist/16-10751.json +0 -1
  60. package/example/api/data/playlist/16-10770.json +0 -1
  61. package/example/api/data/playlist/16-35.json +0 -1
  62. package/example/api/data/playlist/16-36.json +0 -1
  63. package/example/api/data/playlist/16-53.json +0 -1
  64. package/example/api/data/playlist/18-10751.json +0 -1
  65. package/example/api/data/playlist/18-10752.json +0 -1
  66. package/example/api/data/playlist/18-37.json +0 -1
  67. package/example/api/data/playlist/18-53.json +0 -1
  68. package/example/api/data/playlist/18-878.json +0 -1
  69. package/example/api/data/playlist/27-10749.json +0 -1
  70. package/example/api/data/playlist/27-10770.json +0 -1
  71. package/example/api/data/playlist/28-10749.json +0 -1
  72. package/example/api/data/playlist/28-10751.json +0 -1
  73. package/example/api/data/playlist/28-10770.json +0 -1
  74. package/example/api/data/playlist/28-16.json +0 -1
  75. package/example/api/data/playlist/28-18.json +0 -1
  76. package/example/api/data/playlist/28-36.json +0 -1
  77. package/example/api/data/playlist/28-37.json +0 -1
  78. package/example/api/data/playlist/28-53.json +0 -1
  79. package/example/api/data/playlist/28-80.json +0 -1
  80. package/example/api/data/playlist/28-99.json +0 -1
  81. package/example/api/data/playlist/35-10749.json +0 -1
  82. package/example/api/data/playlist/35-10751.json +0 -1
  83. package/example/api/data/playlist/35-10752.json +0 -1
  84. package/example/api/data/playlist/35-27.json +0 -1
  85. package/example/api/data/playlist/35-36.json +0 -1
  86. package/example/api/data/playlist/35-53.json +0 -1
  87. package/example/api/data/playlist/35-80.json +0 -1
  88. package/example/api/data/playlist/36-37.json +0 -1
  89. package/example/api/data/playlist/36-878.json +0 -1
  90. package/example/api/data/playlist/36-9648.json +0 -1
  91. package/example/api/data/playlist/53-10752.json +0 -1
  92. package/example/api/data/playlist/80-10770.json +0 -1
  93. package/example/api/data/playlist/80-14.json +0 -1
  94. package/example/api/data/playlist/80-18.json +0 -1
  95. package/example/api/data/playlist/80-37.json +0 -1
  96. package/example/api/data/playlist/878-37.json +0 -1
  97. package/example/api/data/playlist/9648-10770.json +0 -1
  98. package/example/api/data/playlist/9648-37.json +0 -1
  99. package/example/api/data/playlist/9648-53.json +0 -1
  100. package/example/api/data/playlist/9648-878.json +0 -1
  101. package/example/api/data/playlist/99-10749.json +0 -1
  102. package/example/api/data/playlist/99-14.json +0 -1
  103. package/example/api/data/playlist/99-18.json +0 -1
  104. package/example/api/data/playlist/99-27.json +0 -1
  105. package/example/api/data/playlist/99-53.json +0 -1
  106. package/example/api/data/playlist/99-9648.json +0 -1
  107. package/example/api/data/playlist/index.ts +0 -73
  108. package/example/api/data/rows.json +0 -1
  109. package/example/api/index.ts +0 -36
  110. package/example/app/(tabs)/_layout.tsx +0 -60
  111. package/example/app/(tabs)/cards.tsx +0 -81
  112. package/example/app/(tabs)/index.tsx +0 -205
  113. package/example/app/(tabs)/moviesL.tsx +0 -7
  114. package/example/app/(tabs)/moviesLR.tsx +0 -7
  115. package/example/app/+not-found.tsx +0 -32
  116. package/example/app/_layout.tsx +0 -34
  117. package/example/app/accurate-scrollto/index.tsx +0 -125
  118. package/example/app/accurate-scrollto-2/index.tsx +0 -52
  119. package/example/app/accurate-scrollto-huge/index.tsx +0 -128
  120. package/example/app/add-to-end/index.tsx +0 -82
  121. package/example/app/ai-chat/index.tsx +0 -236
  122. package/example/app/bidirectional-infinite-list/index.tsx +0 -133
  123. package/example/app/cards-columns/index.tsx +0 -37
  124. package/example/app/cards-flashlist/index.tsx +0 -122
  125. package/example/app/cards-flatlist/index.tsx +0 -94
  126. package/example/app/cards-no-recycle/index.tsx +0 -110
  127. package/example/app/cards-renderItem.tsx +0 -354
  128. package/example/app/chat-example/index.tsx +0 -167
  129. package/example/app/chat-infinite/index.tsx +0 -239
  130. package/example/app/chat-keyboard/index.tsx +0 -248
  131. package/example/app/chat-resize-outer/index.tsx +0 -247
  132. package/example/app/columns/index.tsx +0 -78
  133. package/example/app/countries/index.tsx +0 -182
  134. package/example/app/countries-flashlist/index.tsx +0 -163
  135. package/example/app/countries-reorder/index.tsx +0 -187
  136. package/example/app/extra-data/index.tsx +0 -86
  137. package/example/app/filter-elements/filter-data-provider.tsx +0 -55
  138. package/example/app/filter-elements/index.tsx +0 -118
  139. package/example/app/initial-scroll-index/index.tsx +0 -106
  140. package/example/app/initial-scroll-index/renderFixedItem.tsx +0 -215
  141. package/example/app/initial-scroll-index-free-height/index.tsx +0 -70
  142. package/example/app/initial-scroll-index-keyed/index.tsx +0 -62
  143. package/example/app/lazy-list/index.tsx +0 -123
  144. package/example/app/movies-flashlist/index.tsx +0 -7
  145. package/example/app/mutable-cells/index.tsx +0 -104
  146. package/example/app/video-feed/index.tsx +0 -119
  147. package/example/app.config.js +0 -22
  148. package/example/app.json +0 -45
  149. package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
  150. package/example/assets/images/adaptive-icon.png +0 -0
  151. package/example/assets/images/favicon.png +0 -0
  152. package/example/assets/images/icon.png +0 -0
  153. package/example/assets/images/partial-react-logo.png +0 -0
  154. package/example/assets/images/react-logo.png +0 -0
  155. package/example/assets/images/react-logo@2x.png +0 -0
  156. package/example/assets/images/react-logo@3x.png +0 -0
  157. package/example/assets/images/splash-icon.png +0 -0
  158. package/example/autoscroll.sh +0 -101
  159. package/example/bun.lock +0 -2266
  160. package/example/bunfig.toml +0 -2
  161. package/example/components/Breathe.tsx +0 -54
  162. package/example/components/Circle.tsx +0 -69
  163. package/example/components/Collapsible.tsx +0 -44
  164. package/example/components/ExternalLink.tsx +0 -24
  165. package/example/components/HapticTab.tsx +0 -18
  166. package/example/components/HelloWave.tsx +0 -37
  167. package/example/components/Movies.tsx +0 -179
  168. package/example/components/ParallaxScrollView.tsx +0 -81
  169. package/example/components/ThemedText.tsx +0 -60
  170. package/example/components/ThemedView.tsx +0 -14
  171. package/example/components/__tests__/ThemedText-test.tsx +0 -10
  172. package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +0 -24
  173. package/example/components/ui/IconSymbol.ios.tsx +0 -32
  174. package/example/components/ui/IconSymbol.tsx +0 -43
  175. package/example/components/ui/TabBarBackground.ios.tsx +0 -22
  176. package/example/components/ui/TabBarBackground.tsx +0 -6
  177. package/example/constants/Colors.ts +0 -26
  178. package/example/constants/constants.ts +0 -5
  179. package/example/constants/useScrollTest.ts +0 -19
  180. package/example/hooks/useColorScheme.ts +0 -1
  181. package/example/hooks/useColorScheme.web.ts +0 -8
  182. package/example/hooks/useThemeColor.ts +0 -22
  183. package/example/ios/.xcode.env +0 -11
  184. package/example/ios/Podfile +0 -64
  185. package/example/ios/Podfile.lock +0 -2767
  186. package/example/ios/Podfile.properties.json +0 -5
  187. package/example/ios/listtest/AppDelegate.swift +0 -70
  188. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  189. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +0 -14
  190. package/example/ios/listtest/Images.xcassets/Contents.json +0 -6
  191. package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +0 -20
  192. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +0 -23
  193. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
  194. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
  195. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
  196. package/example/ios/listtest/Info.plist +0 -85
  197. package/example/ios/listtest/PrivacyInfo.xcprivacy +0 -48
  198. package/example/ios/listtest/SplashScreen.storyboard +0 -42
  199. package/example/ios/listtest/Supporting/Expo.plist +0 -12
  200. package/example/ios/listtest/listtest-Bridging-Header.h +0 -3
  201. package/example/ios/listtest/listtest.entitlements +0 -5
  202. package/example/ios/listtest.xcodeproj/project.pbxproj +0 -547
  203. package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +0 -88
  204. package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +0 -10
  205. package/example/metro.config.js +0 -16
  206. package/example/package.json +0 -73
  207. package/example/scripts/reset-project.js +0 -84
  208. package/example/tsconfig.json +0 -26
  209. package/posttsup.ts +0 -24
  210. package/src/Container.tsx +0 -176
  211. package/src/Containers.tsx +0 -85
  212. package/src/ContextContainer.ts +0 -145
  213. package/src/DebugView.tsx +0 -83
  214. package/src/LazyLegendList.tsx +0 -41
  215. package/src/LeanView.tsx +0 -18
  216. package/src/LegendList.tsx +0 -558
  217. package/src/ListComponent.tsx +0 -191
  218. package/src/ScrollAdjust.tsx +0 -24
  219. package/src/ScrollAdjustHandler.ts +0 -26
  220. package/src/Separator.tsx +0 -14
  221. package/src/animated.tsx +0 -6
  222. package/src/calculateItemsInView.ts +0 -363
  223. package/src/calculateOffsetForIndex.ts +0 -23
  224. package/src/calculateOffsetWithOffsetPosition.ts +0 -26
  225. package/src/checkAllSizesKnown.ts +0 -17
  226. package/src/checkAtBottom.ts +0 -36
  227. package/src/checkAtTop.ts +0 -27
  228. package/src/checkThreshold.ts +0 -30
  229. package/src/constants.ts +0 -11
  230. package/src/createColumnWrapperStyle.ts +0 -16
  231. package/src/doInitialAllocateContainers.ts +0 -40
  232. package/src/doMaintainScrollAtEnd.ts +0 -34
  233. package/src/findAvailableContainers.ts +0 -98
  234. package/src/finishScrollTo.ts +0 -8
  235. package/src/getId.ts +0 -21
  236. package/src/getItemSize.ts +0 -52
  237. package/src/getRenderedItem.ts +0 -34
  238. package/src/getScrollVelocity.ts +0 -47
  239. package/src/handleLayout.ts +0 -70
  240. package/src/helpers.ts +0 -39
  241. package/src/index.ts +0 -11
  242. package/src/keyboard-controller.tsx +0 -63
  243. package/src/onScroll.ts +0 -66
  244. package/src/prepareMVCP.ts +0 -50
  245. package/src/reanimated.tsx +0 -63
  246. package/src/requestAdjust.ts +0 -41
  247. package/src/scrollTo.ts +0 -40
  248. package/src/scrollToIndex.ts +0 -34
  249. package/src/setDidLayout.ts +0 -25
  250. package/src/setPaddingTop.ts +0 -28
  251. package/src/state.tsx +0 -304
  252. package/src/types.ts +0 -610
  253. package/src/updateAlignItemsPaddingTop.ts +0 -18
  254. package/src/updateAllPositions.ts +0 -130
  255. package/src/updateItemSize.ts +0 -203
  256. package/src/updateTotalSize.ts +0 -44
  257. package/src/useAnimatedValue.ts +0 -6
  258. package/src/useCombinedRef.ts +0 -22
  259. package/src/useInit.ts +0 -17
  260. package/src/useSyncLayout.tsx +0 -68
  261. package/src/useValue$.ts +0 -53
  262. package/src/viewability.ts +0 -279
  263. package/tsconfig.json +0 -59
  264. package/tsup.config.ts +0 -21
@@ -1,2 +0,0 @@
1
- [install]
2
- saveTextLockfile = true
@@ -1,54 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import { View, StyleSheet } from "react-native";
3
- import Animated, {
4
- Easing,
5
- useAnimatedStyle,
6
- useSharedValue,
7
- withRepeat,
8
- withTiming,
9
- } from "react-native-reanimated";
10
- import { mix } from "react-native-redash";
11
-
12
- import Circle from "./Circle";
13
-
14
- const styles = StyleSheet.create({
15
- container: {
16
- flex: 1,
17
- backgroundColor: "black",
18
- },
19
- });
20
- const Breathe = () => {
21
- const progress = useSharedValue(0);
22
- const goesDown = useSharedValue(false);
23
- useEffect(() => {
24
- progress.value = withRepeat(
25
- withTiming(
26
- 1,
27
- { duration: 3000, easing: Easing.bezier(0.5, 0, 0.5, 1) },
28
- () => (goesDown.value = !goesDown.value)
29
- ),
30
- -1,
31
- true
32
- );
33
- }, [goesDown, progress]);
34
- const style = useAnimatedStyle(() => ({
35
- flex: 1,
36
- transform: [{ rotate: `${mix(progress.value, -Math.PI, 0)}rad` }],
37
- }));
38
- return (
39
- <View style={styles.container}>
40
- <Animated.View style={style}>
41
- {new Array(6).fill(0).map((_, index) => (
42
- <Circle
43
- progress={progress}
44
- index={index}
45
- key={index}
46
- goesDown={goesDown}
47
- />
48
- ))}
49
- </Animated.View>
50
- </View>
51
- );
52
- };
53
-
54
- export default Breathe;
@@ -1,69 +0,0 @@
1
- import React from "react";
2
- import { Dimensions, StyleSheet } from "react-native";
3
- import Animated, {
4
- Extrapolate,
5
- interpolate,
6
- useAnimatedStyle,
7
- } from "react-native-reanimated";
8
- import { clamp, mix, polar2Canvas } from "react-native-redash";
9
- import { LinearGradient } from "expo-linear-gradient";
10
-
11
- const { width } = Dimensions.get("window");
12
- const SIZE = width / 2;
13
- const styles = StyleSheet.create({
14
- container: {
15
- ...StyleSheet.absoluteFillObject,
16
- justifyContent: "center",
17
- alignItems: "center",
18
- },
19
- circle: {
20
- width: SIZE,
21
- height: SIZE,
22
- borderRadius: SIZE / 2,
23
- opacity: 0.5,
24
- },
25
- });
26
-
27
- const transform = (theta: number, value: number) => {
28
- "worklet";
29
- const { x, y } = polar2Canvas({ theta, radius: SIZE / 2 }, { x: 0, y: 0 });
30
- const translateX = mix(value, 0, x);
31
- const translateY = mix(value, 0, y);
32
- return [{ translateX }, { translateY }, { scale: mix(value, 0.3, 1) }];
33
- };
34
-
35
- interface CircleProps {
36
- progress: Animated.SharedValue<number>;
37
- goesDown: Animated.SharedValue<boolean>;
38
- index: number;
39
- }
40
-
41
- const Circle = ({ progress, goesDown, index }: CircleProps) => {
42
- const theta = (index * (2 * Math.PI)) / 6;
43
- const style = useAnimatedStyle(() => {
44
- return {
45
- transform: transform(theta, progress.value),
46
- };
47
- });
48
- const style1 = useAnimatedStyle(() => {
49
- const value = goesDown.value
50
- ? clamp(progress.value + 0.1, 0, 1)
51
- : progress.value;
52
- return {
53
- opacity: interpolate(value, [0.6, 1], [0, 1], Extrapolate.CLAMP),
54
- transform: transform(theta, value),
55
- };
56
- });
57
- return (
58
- <>
59
- <Animated.View style={[styles.container, style1]}>
60
- <LinearGradient colors={["#62BFA1", "#529CA0"]} style={styles.circle} />
61
- </Animated.View>
62
- <Animated.View style={[styles.container, style]}>
63
- <LinearGradient colors={["#62BFA1", "#529CA0"]} style={styles.circle} />
64
- </Animated.View>
65
- </>
66
- );
67
- };
68
-
69
- export default Circle;
@@ -1,44 +0,0 @@
1
- import { PropsWithChildren, useState } from 'react';
2
- import { StyleSheet, TouchableOpacity, useColorScheme } from 'react-native';
3
-
4
- import { ThemedText } from '@/components/ThemedText';
5
- import { ThemedView } from '@/components/ThemedView';
6
- import { IconSymbol } from '@/components/ui/IconSymbol';
7
- import { Colors } from '@/constants/Colors';
8
-
9
- export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
10
- const [isOpen, setIsOpen] = useState(false);
11
- const theme = useColorScheme() ?? 'light';
12
-
13
- return (
14
- <ThemedView>
15
- <TouchableOpacity
16
- style={styles.heading}
17
- onPress={() => setIsOpen((value) => !value)}
18
- activeOpacity={0.8}>
19
- <IconSymbol
20
- name="chevron.right"
21
- size={18}
22
- weight="medium"
23
- color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
24
- style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
25
- />
26
-
27
- <ThemedText type="defaultSemiBold">{title}</ThemedText>
28
- </TouchableOpacity>
29
- {isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
30
- </ThemedView>
31
- );
32
- }
33
-
34
- const styles = StyleSheet.create({
35
- heading: {
36
- flexDirection: 'row',
37
- alignItems: 'center',
38
- gap: 6,
39
- },
40
- content: {
41
- marginTop: 6,
42
- marginLeft: 24,
43
- },
44
- });
@@ -1,24 +0,0 @@
1
- import { Link } from 'expo-router';
2
- import { openBrowserAsync } from 'expo-web-browser';
3
- import { type ComponentProps } from 'react';
4
- import { Platform } from 'react-native';
5
-
6
- type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: string };
7
-
8
- export function ExternalLink({ href, ...rest }: Props) {
9
- return (
10
- <Link
11
- target="_blank"
12
- {...rest}
13
- href={href}
14
- onPress={async (event) => {
15
- if (Platform.OS !== 'web') {
16
- // Prevent the default behavior of linking to the default browser on native.
17
- event.preventDefault();
18
- // Open the link in an in-app browser.
19
- await openBrowserAsync(href);
20
- }
21
- }}
22
- />
23
- );
24
- }
@@ -1,18 +0,0 @@
1
- import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs';
2
- import { PlatformPressable } from '@react-navigation/elements';
3
- import * as Haptics from 'expo-haptics';
4
-
5
- export function HapticTab(props: BottomTabBarButtonProps) {
6
- return (
7
- <PlatformPressable
8
- {...props}
9
- onPressIn={(ev) => {
10
- if (process.env.EXPO_OS === 'ios') {
11
- // Add a soft haptic feedback when pressing down on the tabs.
12
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
13
- }
14
- props.onPressIn?.(ev);
15
- }}
16
- />
17
- );
18
- }
@@ -1,37 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
- import Animated, {
3
- useSharedValue,
4
- useAnimatedStyle,
5
- withTiming,
6
- withRepeat,
7
- withSequence,
8
- } from 'react-native-reanimated';
9
-
10
- import { ThemedText } from '@/components/ThemedText';
11
-
12
- export function HelloWave() {
13
- const rotationAnimation = useSharedValue(0);
14
-
15
- rotationAnimation.value = withRepeat(
16
- withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })),
17
- 4 // Run the animation 4 times
18
- );
19
-
20
- const animatedStyle = useAnimatedStyle(() => ({
21
- transform: [{ rotate: `${rotationAnimation.value}deg` }],
22
- }));
23
-
24
- return (
25
- <Animated.View style={animatedStyle}>
26
- <ThemedText style={styles.text}>👋</ThemedText>
27
- </Animated.View>
28
- );
29
- }
30
-
31
- const styles = StyleSheet.create({
32
- text: {
33
- fontSize: 28,
34
- lineHeight: 32,
35
- marginTop: -6,
36
- },
37
- });
@@ -1,179 +0,0 @@
1
- // Forked from https://github.com/Almouro/rn-list-comparison-movies
2
- // Full credit to Alex Moreaux (@Almouro) for the original code
3
-
4
- import { LegendList, type LegendListRenderItemProps } from "@legendapp/list";
5
- import { FlashList } from "@shopify/flash-list";
6
- import * as React from "react";
7
- import { Dimensions, Image, StyleSheet, Text, View } from "react-native";
8
- import { IMAGE_SIZE, type Movie, type Playlist, getImageUrl } from "../api";
9
- import { playlists as playlistData } from "../api/data/playlist";
10
-
11
- const itemCount = 0;
12
-
13
- const cardStyles = StyleSheet.create({
14
- image: {
15
- width: IMAGE_SIZE.width,
16
- height: IMAGE_SIZE.height,
17
- borderRadius: 5,
18
- },
19
- background: {
20
- ...StyleSheet.absoluteFillObject,
21
- backgroundColor: "#272829",
22
- },
23
- });
24
-
25
- const MoviePortrait = ({ movie }: { movie: Movie }) => {
26
- return (
27
- <View style={cardStyles.image}>
28
- <View style={cardStyles.background} />
29
- <Image
30
- key={movie.id}
31
- source={{ uri: getImageUrl(movie.poster_path) }}
32
- style={cardStyles.image}
33
- fadeDuration={0}
34
- />
35
- </View>
36
- );
37
- };
38
-
39
- const MarginBetweenItems = () => <View style={{ width: margins.s }} />;
40
-
41
- const margins = {
42
- s: 5,
43
- m: 10,
44
- l: 20,
45
- };
46
-
47
- const rowStyles = StyleSheet.create({
48
- title: {
49
- fontSize: 20,
50
- fontWeight: "bold",
51
- color: "white",
52
- marginHorizontal: margins.m,
53
- marginBottom: margins.s,
54
- },
55
- container: {
56
- minHeight: cardStyles.image.height,
57
- marginBottom: margins.l,
58
- width: Dimensions.get("window").width,
59
- },
60
- listContainer: {
61
- paddingHorizontal: margins.m,
62
- },
63
- });
64
-
65
- const rowCount = 0;
66
-
67
- const MovieRow = ({
68
- playlist,
69
- ListComponent,
70
- isLegend,
71
- }: {
72
- playlist: Playlist;
73
- ListComponent: typeof FlashList | typeof LegendList;
74
- isLegend: boolean;
75
- }) => {
76
- const movies = playlistData[playlist.id]();
77
- const DRAW_DISTANCE_ROW = 500;
78
- // let opacity = 0;
79
- // if (isLegend) {
80
- // const [_opacity, setOpacity] = useRecyclingState<number>(() => {
81
- // if (setOpacity) {
82
- // requestAnimationFrame(() => setOpacity(1));
83
- // return 0;
84
- // }
85
- // return 1;
86
- // });
87
- // opacity = _opacity;
88
- // } else {
89
- // opacity = 1;
90
- // }
91
-
92
- // const listRef = useRef<FlashList<Movie>>(null);
93
-
94
- // const {onMomentumScrollBegin, onScroll} = useRememberListScroll(
95
- // listRef,
96
- // playlist.id,
97
- // );
98
-
99
- // useEffect(() => {
100
- // rowCount++;
101
- // console.log("rowCount", rowCount);
102
- // }, []);
103
-
104
- // const fadeAnim = useRef(new Animated.Value(0)).current;
105
- // // useEffect(() => {
106
- // // itemCount++;
107
- // // console.log("itemCount", itemCount);
108
- // // }, []);
109
-
110
- // useRecyclingEffect(() => {
111
- // console.log("useRecyclingEffect");
112
- // fadeAnim.setValue(0);
113
- // Animated.timing(fadeAnim, {
114
- // toValue: 1,
115
- // duration: 2000,
116
- // useNativeDriver: true,
117
- // }).start();
118
- // });
119
-
120
- return (
121
- <React.Fragment>
122
- <Text numberOfLines={1} style={rowStyles.title}>
123
- {playlist.title}
124
- </Text>
125
- <View style={[rowStyles.container]}>
126
- <ListComponent
127
- contentContainerStyle={rowStyles.listContainer}
128
- // See https://shopify.github.io/flash-list/docs/fundamentals/performant-components/#remove-key-prop
129
- // keyExtractor={(movie: Movie, index: number) => (isLegend ? movie.id.toString() : index.toString())}
130
- // keyExtractor={(movie: Movie, index: number) => index.toString()}
131
- ItemSeparatorComponent={MarginBetweenItems}
132
- horizontal
133
- estimatedItemSize={cardStyles.image.width + 5}
134
- data={movies}
135
- // recycleItems
136
- renderItem={({ item }: { item: Movie }) => <MoviePortrait movie={item} />}
137
- // ref={listRef}
138
- // onMomentumScrollBegin={onMomentumScrollBegin}
139
- // onScroll={onScroll}
140
- drawDistance={DRAW_DISTANCE_ROW}
141
- />
142
- </View>
143
- </React.Fragment>
144
- );
145
- };
146
-
147
- const listStyles = StyleSheet.create({
148
- container: {
149
- backgroundColor: "black",
150
- paddingVertical: margins.m,
151
- },
152
- });
153
-
154
- const Movies = ({ isLegend, recycleItems }: { isLegend: boolean; recycleItems?: boolean }) => {
155
- const playlists = require("../api/data/rows.json");
156
-
157
- const ListComponent: typeof LegendList = isLegend ? LegendList : (FlashList as any);
158
-
159
- // Flashlist appears to internally multiple the draw distance by 2-3 so increase the draw distance
160
- // for the Legend version to get the same effect
161
- const DRAW_DISTANCE = 500;
162
- console.log("is legend", isLegend, DRAW_DISTANCE);
163
-
164
- return (
165
- <ListComponent
166
- data={playlists}
167
- keyExtractor={(playlist: Playlist) => playlist.id}
168
- estimatedItemSize={cardStyles.image.height + 52}
169
- renderItem={({ item: playlist }: LegendListRenderItemProps<Playlist>) => (
170
- <MovieRow ListComponent={ListComponent} isLegend={isLegend} playlist={playlist} />
171
- )}
172
- contentContainerStyle={listStyles.container}
173
- drawDistance={DRAW_DISTANCE}
174
- recycleItems={recycleItems}
175
- />
176
- );
177
- };
178
-
179
- export default Movies;
@@ -1,81 +0,0 @@
1
- import type { PropsWithChildren, ReactElement } from 'react';
2
- import { StyleSheet, useColorScheme } from 'react-native';
3
- import Animated, {
4
- interpolate,
5
- useAnimatedRef,
6
- useAnimatedStyle,
7
- useScrollViewOffset,
8
- } from 'react-native-reanimated';
9
-
10
- import { ThemedView } from '@/components/ThemedView';
11
- import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
12
-
13
- const HEADER_HEIGHT = 250;
14
-
15
- type Props = PropsWithChildren<{
16
- headerImage: ReactElement;
17
- headerBackgroundColor: { dark: string; light: string };
18
- }>;
19
-
20
- export default function ParallaxScrollView({
21
- children,
22
- headerImage,
23
- headerBackgroundColor,
24
- }: Props) {
25
- const colorScheme = useColorScheme() ?? 'light';
26
- const scrollRef = useAnimatedRef<Animated.ScrollView>();
27
- const scrollOffset = useScrollViewOffset(scrollRef);
28
- const bottom = useBottomTabOverflow();
29
- const headerAnimatedStyle = useAnimatedStyle(() => {
30
- return {
31
- transform: [
32
- {
33
- translateY: interpolate(
34
- scrollOffset.value,
35
- [-HEADER_HEIGHT, 0, HEADER_HEIGHT],
36
- [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
37
- ),
38
- },
39
- {
40
- scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
41
- },
42
- ],
43
- };
44
- });
45
-
46
- return (
47
- <ThemedView style={styles.container}>
48
- <Animated.ScrollView
49
- ref={scrollRef}
50
- scrollEventThrottle={16}
51
- scrollIndicatorInsets={{ bottom }}
52
- contentContainerStyle={{ paddingBottom: bottom }}>
53
- <Animated.View
54
- style={[
55
- styles.header,
56
- { backgroundColor: headerBackgroundColor[colorScheme] },
57
- headerAnimatedStyle,
58
- ]}>
59
- {headerImage}
60
- </Animated.View>
61
- <ThemedView style={styles.content}>{children}</ThemedView>
62
- </Animated.ScrollView>
63
- </ThemedView>
64
- );
65
- }
66
-
67
- const styles = StyleSheet.create({
68
- container: {
69
- flex: 1,
70
- },
71
- header: {
72
- height: HEADER_HEIGHT,
73
- overflow: 'hidden',
74
- },
75
- content: {
76
- flex: 1,
77
- padding: 32,
78
- gap: 16,
79
- overflow: 'hidden',
80
- },
81
- });
@@ -1,60 +0,0 @@
1
- import { Text, type TextProps, StyleSheet } from 'react-native';
2
-
3
- import { useThemeColor } from '@/hooks/useThemeColor';
4
-
5
- export type ThemedTextProps = TextProps & {
6
- lightColor?: string;
7
- darkColor?: string;
8
- type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
9
- };
10
-
11
- export function ThemedText({
12
- style,
13
- lightColor,
14
- darkColor,
15
- type = 'default',
16
- ...rest
17
- }: ThemedTextProps) {
18
- const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
19
-
20
- return (
21
- <Text
22
- style={[
23
- { color },
24
- type === 'default' ? styles.default : undefined,
25
- type === 'title' ? styles.title : undefined,
26
- type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
27
- type === 'subtitle' ? styles.subtitle : undefined,
28
- type === 'link' ? styles.link : undefined,
29
- style,
30
- ]}
31
- {...rest}
32
- />
33
- );
34
- }
35
-
36
- const styles = StyleSheet.create({
37
- default: {
38
- fontSize: 16,
39
- lineHeight: 24,
40
- },
41
- defaultSemiBold: {
42
- fontSize: 16,
43
- lineHeight: 24,
44
- fontWeight: '600',
45
- },
46
- title: {
47
- fontSize: 32,
48
- fontWeight: 'bold',
49
- lineHeight: 32,
50
- },
51
- subtitle: {
52
- fontSize: 20,
53
- fontWeight: 'bold',
54
- },
55
- link: {
56
- lineHeight: 30,
57
- fontSize: 16,
58
- color: '#0a7ea4',
59
- },
60
- });
@@ -1,14 +0,0 @@
1
- import { View, type ViewProps } from 'react-native';
2
-
3
- import { useThemeColor } from '@/hooks/useThemeColor';
4
-
5
- export type ThemedViewProps = ViewProps & {
6
- lightColor?: string;
7
- darkColor?: string;
8
- };
9
-
10
- export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
11
- const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
12
-
13
- return <View style={[{ backgroundColor }, style]} {...otherProps} />;
14
- }
@@ -1,10 +0,0 @@
1
- import * as React from 'react';
2
- import renderer from 'react-test-renderer';
3
-
4
- import { ThemedText } from '../ThemedText';
5
-
6
- it(`renders correctly`, () => {
7
- const tree = renderer.create(<ThemedText>Snapshot test!</ThemedText>).toJSON();
8
-
9
- expect(tree).toMatchSnapshot();
10
- });
@@ -1,24 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`renders correctly 1`] = `
4
- <Text
5
- style={
6
- [
7
- {
8
- "color": "#11181C",
9
- },
10
- {
11
- "fontSize": 16,
12
- "lineHeight": 24,
13
- },
14
- undefined,
15
- undefined,
16
- undefined,
17
- undefined,
18
- undefined,
19
- ]
20
- }
21
- >
22
- Snapshot test!
23
- </Text>
24
- `;
@@ -1,32 +0,0 @@
1
- import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols';
2
- import { StyleProp, ViewStyle } from 'react-native';
3
-
4
- export function IconSymbol({
5
- name,
6
- size = 24,
7
- color,
8
- style,
9
- weight = 'regular',
10
- }: {
11
- name: SymbolViewProps['name'];
12
- size?: number;
13
- color: string;
14
- style?: StyleProp<ViewStyle>;
15
- weight?: SymbolWeight;
16
- }) {
17
- return (
18
- <SymbolView
19
- weight={weight}
20
- tintColor={color}
21
- resizeMode="scaleAspectFit"
22
- name={name}
23
- style={[
24
- {
25
- width: size,
26
- height: size,
27
- },
28
- style,
29
- ]}
30
- />
31
- );
32
- }