-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
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(theme-classic): new navbar item linking to a sidebar #6139
Conversation
…lSidebar() function and getFirstDocIdOfSidebar() function, modified GlobalVersion and toGlobalVersion
…em with 'docSidebar' type, added validation in validateThemeConfig.ts
…where it didn't work with undefined category link object
✔️ [V2] 🔨 Explore the source changes: bcd01a9 🔍 Inspect the deploy log: https://app.netlify.com/sites/docusaurus-2/deploys/61d6b982fd35090007725ff4 😎 Browse the preview: https://deploy-preview-6139--docusaurus-2.netlify.app |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-6139--docusaurus-2.netlify.app/ |
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, thanks for the amazing work done! The tests you've made have made the review so much easier. The comments are mostly about code style.
Could you also add unit tests for the getFirstDocIdOfSidebar
function, and update the existing test snapshots?
Also, we can test this on our website. The API
item can be linking to the api
sidebar.
I'll be working on this for now
Our current implementation differs slightly from what @slorber envisioned in that issue. The global data is set as |
@lmpham1 Thanks! Now it's just docs left. You can just go add docs in this PR instead of creating a new one. |
@Josh-Cena hey, I just added the documentation for our new navbar item type in |
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.
LGTM! Waiting on @slorber since I did change the API design a bit
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, that looks like a good first version!
There are a few issues that we should fix before merging.
What about dogfooding this feature on our own site? We can replace our docs/api tabs by this new navbar items, this would help to review/validate it works fine
@@ -266,6 +276,45 @@ Available document ids are: | |||
} | |||
} | |||
|
|||
function getFirstDocOfSidebar(sidebar: Sidebar): |
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.
What about refactor to following signature?
function findFirstLink(sidebar: Sidebar): {label: string, path: string} | undefined
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.
So to make this function return the doc's path, I passed into it a LoadedVersion
object to look up the doc's permalink:
function findFirstLink(sidebar: Sidebar, version: LoadedVersion): { label: string; path: string } | undefined
I just refactored the function in my recent commit. Let me know if you think this is a good approach, or if you think it's a bit overkill to pass LoadedVersion
into this function.
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 it's overkill. Passing in such a big entity makes this function very hard to reason about and optimize in the future. I prefer the initial implementation: the return type is a bit complicated, but it's lightweight and easy to be piped into other processing.
I reverted that refactor commit. Sorry for this but I do have some opinions on what sidebarUtils
should do. It should strictly be a pure function operating on the sidebar and nothing else. Hooking into the version information is always overkill and should be done where it's actually needed.
packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx
Outdated
Show resolved
Hide resolved
packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx
Outdated
Show resolved
Hide resolved
{...props} | ||
className={clsx(props.className, { | ||
[activeDocInfimaClassName]: | ||
activeDoc?.sidebar && activeDoc.sidebar === sidebarId, |
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.
activeDoc?.sidebar && activeDoc.sidebar === sidebarId, | |
activeDoc?.sidebar === sidebarId, |
Should be fine considering sidebarId is mandatory
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.
Wonder if the item would be highlighted when we browse a category index 🤪
packages/docusaurus-theme-classic/src/theme/NavbarItem/DocSidebarNavbarItem.tsx
Outdated
Show resolved
Hide resolved
…barNavbarItem.tsx Co-authored-by: Sébastien Lorber <[email protected]>
…le to look for sidebars in all version
@@ -15,11 +15,19 @@ import {useDocsPreferredVersion, uniq} from '@docusaurus/theme-common'; | |||
import type {GlobalDataVersion} from '@docusaurus/plugin-content-docs'; | |||
|
|||
function getSidebarInVersion(versions: GlobalDataVersion[], sidebarId: string) { | |||
const allSidebars = versions.flatMap((version) => version.sidebars); | |||
const allSidebars = versions.map((version) => version.sidebars); |
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 use a flat 1-level array here. You can create an array of sidebar entries [sidebarId,sidebar]
const allSidebars = versions.flatMap((version) => Object.entries(version.sidebars));
This makes the following code simpler:
const sidebarEntry = allSidebars.find((sidebarEntry) => sidebarEntry[0] === sidebarId)
return sidebarItem ? sidebarItem[1] : undefined; | ||
} | ||
return undefined; | ||
})[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.
that does not look like a good algo to me (result might not be at index 0, at least you'd want to "compact" the array and remove undefined values) and this is too complex to read. See my suggestion above
…refactor getSidebarLink in DocSidebarNavbarItem
…malink from within the function
…oc's permalink from within the function" This reverts commit 3192dcb. Signed-off-by: Joshua Chen <[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.
Looks almost good, just minor changes 👍
exact | ||
{...props} | ||
className={clsx(props.className, { | ||
[activeDocInfimaClassName]: activeDoc?.sidebar === sidebarId, |
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, this does not work with "generated index", but it's not a problem with current PR, see #6268
We can solve this separately
Co-authored-by: Sébastien Lorber <[email protected]>
LGTM, thanks ! |
Motivation
This PR resolves #6117
Have you read the Contributing Guidelines on pull requests?
Yes.
Implementations
For the
plugin-content-doc
, I wrote 2 functions:getFirstDocIdOfSidebar
inplugin-content-doc/src/sidebars/utils.ts
, which receives aSidebar
object and returns the docId of that object. If it's a category with autogenerated index, the slug of that index page will be returned instead.toGlobalSidebar
inplugin-content-doc/src/globalData.ts
, which map the sidebar name and docId returned fromgetFirstDocIdOfSidebar
function to aGlobalSidebar
object, which is then attached to aGlobalVersion
object intoGlobalVersion
functionFor
theme-classic/src/theme/NavbarItem
, I added a new item calledDocSidebarNavbarItem
that handle the new navbar item type. It does so by fetching theGlobalVersion
object, and retrieve itsGlobalSidebar
data that already contain aGlobalSidebarLink
pointing to its first documentTest Plan
To test my changes, I modified the sidebar and navbar objects in the
docusaurus.config.js
andsidebar.js
files in/website/
. These changes are not included in this PR, but I have created a separate test branch on my fork with these changes so that you can test it there.The detailed changes:
I also created a demo video with the exact changes above: https://youtu.be/BtJ3306urjI
I also tested category with a doc link, as well as without a category link object, and they also seem to be working.
Related PRs
Might require updating the documentation to include this new feature if this PR is merged.
Feel free to let me know if you want any changes to be made!