-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
feat(core): route announcer #7074
Conversation
By doing this, client-side route changes will be announced to screen readers, improving accessibility to screen-reader users. This was heavily inspired by https://github.com/vercel/next.js/blob/canary/packages/next/client/route-announcer.tsx. Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
✅ [V2]Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site settings. |
⚡️ Lighthouse report for the deploy preview of this PR
|
I have dived in the codebase, and it looks like it has a 1000 second wait time before a new route can load. Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Someone suggested to put it in App.tsx instead of `@theme/Root`. Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
In my testing 50ms is ok to me. You may change it if it something goes wrong. Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
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.
Thanks, seems to work great 👍 Will leave it to others to review as well. Left some more suggestions.
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Someone suggested to this to adjust some code and to prevent blocked on an external dep as commented. Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
The timeout unfortunately doesn't work if the network is slow and the bundle preloading takes more than 50ms. I think this should better be implemented as a client module since it seems pretty decoupled from the main app. We can do this after fixing #6732 |
…-- similarly to gatsby 4 Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
Signed-off-by: Shinwon Elizabeth Yoon <[email protected]>
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 current behavior looks cool to me. I still somehow believe this can be factored out into a separate client module and not in the main component tree (since all it does is consuming the location and portaling to a DOM element), but I'll let @slorber take a look first. At least now we can be unblocked from #6732
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.
Perhaps we should move this component to the classic-theme area to make related message translatable?
I agree. Given the current architecture, it seems feasible to put this in layout as well. |
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.
Hey, looks like an interesting addition.
I don't know how route announcement is supposed to be implemented theoretically, can you explain, please? Particularly the thing about using a custom element, a portal, rAF...
I don't understand a few choices in this PR that looks weird to me, but maybe I'm wrong
The announcement label template should rather be translatable, and this does not really belong in core
Maybe this feature could be a route announcement plugin using a client module?
|
||
export function Portal({ | ||
children, | ||
type = 'docusaurus-portal', |
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.
are other portal types planned?
What is the purpose of calling document.createElement("docusaurus-portal");
?
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.
@slorber This is the container node's tag name. Portal elements can often be custom elements so as not to have any default user-agent styles.
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.
@slorber @lex111 I've move the announcer implementation to theme-classic so we can translate it. Because the client module has just been fixed, I decided to go with a pure-DOM solution without wiring it to a theme component, so that we have a use-case of reading and manipulating DOM in client module. I doubt if anyone wants to swizzle the announcement anyways. I've kept the Portal
core component for now, although we don't use it anymore, in case it's useful in the future. Tell me what you think.
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#docusaurus-route-announcer-content { |
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.
Using an ID selector here. Not sure if we necessarily want a class name here, or if we want to use inline styles.
const announcerContainer = document.createElement( | ||
'docusaurus-route-announcer', | ||
); | ||
const announcement = document.createElement('p'); | ||
Object.assign(announcement, { | ||
ariaLive: 'assertive', // Make the announcement immediately. | ||
id: 'docusaurus-route-announcer-content', | ||
role: 'alert', | ||
}); |
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.
Pure DOM manipulation. Because client modules don't have access to the React context, it would be quite cumbersome if we want to use React to do this. The alternative will be to put this in Layout
, but there may be other edge-cases (for example, the layout doesn't re-mount between doc pages)
@@ -49,6 +48,7 @@ const EXPECTED_CSS_MARKERS = [ | |||
|
|||
// Lazy-loaded lib | |||
'.DocSearch-Modal', | |||
'.DocSearch-Hit-content-wrapper', |
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'm surprised that this moved, but it makes more sense this way? Not sure why it was loaded so early before.
return dispatchLifecycleAction('onRouteDidUpdate', { | ||
previousLocation, | ||
location, | ||
}); |
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.
Exposed the cleanup function here, so we can clean up the side-effect of appending DOM child.
Motivation
By doing this, client-side route changes will be announced to screen readers, improving accessibility to screen-reader users.
This was heavily inspired by https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/navigation.js#L173-L202.
Have you read the Contributing Guidelines on pull requests?
yes
Test Plan
Related PRs
N/A