-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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(v2): auto focus to tab if it is outside viewport #4209
Conversation
return top >= 0 && right <= innerWidth && bottom <= innerHeight && left >= 0; | ||
} | ||
|
||
export const domUtils = new Proxy( |
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 decided to use proxy to simplify checking the DOM environment (otherwise it was necessary to include duplicated check condition in each util function).
Is this an acceptable solution or should we use the "traditional" option?
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 prefer the traditional option, Proxy complicates things for little value and will also mess-up with the TypeScript support that we want to improve in the long term.
[V1] Deploy preview success Built with commit b9583f3 |
Size Change: +196 B (0%) Total Size: 532 kB
ℹ️ View Unchanged
|
Deploy preview for docusaurus-2 ready! Built with commit b9583f3 |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-4209--docusaurus-2.netlify.app/classic/ |
@slorber please take a look at this PR. I would like to see it in new release. |
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 think the solution and code added to solve the problem is too complex and suggested a simpler solution.
In my opinion the current implementation of Tabs is not very good, not idiomatic React, and should be refactored totally in the future. I'd preferably like to avoid adding too much complexity to tabs so that a future refactoring would be simpler to achieve, and so that we can invest in the ideal solution instead of a good enough one
return top >= 0 && right <= innerWidth && bottom <= innerHeight && left >= 0; | ||
} | ||
|
||
export const domUtils = new Proxy( |
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 prefer the traditional option, Proxy complicates things for little value and will also mess-up with the TypeScript support that we want to improve in the long term.
window.scrollBy(0, -navbarHeight); | ||
} | ||
}, 50); | ||
}, 150); |
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.
In an ideal world we'd want the mouse cursor to stay above the tab we just clicked without the user seeing things scroll (using useLayoutEffect), but this is more complex to achieve.
As your solution is not the ideal solution, but more a "best effort, good enough", and I think it's a bit too complicated for little value.
Something like this is simpler and even better in my opinion:
if (groupId != null) {
setTabGroupChoices(groupId, selectedTabValue);
setTimeout(() => {
if (domUtils.isInViewport(selectedTab)) {
return;
}
selectedTab.scrollIntoView({
block: 'center',
behavior: 'smooth',
});
}, 150);
}
block start is not the best for me because the user will click on a tab in the middle of the screen and that tab will appear at the very top of the screen afterward. Without animation, he may struggle to understand what is happening. Centering the tab makes more sense to me and handle the collapsible scrollbar at the same time with less complexity and much less code to ship/maintain
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.
Alright, so I also added a short blicker on the active tab item to point the user to the correct tab. Or do you think this is superfluous?
Changed behavior:
I have not reverted the other code. For example, managing the state of the hideable navbar is useful to us to fix a bug with docsearch (after closing the search modal, the navbar is closed for some reason).
dfd4538
to
05d9947
Compare
domUtils.convertRemToPx( | ||
domUtils.getPropertyValue('--ifm-navbar-height'), | ||
)) || | ||
0; |
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.
Does it give a different height compared to before?
I feel this solution is more complex, more likely to break (for example if we change the rem unit to something else) and more expensive to run.
Isn't reading the stylesheet in render expensive?
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.
As understand, these functions have about the same effect on performance, but I agree with you, so I simplified the solution as you suggested above.
animation: blink 0.5s ease-in-out 5; | ||
} | ||
|
||
@keyframes blink { |
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.
Not sure that this animation looks good, so it might be worth removing.
LGTM, just fixed a typo add()->remove() |
Motivation
Trying to fix #3728
Currently, the thing is if tab sync is enabled, and going to switch from long-content tab to short one, we will not see a new tab on the screen. This is confusing for users and they have to manually scroll to the desired tab.
I suggest avoiding this unpleasant action by automatically focusing on the tab, but only if really necessary (when the new tab is outside the viewport).
I intentionally didn't do this via the new prop because it's a useful UX improvement that anyone using the synching tabs feature will need.
To achieve this, we had to move hideable navbar state to the context provider (by analogy with the announcement bar).
Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
Used code for test
Related PRs
(If this PR adds or changes functionality, please take some time to update the docs at https://github.com/facebook/docusaurus, and link to your PR here.)