-
Notifications
You must be signed in to change notification settings - Fork 398
refactor(toc): use cdkScrollable for scrolling, remove unnecessary inputs #321
base: main
Are you sure you want to change the base?
Conversation
if (target) { | ||
target.scrollIntoView(); | ||
} | ||
contentReady(): void { |
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.
I'd rather name this method for what it does rather than when it's called
} | ||
/** Find the target from the url fragment and scroll it into view. */ | ||
private scrollFragmentIntoView(): void { | ||
this._ngZone.runTask(() => { |
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.
Why does this need to enter the zone if it's only updating the scroll position?
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.
Oops that was leftover from debugging something else. Removed.
this._ngZone.runTask(() => { | ||
const target = document.getElementById(this._urlFragment); | ||
if (target) { | ||
// scrollIntoView may require next macrotask if target has just been loaded |
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.
I don't quite follow why this is necessary; the document-viewer
knows exactly when the content is loaded and in the DOM
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.
Without it, scroll position would always end up at the top of the page (can be seen here).
However I now recall that there was some other component that manually updates the scroll position. I'll try to track down any sort of race condition occurring there.
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.
Yeah it's conflicting with the navigation focus directive,
ngOnInit() { | |
clearTimeout(lastTimeoutId); | |
// 100ms timeout is used to allow the page to settle before moving focus for screen readers. | |
lastTimeoutId = setTimeout(() => this.el.nativeElement.focus(), 100); | |
} |
EDIT: actually not so sure
EDIT 2: It was the component overview doing the auto focus, not the navigation focus directive
d748a50
to
5ad187b
Compare
@jelbourn ready for another review. The component overview and component api components were autofocusing the visually hidden element at the top after 100ms. I've changed them to wait until the content has loaded, but before the TOC scrolls the correct header into view. Would it be better for a11y to place focus on the header link when the fragment does exist? |
@willshowell Yeah, if there is a fragment then the autofocus should be on the header for that fragment. I think that was just an oversight when doing the autofocus. Would you be interested in addressing that in this PR? |
@jelbourn Ugh I thought I'd be able to easily, but I'm hitting some strange behavior where |
@amcdnl can you review? |
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.
Looks good overall, just one suggestion for lettables.
import {Subject} from 'rxjs/Subject'; | ||
import 'rxjs/add/operator/filter'; |
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.
Lets use Rx Lettables here. I have a PR to transform the rest of them in the app.
… subscribing to events on container - Remove links as an input - Calculate container from scrollable event instead of using input
- Unfortunately seems to require setTimeout... Postponing to next microtask does not work (Promise.resolve)
5ad187b
to
0369155
Compare
_activeLinkIndex
to ensure only a single link is active at a time (removesactive
from link interface)links
Note: this still does not work for toc on the guides pages. I thought scrolling would be on the window and therefore be picked up by the scroll dispatcher, but that does not seem to be the case.
cc @jelbourn