Skip to content

API Proposal: User Event scroll function #1450

Closed
@mdjastrzebski

Description

@mdjastrzebski

@siepra is working User Event scroll API design, the code is quite advanced, so it's high time that we have a solid API with nice DX for that feature. There is no RTL's User Event API for scrolling, so we need to come up with our own. As a base for discussion, I have prepare an initial proposal.

User Event scroll API

Base case

// vertical scroll
user.scrollTo(element, { y: targetPos })

// horizontal scroll:
user.scrollTo(element, { x: targetPos })

Note: the function is named scrollTo instead of scroll to remove ambiguity whether this is target value or relative value. Coincidently this is also the name of imperative handle for scrolling in RN.

This will emit a sequence of onScrollBeginDrag, onScroll (x N), onScrollEndDrag.

By default, the first scroll will start from (0, 0) and will emit default of 5 onScroll intermediate steps between initial position and target position. Subsequent scrolls will start from where the last scroll (using User Event) ended.

Intermediate steps

Explicit steps

Alternatively, you can pass exact steps that will be called as an array. First element is the initial position, and all other elements indicate subsequent steps. The number of steps will be equal to the length of the array.

user.scrollTo(element, { y: [0, 10, 20, 30] })

Number of steps (alternative approach)

You can customize the intermediate steps by passing number of steps and/or ininitial position:

user.scrollTo(element, { y: targetPos, steps: 10 })
user.scrollTo(element, { y: targetPos, fromY: initialPos })
user.scrollTo(element, { y: targetPos, fromY: initialPos, steps: 10 })

We probably should pick only one of the above. Based on my surveys with CK devs, the first one seems to be preferred.

Momentum scroll

Momentum scroll happens after initial sequence of onScrollBeginDrag, onScroll (x N), onScrollEndDrag when scroll view has some velocity (momentum) after user lifts the finger up. This will result in calling onMomentumScrollBegin, onScroll (x N), onMomentumScrollEnd.

By default scrollBy will only invoke drag scroll without momentum part. User can activate momentum scroll passing momentumY or momentumX variables:

// vertical
user.scrollTo({ momentumY: targetPos })

// horizontal
user.scrollTo({ momentumX: targetPos })

This can be linked with previous options:

// Drag scroll from initial position to targetPos1, then momentum scroll to targetPos2
user.scrollTo({ y: targetPos1, momentumY: targetPos2 })

// Pass explicit steps and/or momentum steps
user.scrollTo({ y: [0, 10, 20], momentumY: [30, 40] })

// Control the number of drag steps using `steps`, and momentum steps using `momentumSteps` (alternative intermediate steps approach)
user.scrollTo({ y: targetPos1, momentumY: targetPos2, steps: 5, momentumSteps: 4 })

If the user did not pass drag scroll position, then distance from last position, or default (0, 0), to target position will be divided equally between drag scroll and momentum scroll.

Please share your comments on all things involved, naming of function and options, ways of conveying ideas like intermediate steps, etc, etc. Feel free to challenge this design, propose alternatives, etc. The API is very flexible at this stage, changing it later will probably require breaking changes, etc.

Links

Specific questions:

  1. Should the API be named scrollTo or scroll?
  2. What should be default number of scroll steps, if not specified by user. Similar for momentum steps?
  3. Should we support indicating number of steps using steps param, y: [0, 10, 20] array or both? Or other perhaps?
  4. How should we expose momentum scroll concept: momentumY params, momentum: boolean param, user.momentumScrollTo() function, or other perhaps?
  5. Should RNTL remember the last scroll position and start next scroll from there? Or should we always start from explicit position or (0,0) if not provided?

CC: @pierrezimmermannbam @AugustinLF @MattAgn @thymikee @siepra

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions