Skip to content

Commit cb91453

Browse files
committed
Support translations and generic variants together
Add rudimentary support for translations & generic variants to be used on the same site. - Refactor `withVariants` into a `variants` object that contains two arrays for the different types: `translations` and `generic`. - Switch the logic around to check these two arrays independently of each other. - If there are any translations (spaces with a different language than the current), the menu dropdown is shown. If there are any generic variants (spaces with the same language as the current), the variant dropdown is shown.
1 parent 1d1f0a7 commit cb91453

File tree

3 files changed

+40
-25
lines changed

3 files changed

+40
-25
lines changed

.changeset/rich-hairs-check.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gitbook": patch
3+
---
4+
5+
Support translations and generic variants together

packages/gitbook/src/components/Header/Header.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { GitBookSiteContext } from '@/lib/context';
33
import { CONTAINER_STYLE, HEADER_HEIGHT_DESKTOP } from '@/components/layout';
44
import { getSpaceLanguage, t } from '@/intl/server';
55
import { tcls } from '@/lib/tailwind';
6+
import type { SiteSpace } from '@gitbook/api';
67
import { SearchContainer } from '../Search';
78
import { SiteSectionTabs, encodeClientSiteSections } from '../SiteSections';
89
import { HeaderLink } from './HeaderLink';
@@ -18,9 +19,12 @@ import { TranslationsDropdown } from './SpacesDropdown';
1819
export function Header(props: {
1920
context: GitBookSiteContext;
2021
withTopHeader?: boolean;
21-
withVariants?: 'generic' | 'translations';
22+
variants: {
23+
generic: SiteSpace[];
24+
translations: SiteSpace[];
25+
};
2226
}) {
23-
const { context, withTopHeader, withVariants } = props;
27+
const { context, withTopHeader, variants } = props;
2428
const { siteSpace, siteSpaces, sections, customization } = context;
2529

2630
const withSections = Boolean(
@@ -91,7 +95,7 @@ export function Header(props: {
9195
'theme-bold:text-header-link',
9296
'hover:bg-tint-hover',
9397
'hover:theme-bold:bg-header-link/3',
94-
withVariants === 'generic'
98+
variants.generic.length > 1
9599
? 'xl:hidden'
96100
: 'page-no-toc:hidden lg:hidden'
97101
)}
@@ -126,7 +130,7 @@ export function Header(props: {
126130
>
127131
<SearchContainer
128132
style={customization.styling.search}
129-
withVariants={withVariants === 'generic'}
133+
withVariants={variants.generic.length > 1}
130134
withSiteVariants={
131135
sections?.list.some(
132136
(s) =>
@@ -150,7 +154,7 @@ export function Header(props: {
150154
</div>
151155

152156
{customization.header.links.length > 0 ||
153-
(!withSections && withVariants === 'translations') ? (
157+
(!withSections && variants.translations.length > 1) ? (
154158
<HeaderLinks>
155159
{customization.header.links.length > 0 ? (
156160
<>
@@ -170,11 +174,11 @@ export function Header(props: {
170174
/>
171175
</>
172176
) : null}
173-
{!withSections && withVariants === 'translations' ? (
177+
{!withSections && variants.translations.length > 1 ? (
174178
<TranslationsDropdown
175179
context={context}
176180
siteSpace={siteSpace}
177-
siteSpaces={siteSpaces}
181+
siteSpaces={variants.translations}
178182
className="flex! theme-bold:text-header-link hover:theme-bold:bg-header-link/3"
179183
/>
180184
) : null}
@@ -187,11 +191,11 @@ export function Header(props: {
187191
{sections && withSections ? (
188192
<div className="transition-[padding] duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
189193
<SiteSectionTabs sections={encodeClientSiteSections(context, sections)}>
190-
{withVariants === 'translations' ? (
194+
{variants.translations.length > 1 ? (
191195
<TranslationsDropdown
192196
context={context}
193197
siteSpace={siteSpace}
194-
siteSpaces={siteSpaces}
198+
siteSpaces={variants.translations}
195199
className="my-2 ml-2 self-start"
196200
/>
197201
) : null}

packages/gitbook/src/components/SpaceLayout/SpaceLayout.tsx

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
CustomizationAIMode,
44
CustomizationHeaderPreset,
55
CustomizationSearchStyle,
6+
type SiteSpace,
67
} from '@gitbook/api';
78
import type React from 'react';
89

@@ -106,15 +107,20 @@ export function SpaceLayout(props: SpaceLayoutProps) {
106107

107108
const withSections = Boolean(sections && sections.list.length > 1);
108109

109-
const currentLanguage = getSpaceLanguage(context);
110-
const withVariants: 'generic' | 'translations' | undefined =
111-
siteSpaces.length > 1
112-
? siteSpaces.some(
113-
(space) => space.space.language && space.space.language !== currentLanguage.locale
114-
)
115-
? 'translations'
116-
: 'generic'
117-
: undefined;
110+
const currentLanguage = getSpaceLanguage(context).locale;
111+
const variants: Record<'generic' | 'translations', SiteSpace[]> = {
112+
translations: siteSpaces.filter(
113+
(space) =>
114+
space === siteSpace ||
115+
(space.space.language && space.space.language !== currentLanguage)
116+
),
117+
generic: siteSpaces.filter(
118+
(space) =>
119+
space === siteSpace ||
120+
!space.space.language ||
121+
space.space.language === currentLanguage
122+
),
123+
};
118124

119125
const withFooter =
120126
customization.themes.toggeable ||
@@ -125,7 +131,7 @@ export function SpaceLayout(props: SpaceLayoutProps) {
125131
return (
126132
<SpaceLayoutServerContext {...props}>
127133
<Announcement context={context} />
128-
<Header withTopHeader={withTopHeader} withVariants={withVariants} context={context} />
134+
<Header withTopHeader={withTopHeader} variants={variants} context={context} />
129135
<NavigationLoader />
130136
{customization.ai?.mode === CustomizationAIMode.Assistant ? (
131137
<AIChat trademark={customization.trademark.enabled} />
@@ -165,11 +171,11 @@ export function SpaceLayout(props: SpaceLayoutProps) {
165171
)}
166172
>
167173
<HeaderLogo context={context} />
168-
{withVariants === 'translations' ? (
174+
{variants.translations.length > 1 ? (
169175
<TranslationsDropdown
170176
context={context}
171177
siteSpace={siteSpace}
172-
siteSpaces={siteSpaces}
178+
siteSpaces={variants.translations}
173179
className="[&_.button-leading-icon]:block! ml-auto py-2 [&_.button-content]:hidden"
174180
/>
175181
) : null}
@@ -183,7 +189,7 @@ export function SpaceLayout(props: SpaceLayoutProps) {
183189
<div className="flex gap-2">
184190
<SearchContainer
185191
style={CustomizationSearchStyle.Subtle}
186-
withVariants={withVariants === 'generic'}
192+
withVariants={variants.generic.length > 1}
187193
withSiteVariants={
188194
sections?.list.some(
189195
(s) =>
@@ -213,14 +219,14 @@ export function SpaceLayout(props: SpaceLayoutProps) {
213219
sections={encodeClientSiteSections(context, sections)}
214220
/>
215221
)}
216-
{withVariants === 'generic' && (
222+
{variants.generic.length > 1 ? (
217223
<SpacesDropdown
218224
context={context}
219225
siteSpace={siteSpace}
220-
siteSpaces={siteSpaces}
226+
siteSpaces={variants.generic}
221227
className="w-full px-3 py-2"
222228
/>
223-
)}
229+
) : null}
224230
</>
225231
}
226232
/>

0 commit comments

Comments
 (0)