@@ -23,17 +23,67 @@ export const Carousel = (props: CarouselProps<CarouselStyle>): ReactElement => {
23
23
24
24
const [ activeSlide , setActiveSlide ] = useState ( 0 ) ;
25
25
26
+ const [ firstItem , setFirstItem ] = useState ( 0 ) ;
27
+
26
28
const [ loading , setLoading ] = useState ( true ) ;
27
29
28
30
useEffect ( ( ) => {
29
- if ( props . contentSource ?. status === ValueStatus . Available ) {
31
+ if ( props . contentSource ?. status === ValueStatus . Available && loading ) {
32
+ // Set initial index of the first item to show the associated active selection.
33
+ const index =
34
+ ( props . activeSelection ?. value
35
+ ? props . contentSource ?. items ?. findIndex ( i => i . id === props . activeSelection ?. value ?. id )
36
+ : 0 ) ?? 0 ;
37
+ setFirstItem ( index ) ;
38
+ setActiveSlide ( index ) ;
30
39
setLoading ( false ) ;
31
40
}
32
- } , [ props . contentSource ] ) ;
41
+ } , [ loading , props . activeSelection , props . contentSource ] ) ;
33
42
34
- const onSnap = useCallback ( ( index : number ) => {
35
- setActiveSlide ( index ) ;
36
- } , [ ] ) ;
43
+ useEffect ( ( ) => {
44
+ if ( carouselRef && props . activeSelection ) {
45
+ let index = props . contentSource . items ?. findIndex ( i => i . id === props . activeSelection ?. value ?. id ) ?? 0 ;
46
+ // Removed item that is active selection can not be found
47
+ index = index >= 0 ? index : 0 ;
48
+ // Should check carouselRef.currentIndex though this is not fast enough for update.
49
+ if ( index !== activeSlide ) {
50
+ // Update carousel when associated item is changed
51
+ setActiveSlide ( index ) ;
52
+ const animate = props . animateExpression ?. value ?? true ;
53
+ // Async snap to index, use case add item is added before current selected
54
+ setTimeout ( ( ) => {
55
+ ( carouselRef as NativeCarousel < ObjectItem > ) . snapToItem ( index , animate ) ;
56
+ } , 1 ) ;
57
+ }
58
+ }
59
+ } , [ activeSlide , carouselRef , props . activeSelection , props . animateExpression , props . contentSource ] ) ;
60
+
61
+ useEffect ( ( ) => {
62
+ if ( props . activeSelection ) {
63
+ // Check if selected item is still available, reset to index 0 or null
64
+ let item = props . contentSource . items ?. find ( i => i . id === props . activeSelection ?. value ?. id ) ;
65
+ if ( item == null ) {
66
+ item = props . contentSource . items ?. [ 0 ] ;
67
+ }
68
+ if ( props . activeSelection . value ?. id !== item ?. id ) {
69
+ // Set association when empty to first slide
70
+ props . activeSelection . setValue ( item ) ;
71
+ }
72
+ }
73
+ } , [ props . activeSelection , props . contentSource ] ) ;
74
+
75
+ const onSnap = useCallback (
76
+ ( index : number ) => {
77
+ setActiveSlide ( index ) ;
78
+ if ( props . activeSelection ) {
79
+ const item = props . contentSource ?. items ?. [ index ] ;
80
+ if ( item ?. id !== props . activeSelection . value ?. id ) {
81
+ props . activeSelection . setValue ( item ) ;
82
+ }
83
+ }
84
+ } ,
85
+ [ props . activeSelection , props . contentSource ]
86
+ ) ;
37
87
38
88
const renderItem = useCallback ( ( { item, index } : { item : ObjectItem ; index : number } ) => {
39
89
const viewStyle = layoutSpecificStyle . slideItem ;
@@ -97,7 +147,7 @@ export const Carousel = (props: CarouselProps<CarouselStyle>): ReactElement => {
97
147
) ;
98
148
} , [ activeSlide , carouselRef , props . contentSource , props . showPagination ] ) ;
99
149
100
- const onLayout = ( event : LayoutChangeEvent ) => {
150
+ const onLayout = ( event : LayoutChangeEvent ) : void => {
101
151
let viewHeight = event . nativeEvent . layout . height ;
102
152
const viewWidth = event . nativeEvent . layout . width ;
103
153
@@ -149,7 +199,7 @@ export const Carousel = (props: CarouselProps<CarouselStyle>): ReactElement => {
149
199
testID = { `${ props . name } $carousel` }
150
200
activeSlideAlignment = { props . activeSlideAlignment }
151
201
layout = "default"
152
- firstItem = { 0 }
202
+ firstItem = { firstItem }
153
203
useScrollView
154
204
enableSnap
155
205
data = { props . contentSource . items }
0 commit comments