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