Skip to content

Commit 681c7a1

Browse files
authored
[MOO-1887]: Fix initial slide positioning in IntroScreen widget (#281)
2 parents 22882cd + 6cbd6b1 commit 681c7a1

File tree

9 files changed

+110
-34
lines changed

9 files changed

+110
-34
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"husky": "^8.0.3",
7070
"identity-obj-proxy": "^3.0.0",
7171
"image-js": "^0.35.6",
72+
"jest": "^29.4.1",
7273
"lint-staged": "^10.5.4",
7374
"mendix-client": "^7.15.8",
7475
"patch-package": "^8.0.0",
@@ -79,6 +80,7 @@
7980
"react-dom": "18.3.1",
8081
"recursive-copy": "^2.0.14",
8182
"rollup": "^2.79.2",
83+
"ts-jest": "^29.4.0",
8284
"ts-node": "^10.9.2"
8385
},
8486
"commitlint": {

packages/pluggableWidgets/intro-screen-native/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
99
### Fixed
1010

1111
- We have fixed defaultProps deprecation warning.
12+
- Initial slide now correctly positioned on mount.
1213

1314
## [4.0.0] - 2024-12-3
1415

packages/pluggableWidgets/intro-screen-native/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "intro-screen-native",
33
"widgetName": "IntroScreen",
4-
"version": "4.0.1",
4+
"version": "4.1.0",
55
"license": "Apache-2.0",
66
"repository": {
77
"type": "git",

packages/pluggableWidgets/intro-screen-native/src/IntroScreen.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,27 @@ export function IntroScreen(props: IntroScreenProps<IntroScreenStyle>): JSX.Elem
2424
} else {
2525
setVisible(true);
2626
}
27-
}, []);
27+
}, [props.identifier]);
28+
29+
const hideModal = useCallback((): void => {
30+
if (props.identifier) {
31+
AsyncStorage.setItem(props.identifier, "gone").then(() => setVisible(false));
32+
} else {
33+
setVisible(false);
34+
}
35+
}, [props.identifier]);
2836

2937
const onDone = useCallback(() => {
3038
hideModal();
3139
executeAction(props.onDone);
32-
}, [props.onDone]);
40+
}, [hideModal, props.onDone]);
3341

3442
const onSlideChange = useCallback(() => executeAction(props.onSlideChange), [props.onSlideChange]);
3543

3644
const onSkip = useCallback(() => {
3745
hideModal();
3846
executeAction(props.onSkip);
39-
}, [props.onSkip]);
47+
}, [hideModal, props.onSkip]);
4048

4149
const checkLabel = (label?: DynamicValue<string>): string | undefined => {
4250
if (label && label.value && label.status === ValueStatus.Available) {
@@ -45,14 +53,6 @@ export function IntroScreen(props: IntroScreenProps<IntroScreenStyle>): JSX.Elem
4553
return undefined;
4654
};
4755

48-
const hideModal = (): void => {
49-
if (props.identifier) {
50-
AsyncStorage.setItem(props.identifier, "gone").then(() => setVisible(false));
51-
} else {
52-
setVisible(false);
53-
}
54-
};
55-
5656
const showSkipPrevious = props.buttonPattern === "all";
5757
const showNextDone = props.buttonPattern !== "none";
5858

packages/pluggableWidgets/intro-screen-native/src/SwipeableContainer.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {
88
StyleSheet,
99
Text,
1010
TouchableNativeFeedback,
11+
TouchableNativeFeedbackProps,
1112
TouchableOpacity,
13+
TouchableOpacityProps,
1214
View
1315
} from "react-native";
1416
import { ButtonStyle, IntroScreenStyle } from "./ui/Styles";
@@ -43,10 +45,13 @@ interface SwipeableContainerProps {
4345
activeSlide?: EditableValue<Big>;
4446
}
4547

48+
type TouchableProps = TouchableNativeFeedbackProps | TouchableOpacityProps;
49+
4650
declare type Option<T> = T | undefined;
4751

4852
const isAndroidRTL = I18nManager.isRTL && Platform.OS === "android";
49-
const Touchable = Platform.OS === "android" ? TouchableNativeFeedback : TouchableOpacity;
53+
const Touchable: React.ComponentType<TouchableProps> =
54+
Platform.OS === "android" ? TouchableNativeFeedback : TouchableOpacity;
5055

5156
const refreshActiveSlideAttribute = (slides: SlidesType[], activeSlide?: EditableValue<Big>): number => {
5257
if (activeSlide && activeSlide.status === ValueStatus.Available && slides && slides.length > 0) {
@@ -66,12 +71,10 @@ export const SwipeableContainer = (props: SwipeableContainerProps): ReactElement
6671
const [activeIndex, setActiveIndex] = useState(0);
6772
const flatList = useRef<FlatList<any>>(null);
6873

69-
useEffect(() => {
70-
const slide = refreshActiveSlideAttribute(props.slides, props.activeSlide);
71-
if (width && props.activeSlide && props.activeSlide.status === ValueStatus.Available && slide !== activeIndex) {
72-
goToSlide(slide);
73-
}
74-
}, [props.activeSlide, activeIndex, width]);
74+
const rtlSafeIndex = useCallback(
75+
(i: number): number => (isAndroidRTL ? props.slides.length - 1 - i : i),
76+
[props.slides.length]
77+
);
7578

7679
const goToSlide = useCallback(
7780
(pageNum: number) => {
@@ -82,9 +85,16 @@ export const SwipeableContainer = (props: SwipeableContainerProps): ReactElement
8285
});
8386
}
8487
},
85-
[width, flatList]
88+
[rtlSafeIndex, width]
8689
);
8790

91+
useEffect(() => {
92+
const slide = refreshActiveSlideAttribute(props.slides, props.activeSlide);
93+
if (width && props.activeSlide?.status === ValueStatus.Available && slide !== activeIndex) {
94+
goToSlide(slide);
95+
}
96+
}, [props.activeSlide, activeIndex, width, props.slides, goToSlide]);
97+
8898
const onNextPress = (): void => {
8999
goToSlide(activeIndex + 1);
90100
onSlideChange(activeIndex + 1, activeIndex);
@@ -278,11 +288,6 @@ export const SwipeableContainer = (props: SwipeableContainerProps): ReactElement
278288
);
279289
};
280290

281-
const rtlSafeIndex = useCallback(
282-
(i: number): number => (isAndroidRTL ? props.slides.length - 1 - i : i),
283-
[props.slides.length]
284-
);
285-
286291
const onMomentumScrollEnd = useCallback(
287292
(event: NativeSyntheticEvent<any>) => {
288293
const offset = event.nativeEvent.contentOffset.x;
@@ -314,6 +319,8 @@ export const SwipeableContainer = (props: SwipeableContainerProps): ReactElement
314319
<View style={styles.flexOne}>
315320
<FlatList
316321
testID={props.testID}
322+
initialScrollIndex={refreshActiveSlideAttribute(props.slides, props.activeSlide)}
323+
getItemLayout={(_, i) => ({ length: width, offset: width * i, index: i })}
317324
ref={flatList}
318325
data={props.slides}
319326
horizontal

packages/pluggableWidgets/intro-screen-native/src/__tests__/__snapshots__/IntroScreen.notch.spec.tsx.snap

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ exports[`Intro Screen renders 1`] = `
3737
extraData={0}
3838
getItem={[Function]}
3939
getItemCount={[Function]}
40+
getItemLayout={[Function]}
4041
horizontal={true}
42+
initialScrollIndex={0}
4143
keyExtractor={[Function]}
4244
onContentSizeChange={[Function]}
4345
onLayout={[Function]}
@@ -64,7 +66,6 @@ exports[`Intro Screen renders 1`] = `
6466
<View>
6567
<View
6668
onFocusCapture={[Function]}
67-
onLayout={[Function]}
6869
style={
6970
[
7071
{
@@ -225,7 +226,9 @@ exports[`Intro Screen renders with 1 bottom button 1`] = `
225226
extraData={0}
226227
getItem={[Function]}
227228
getItemCount={[Function]}
229+
getItemLayout={[Function]}
228230
horizontal={true}
231+
initialScrollIndex={0}
229232
keyExtractor={[Function]}
230233
onContentSizeChange={[Function]}
231234
onLayout={[Function]}
@@ -252,7 +255,6 @@ exports[`Intro Screen renders with 1 bottom button 1`] = `
252255
<View>
253256
<View
254257
onFocusCapture={[Function]}
255-
onLayout={[Function]}
256258
style={
257259
[
258260
{
@@ -427,7 +429,9 @@ exports[`Intro Screen renders with 2 bottom button 1`] = `
427429
extraData={0}
428430
getItem={[Function]}
429431
getItemCount={[Function]}
432+
getItemLayout={[Function]}
430433
horizontal={true}
434+
initialScrollIndex={0}
431435
keyExtractor={[Function]}
432436
onContentSizeChange={[Function]}
433437
onLayout={[Function]}
@@ -454,7 +458,6 @@ exports[`Intro Screen renders with 2 bottom button 1`] = `
454458
<View>
455459
<View
456460
onFocusCapture={[Function]}
457-
onLayout={[Function]}
458461
style={
459462
[
460463
{
@@ -629,7 +632,9 @@ exports[`Intro Screen renders with active slide attribute 1`] = `
629632
extraData={0}
630633
getItem={[Function]}
631634
getItemCount={[Function]}
635+
getItemLayout={[Function]}
632636
horizontal={true}
637+
initialScrollIndex={0}
633638
keyExtractor={[Function]}
634639
onContentSizeChange={[Function]}
635640
onLayout={[Function]}
@@ -656,7 +661,6 @@ exports[`Intro Screen renders with active slide attribute 1`] = `
656661
<View>
657662
<View
658663
onFocusCapture={[Function]}
659-
onLayout={[Function]}
660664
style={
661665
[
662666
{

packages/pluggableWidgets/intro-screen-native/src/__tests__/__snapshots__/IntroScreen.spec.tsx.snap

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ exports[`Intro Screen renders 1`] = `
3737
extraData={0}
3838
getItem={[Function]}
3939
getItemCount={[Function]}
40+
getItemLayout={[Function]}
4041
horizontal={true}
42+
initialScrollIndex={0}
4143
keyExtractor={[Function]}
4244
onContentSizeChange={[Function]}
4345
onLayout={[Function]}
@@ -64,7 +66,6 @@ exports[`Intro Screen renders 1`] = `
6466
<View>
6567
<View
6668
onFocusCapture={[Function]}
67-
onLayout={[Function]}
6869
style={
6970
[
7071
{
@@ -225,7 +226,9 @@ exports[`Intro Screen renders with 1 bottom button 1`] = `
225226
extraData={0}
226227
getItem={[Function]}
227228
getItemCount={[Function]}
229+
getItemLayout={[Function]}
228230
horizontal={true}
231+
initialScrollIndex={0}
229232
keyExtractor={[Function]}
230233
onContentSizeChange={[Function]}
231234
onLayout={[Function]}
@@ -252,7 +255,6 @@ exports[`Intro Screen renders with 1 bottom button 1`] = `
252255
<View>
253256
<View
254257
onFocusCapture={[Function]}
255-
onLayout={[Function]}
256258
style={
257259
[
258260
{
@@ -427,7 +429,9 @@ exports[`Intro Screen renders with 2 bottom button 1`] = `
427429
extraData={0}
428430
getItem={[Function]}
429431
getItemCount={[Function]}
432+
getItemLayout={[Function]}
430433
horizontal={true}
434+
initialScrollIndex={0}
431435
keyExtractor={[Function]}
432436
onContentSizeChange={[Function]}
433437
onLayout={[Function]}
@@ -454,7 +458,6 @@ exports[`Intro Screen renders with 2 bottom button 1`] = `
454458
<View>
455459
<View
456460
onFocusCapture={[Function]}
457-
onLayout={[Function]}
458461
style={
459462
[
460463
{
@@ -629,7 +632,9 @@ exports[`Intro Screen renders with active slide attribute 1`] = `
629632
extraData={0}
630633
getItem={[Function]}
631634
getItemCount={[Function]}
635+
getItemLayout={[Function]}
632636
horizontal={true}
637+
initialScrollIndex={0}
633638
keyExtractor={[Function]}
634639
onContentSizeChange={[Function]}
635640
onLayout={[Function]}
@@ -656,7 +661,6 @@ exports[`Intro Screen renders with active slide attribute 1`] = `
656661
<View>
657662
<View
658663
onFocusCapture={[Function]}
659-
onLayout={[Function]}
660664
style={
661665
[
662666
{

packages/pluggableWidgets/intro-screen-native/src/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<package xmlns="http://www.mendix.com/package/1.0/">
3-
<clientModule name="IntroScreen" version="4.0.1" xmlns="http://www.mendix.com/clientModule/1.0/">
3+
<clientModule name="IntroScreen" version="4.1.0" xmlns="http://www.mendix.com/clientModule/1.0/">
44
<widgetFiles>
55
<widgetFile path="IntroScreen.xml" />
66
</widgetFiles>

0 commit comments

Comments
 (0)