mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-20 09:33:21 +00:00
Preserve current variant when navigating between sections (#3306)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": minor
|
||||
---
|
||||
|
||||
Best effort at preserving current variant when navigating between sections by matching the pathname against site spaces in the new section.
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { SiteSpace } from '@gitbook/api';
|
||||
|
||||
import { getSiteSpaceURL } from '@/lib/sites';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import { joinPath } from '@/lib/paths';
|
||||
import type { GitBookSiteContext } from '@v2/lib/context';
|
||||
import { DropdownChevron, DropdownMenu } from './DropdownMenu';
|
||||
import { SpacesDropdownMenuItem } from './SpacesDropdownMenuItem';
|
||||
@@ -14,7 +13,6 @@ export function SpacesDropdown(props: {
|
||||
className?: string;
|
||||
}) {
|
||||
const { context, siteSpace, siteSpaces, className } = props;
|
||||
const { linker } = context;
|
||||
|
||||
return (
|
||||
<DropdownMenu
|
||||
@@ -73,9 +71,7 @@ export function SpacesDropdown(props: {
|
||||
variantSpace={{
|
||||
id: otherSiteSpace.id,
|
||||
title: otherSiteSpace.title,
|
||||
url: otherSiteSpace.urls.published
|
||||
? linker.toLinkForContent(otherSiteSpace.urls.published)
|
||||
: getFallbackSiteSpaceURL(otherSiteSpace, context),
|
||||
url: getSiteSpaceURL(context, otherSiteSpace),
|
||||
}}
|
||||
active={otherSiteSpace.id === siteSpace.id}
|
||||
/>
|
||||
@@ -83,14 +79,3 @@ export function SpacesDropdown(props: {
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the site is not published yet, `urls.published` is not available.
|
||||
* To ensure navigation works in preview, we compute a relative URL from the siteSpace path.
|
||||
*/
|
||||
function getFallbackSiteSpaceURL(siteSpace: SiteSpace, context: GitBookSiteContext) {
|
||||
const { linker, sections } = context;
|
||||
return linker.toPathInSite(
|
||||
sections?.current ? joinPath(sections.current.path, siteSpace.path) : siteSpace.path
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getSectionURL, getSiteSpaceURL } from '@/lib/sites';
|
||||
import type { SiteSection, SiteSectionGroup } from '@gitbook/api';
|
||||
import type { GitBookSiteContext, SiteSections } from '@v2/lib/context';
|
||||
|
||||
@@ -46,15 +47,35 @@ export function encodeClientSiteSections(context: GitBookSiteContext, sections:
|
||||
}
|
||||
|
||||
function encodeSection(context: GitBookSiteContext, section: SiteSection) {
|
||||
const { linker } = context;
|
||||
return {
|
||||
id: section.id,
|
||||
title: section.title,
|
||||
description: section.description,
|
||||
icon: section.icon,
|
||||
object: section.object,
|
||||
url: section.urls.published
|
||||
? linker.toLinkForContent(section.urls.published)
|
||||
: linker.toPathInSite(section.path),
|
||||
url: findBestTargetURL(context, section),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the best default site space to navigate to for a givent section:
|
||||
* 1. If we are on the default, continue on the default.
|
||||
* 2. If a site space has the same path as the current one, return it.
|
||||
* 3. Otherwise, return the default one.
|
||||
*/
|
||||
function findBestTargetURL(context: GitBookSiteContext, section: SiteSection) {
|
||||
const { siteSpace: currentSiteSpace } = context;
|
||||
|
||||
if (section.siteSpaces.length === 1 || currentSiteSpace.default) {
|
||||
return getSectionURL(context, section);
|
||||
}
|
||||
|
||||
const bestMatch = section.siteSpaces.find(
|
||||
(siteSpace) => siteSpace.path === currentSiteSpace.path
|
||||
);
|
||||
if (bestMatch) {
|
||||
return getSiteSpaceURL(context, bestMatch);
|
||||
}
|
||||
|
||||
return getSectionURL(context, section);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { SiteSection, SiteSectionGroup, SiteSpace, SiteStructure } from '@gitbook/api';
|
||||
import type { GitBookSiteContext } from '@v2/lib/context';
|
||||
import { joinPath } from './paths';
|
||||
|
||||
/**
|
||||
* Get all sections from a site structure.
|
||||
@@ -64,6 +66,34 @@ export function findSiteSpaceById(siteStructure: SiteStructure, spaceId: string)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL to navigate to for a section.
|
||||
* When the site is not published yet, `urls.published` is not available.
|
||||
* To ensure navigation works in preview, we compute a relative URL from the siteSection path.
|
||||
*/
|
||||
export function getSectionURL(context: GitBookSiteContext, section: SiteSection) {
|
||||
const { linker } = context;
|
||||
return section.urls.published
|
||||
? linker.toLinkForContent(section.urls.published)
|
||||
: linker.toPathInSite(section.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL to navigate to for a site space.
|
||||
* When the site is not published yet, `urls.published` is not available.
|
||||
* To ensure navigation works in preview, we compute a relative URL from the siteSpace path.
|
||||
*/
|
||||
export function getSiteSpaceURL(context: GitBookSiteContext, siteSpace: SiteSpace) {
|
||||
const { linker, sections } = context;
|
||||
if (siteSpace.urls.published) {
|
||||
return linker.toLinkForContent(siteSpace.urls.published);
|
||||
}
|
||||
|
||||
return linker.toPathInSite(
|
||||
sections?.current ? joinPath(sections.current.path, siteSpace.path) : siteSpace.path
|
||||
);
|
||||
}
|
||||
|
||||
function findSiteSpaceByIdInSections(sections: SiteSection[], spaceId: string): SiteSpace | null {
|
||||
for (const section of sections) {
|
||||
const siteSpace =
|
||||
|
||||
Reference in New Issue
Block a user