import { Carousel, type CarouselRef } from '@amazon-devices/vega-carousel'
import { useEffect, useMemo, useRef, useState } from 'react'
import {
Dimensions,
FocusManager,
Pressable,
ScrollView,
StyleSheet,
Text,
View,
findNodeHandle,
} from 'react-native'
const BASE_HEIGHT = 1080
function scalePixels(size: number): number {
return Math.round((size * Dimensions.get('window').height) / BASE_HEIGHT)
}
const ITEMS = [
'random-text-one',
'random-text-2',
'random-text-3',
'random-text-4',
'random-text-5',
'random-text-6',
'random-text-7',
'random-text-8',
'random-text-9',
'random-text-10',
'random-text-11',
'random-text-12',
'random-text-13',
'random-text-14',
'random-text-15',
'random-text-16',
'random-text-17',
]
const INITIAL_START_INDEX = 16
const CARD_SIZE = scalePixels(200)
type CardProps = {
item: string
index: number
initialStartIndex: number
}
const Card = ({ item, index, initialStartIndex}: CardProps) => {
const ref = useRef<View>(null)
const [isFocused, setFocused] = useState(false)
useEffect(() => {
if (initialStartIndex === index) {
const handle = findNodeHandle(ref.current)
if (handle) {FocusManager.focus(handle)
}
}
}, [initialStartIndex, index])
return (
<Pressable
ref={ref}
style={[styles.card, isFocused && styles.cardFocused]}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
>
<Text style={styles.text}>{item}</Text>
</Pressable>
)
}
export default function SampleCode() {
const carouselRef = useRef<CarouselRef<string>>(null)
const dataAdapter = useMemo(
() => ({
getItem: (index: number) => ITEMS[index],
getItemCount: () => ITEMS.length,
getItemKey: ({ item }: { item: string }) => item,
notifyDataError: () => false,
}),
[],
)
return (
<View style={styles.screen}>
<Carousel
ref={carouselRef}
orientation="vertical"
dataAdapter={dataAdapter}
trapSelectionOnOrientation
initialStartIndex={INITIAL_START_INDEX}
selectionStrategy='pinned'
hideItemsBeforeSelection={false}
pinnedSelectedItemOffset="center"
containerStyle={styles.carousel}
renderItem={({ item, index }) => (
<Card
item={item}
index={index}
initialStartIndex={INITIAL_START_INDEX}
/>
)}
/>
</View>
)
}
const styles = StyleSheet.create({
screen: {
flexDirection: 'row',
width: '100%',
height: '100%',
},
controls: {
flexGrow: 1,
},
carousel: {
width: CARD_SIZE,
height: scalePixels(1080),
},
card: {
width: CARD_SIZE,
height: CARD_SIZE,
backgroundColor: '#FF0000',
},
cardFocused: {
backgroundColor: '#008000',
},
button: {
backgroundColor: '#333333',
padding: 8,
marginBottom: 4,
},
text: {
color: '#ffffff',
fontSize: 32,
},
})
For some indices, it works but I have not been able to establish a pattern, when and under what conditions, it will start to behave right. But for those, that do not work, it appears to me, carousel is unable to either being them into the viewport, or can only make them partially visible.