Untitled
unknown
plain_text
a year ago
3.8 kB
10
Indexable
import { ThemedText } from '@/components/ThemedText'
import { ThemedView } from '@/components/ThemedView'
import React, { FC, useState } from 'react'
import { FlatList, NativeScrollEvent, NativeSyntheticEvent, StyleSheet, View } from 'react-native'
import { SharedValue, useSharedValue } from 'react-native-reanimated'
const hoursArray = Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, '0'))
const minutesArray = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'))
const ranges = [['AM', 'PM'], hoursArray, minutesArray]
const ITEM_HEIGHT = 60
type ListComponentProps = {
item: string
index: number
contentOffset: SharedValue<number>
}
const ListComponent: FC<ListComponentProps> = ({ item, index, contentOffset }) => {
// const animatedStyle = useAnimatedStyle(() => ({
// opacity: interpolate(
// contentOffset.value,
// [index * ITEM_HEIGHT - ITEM_HEIGHT, index * ITEM_HEIGHT, index * ITEM_HEIGHT + ITEM_HEIGHT],
// [0.25, 1, 0.25],
// 'clamp'
// ),
// }))
return (
<View
style={[
styles.viewText,
{ height: ITEM_HEIGHT, opacity: contentOffset.value === index * ITEM_HEIGHT ? 1 : 0.25 },
]}
>
<ThemedText style={styles.text}>{item}</ThemedText>
</View>
)
}
const Time = () => {
//
const [output, setOutput] = useState({
hours: '00',
minutes: '00',
ampm: 'AM',
})
function handleChange(e: NativeSyntheticEvent<NativeScrollEvent>, rangeIndex: number) {
const value = e.nativeEvent.contentOffset.y
const itemIndex = Math.round(value / ITEM_HEIGHT)
if (rangeIndex === 0) {
setOutput(prev => ({ ...prev, ampm: ranges[rangeIndex][itemIndex] }))
} else if (rangeIndex === 1) {
setOutput(prev => ({ ...prev, hours: ranges[rangeIndex][itemIndex] }))
} else {
setOutput(prev => ({ ...prev, minutes: ranges[rangeIndex][itemIndex] }))
}
}
return (
<ThemedView style={styles.container}>
<View
style={[
styles.verticalSplitter,
{
height: ITEM_HEIGHT * 3, // 5 items rendered, just to have a longer scroll area
},
]}
>
{ranges.map((range, rangeIndex) => {
const paddingVertical = ITEM_HEIGHT
const contentOffset = useSharedValue(0)
return (
<FlatList
key={rangeIndex}
data={range}
contentContainerStyle={{
alignItems: 'center',
paddingVertical,
}}
keyExtractor={(item, idx) => rangeIndex + idx + item}
renderItem={props => <ListComponent {...props} contentOffset={contentOffset} />}
snapToInterval={ITEM_HEIGHT}
decelerationRate={'fast'}
overScrollMode='never'
bounces={false}
scrollEventThrottle={16}
onScroll={e => {
contentOffset.value = e.nativeEvent.contentOffset.y
}}
showsVerticalScrollIndicator={false}
onScrollEndDrag={e => handleChange(e, rangeIndex)}
onMomentumScrollEnd={e => handleChange(e, rangeIndex)}
/>
)
})}
</View>
<ThemedText>{`Output: ${output.hours} ${output.minutes} ${output.ampm}`}</ThemedText>
</ThemedView>
)
}
export default Time
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
verticalSplitter: {
width: '100%',
flexDirection: 'row',
justifyContent: 'space-evenly',
},
viewText: {
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 48,
lineHeight: 48,
fontWeight: '700',
},
})
Editor is loading...
Leave a Comment