Add goToSlide to scrollable-slides#14477
Conversation
| * Calculates the target scroll position for the given slide index. | ||
| * @param {number} index | ||
| */ | ||
| getPosForSlideIndex_(index) { |
There was a problem hiding this comment.
Right now this implementation tries to center the target slide. If we remove the latest commit, it will try to left-align the target slide.
There was a problem hiding this comment.
I think center makes sense. we can revisit if there is interest in other docking locations.
65e44fa to
03a8466
Compare
|
|
||
| /** | ||
| * Scrolls to the slide at the given slide index. | ||
| * @param {*} value |
There was a problem hiding this comment.
nit: I would move the parseInt into the registerAction callback, that way this function can declare explicitly that it needs a number.
| this.registerAction('goToSlide', invocation => { | ||
| const args = invocation.args; | ||
| if (args) { | ||
| this.goToSlide_(args['index']); |
There was a problem hiding this comment.
Do you think this action should be chainable? Actions can return a Promise, and other subsequent actions can be made to wait for that Promise to resolve. I can see a publisher wanting to go to a slide, then do something after the carousel has finished animating to that slide. wdyt?
There was a problem hiding this comment.
tbh, I am not a big fan of our Promise-based actions since author is not in control of whether they want to chain or parallelize the actions. slidescroll version has a slideChange event. I suggest supporting that event here as well (if not supported already, not sure if it is already coded in the base class or not). With that event, authors can react after a slidechage is fully done.
There was a problem hiding this comment.
So with regards to supporting the slideChange event, in the case where the user is manually scrolling, it's not actually obvious which slide index the carousel is on. Per offline discussion, I'll trigger this event when the action is called, and leave an issue to define slide index in context of scrolling.
There was a problem hiding this comment.
Actually, per doc, we shouldn't trigger the event when the action is called:
Fired when the user manually changes the carousel's current slide. Does not fire on autoplay or the goToSlide action.
I'll file an issue for later.
There was a problem hiding this comment.
Documentation might be wrong, based on the code, I see it get fired with gotToSlide action.
There was a problem hiding this comment.
Filed: #14505 to avoid getting too greedy. Stacked the PR though.
|
For the center vs left question, @aghassemi might have better context than I do, but I think center makes sense. It's an easy change if someone opens a bug. |
| * Calculates the target scroll position for the given slide index. | ||
| * @param {number} index | ||
| */ | ||
| getPosForSlideIndex_(index) { |
There was a problem hiding this comment.
I think center makes sense. we can revisit if there is interest in other docking locations.
| * @private | ||
| */ | ||
| goToSlide_(value) { | ||
| const index = parseInt(value, 10); |
There was a problem hiding this comment.
whole function should become a measure/mutate, where getPosForSlideIndex_ is called in the measure block and start of animation is in the mutate block.
| const index = parseInt(args['index'], 10); | ||
| this.goToSlide_(index); | ||
| } | ||
| }, ActionTrust.HIGH); |
There was a problem hiding this comment.
I followed the precedence in slidescroll.js here in terms of ActionTrust. I'm not sure why this is high trust, but I imagine that the trust level should be consistent across the two carousel implementations.
There was a problem hiding this comment.
Both can become low trust given the UI changes are fully contained within the container.
There was a problem hiding this comment.
Actually I think the reason this is high trust is because we allow amp-bind for the [slide] attribute, which also must update when change the slide (no matter how). I reverted the trust change on type="slides". We can keep it low trust on type="carousel" until we implement the slideChange event and other support for amp-bind.
| }); | ||
| }; | ||
|
|
||
| this.vsync_.run({ |
There was a problem hiding this comment.
VSync will be a deprecated API soon (I'm actively removing every use). Please use BaseElement#measureMutateElement, and note that state is not supported (it doesn't help you in the this situation anyways).
There was a problem hiding this comment.
That's good to know! Could we get a wider distribution on this? I think the currently known best practice is still to use vsync for measurements and mutations.
There was a problem hiding this comment.
Added to tomorrow's deep dive.
| * @param {number} index | ||
| * @private | ||
| */ | ||
| goToSlide_(index) { |
There was a problem hiding this comment.
Can this be used anywhere else?
| mutate: mutateSlidePosition, | ||
| }, {}); | ||
| this.measureElement(() => this.getPosForSlideIndex_(index)) | ||
| .then(newPos => { |
There was a problem hiding this comment.
Note: measure.then.mutate is to take two vsync cycles (~16ms-32ms lag) to complete. You can combine them into a single #measureMutateElement call, which will complete in 1 cycle.
There was a problem hiding this comment.
Will that guarantee that the measure finishes before the mutate? Implemented the change assuming that the above is true.
158c1dc to
27cf19c
Compare
|
@jridgewell PTAL? |
|
The failing test seems legitimate. Investigating. |
|
@cathyxz In the previous commit, trust level of the slidechange "event" was changed to low. We want to keep the events high trust, just lower the goToSlide "action" on slidescroll to low trust. |
* Add goToSlide to scrollable-slides * Try to center the target slide * Wrap everything in vsync * Remove vsync, set action trust to LOW * Use measureMutateElement for shorter cycle * Revert ActionTrust change on slidescroll * Change goToSlide action to low trust
Closes #13011.
My only question here is does it make sense to scroll so that the target slide is in the center of the carousel or the left? The way I interpreted the aesthetic of the scrollable-carousel, was that the target slide was the left-most slide. But maybe I'm misinterpreting how people use them.