-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to pass contentSize
and layoutMeasurement
when calling scrollTo
#1543
Changes from 2 commits
12a5335
3f10d73
6e2e6c2
a021500
711722e
c1f58dd
1b16e92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,14 +7,27 @@ import { isHostScrollView } from '../../helpers/host-component-names'; | |
import { pick } from '../../helpers/object'; | ||
import { dispatchEvent, wait } from '../utils'; | ||
import { ContentOffset } from '../event-builder/scroll-view'; | ||
import fireEvent from '../../fire-event'; | ||
import { | ||
createScrollSteps, | ||
inertialInterpolator, | ||
linearInterpolator, | ||
} from './utils'; | ||
import { getElementScrollOffset, setElementScrollOffset } from './state'; | ||
|
||
export interface VerticalScrollToOptions { | ||
interface CommonScrollToOptions { | ||
contentSize?: { | ||
height: number; | ||
width: number; | ||
}; | ||
|
||
layoutMeasurement?: { | ||
height: number; | ||
width: number; | ||
}; | ||
} | ||
|
||
export interface VerticalScrollToOptions extends CommonScrollToOptions { | ||
y: number; | ||
momentumY?: number; | ||
|
||
|
@@ -23,7 +36,7 @@ export interface VerticalScrollToOptions { | |
momentumX?: never; | ||
} | ||
|
||
export interface HorizontalScrollToOptions { | ||
export interface HorizontalScrollToOptions extends CommonScrollToOptions { | ||
x: number; | ||
momentumX?: number; | ||
|
||
|
@@ -50,31 +63,46 @@ export async function scrollTo( | |
|
||
ensureScrollViewDirection(element, options); | ||
|
||
emitContentSizeChangeEvent(element, options); | ||
|
||
const initialPosition = getElementScrollOffset(element); | ||
const dragSteps = createScrollSteps( | ||
{ y: options.y, x: options.x }, | ||
initialPosition, | ||
linearInterpolator | ||
); | ||
await emitDragScrollEvents(this.config, element, dragSteps); | ||
await emitDragScrollEvents(this.config, element, dragSteps, options); | ||
|
||
const momentumStart = dragSteps.at(-1) ?? initialPosition; | ||
const momentumSteps = createScrollSteps( | ||
{ y: options.momentumY, x: options.momentumX }, | ||
momentumStart, | ||
inertialInterpolator | ||
); | ||
await emitMomentumScrollEvents(this.config, element, momentumSteps); | ||
await emitMomentumScrollEvents(this.config, element, momentumSteps, options); | ||
|
||
const finalPosition = | ||
momentumSteps.at(-1) ?? dragSteps.at(-1) ?? initialPosition; | ||
setElementScrollOffset(element, finalPosition); | ||
} | ||
|
||
function emitContentSizeChangeEvent( | ||
element: ReactTestInstance, | ||
options: ScrollToOptions | ||
) { | ||
fireEvent( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Should I also change the signature of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair point, I'll add some dispatch function for such cases. |
||
element, | ||
'contentSizeChange', | ||
options.contentSize?.width ?? 0, | ||
options.contentSize?.height ?? 0 | ||
); | ||
} | ||
|
||
async function emitDragScrollEvents( | ||
config: UserEventConfig, | ||
element: ReactTestInstance, | ||
scrollSteps: ContentOffset[] | ||
scrollSteps: ContentOffset[], | ||
scrollOptions: ScrollToOptions | ||
) { | ||
if (scrollSteps.length === 0) { | ||
return; | ||
|
@@ -84,7 +112,7 @@ async function emitDragScrollEvents( | |
dispatchEvent( | ||
element, | ||
'scrollBeginDrag', | ||
EventBuilder.ScrollView.scroll(scrollSteps[0]) | ||
EventBuilder.ScrollView.scroll(scrollSteps[0], scrollOptions) | ||
); | ||
|
||
// Note: experimentally, in case of drag scroll the last scroll step | ||
|
@@ -95,7 +123,7 @@ async function emitDragScrollEvents( | |
dispatchEvent( | ||
element, | ||
'scroll', | ||
EventBuilder.ScrollView.scroll(scrollSteps[i]) | ||
EventBuilder.ScrollView.scroll(scrollSteps[i], scrollOptions) | ||
); | ||
} | ||
|
||
|
@@ -104,14 +132,15 @@ async function emitDragScrollEvents( | |
dispatchEvent( | ||
element, | ||
'scrollEndDrag', | ||
EventBuilder.ScrollView.scroll(lastStep) | ||
EventBuilder.ScrollView.scroll(lastStep, scrollOptions) | ||
); | ||
} | ||
|
||
async function emitMomentumScrollEvents( | ||
config: UserEventConfig, | ||
element: ReactTestInstance, | ||
scrollSteps: ContentOffset[] | ||
scrollSteps: ContentOffset[], | ||
scrollOptions: ScrollToOptions | ||
) { | ||
if (scrollSteps.length === 0) { | ||
return; | ||
|
@@ -121,7 +150,7 @@ async function emitMomentumScrollEvents( | |
dispatchEvent( | ||
element, | ||
'momentumScrollBegin', | ||
EventBuilder.ScrollView.scroll(scrollSteps[0]) | ||
EventBuilder.ScrollView.scroll(scrollSteps[0], scrollOptions) | ||
); | ||
|
||
// Note: experimentally, in case of momentum scroll the last scroll step | ||
|
@@ -132,7 +161,7 @@ async function emitMomentumScrollEvents( | |
dispatchEvent( | ||
element, | ||
'scroll', | ||
EventBuilder.ScrollView.scroll(scrollSteps[i]) | ||
EventBuilder.ScrollView.scroll(scrollSteps[i], scrollOptions) | ||
); | ||
} | ||
|
||
|
@@ -141,7 +170,7 @@ async function emitMomentumScrollEvents( | |
dispatchEvent( | ||
element, | ||
'momentumScrollEnd', | ||
EventBuilder.ScrollView.scroll(lastStep) | ||
EventBuilder.ScrollView.scroll(lastStep, scrollOptions) | ||
); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ The sequencing of this event matches our experiments with RN runtime:
https://github.com/callstack/react-native-testing-library/wiki/ScrollView-Events