Skip to content

Commit 958eb05

Browse files
committed
clean up
1 parent ed2247e commit 958eb05

File tree

4 files changed

+73
-112
lines changed

4 files changed

+73
-112
lines changed

packages/gitbook/src/components/RootLayout/CustomizationRootLayout.tsx

+18-80
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,7 @@ import {
2222
} from '@gitbook/colors';
2323
import { IconStyle, IconsProvider } from '@gitbook/icons';
2424

25-
import {
26-
type CustomizationFont,
27-
fontNotoColorEmoji,
28-
fonts,
29-
generateFontFacesCSS,
30-
getCustomFontSources,
31-
getFontData,
32-
ibmPlexMono,
33-
} from '@/fonts';
25+
import { fontNotoColorEmoji, getFontData, renderFontPreloads, renderFontStyles } from '@/fonts';
3426
import { getSpaceLanguage } from '@/intl/server';
3527
import { getAssetURL } from '@/lib/assets';
3628
import { tcls } from '@/lib/tailwind';
@@ -77,8 +69,7 @@ export async function CustomizationRootLayout(props: {
7769
sidebarStyles.list && `sidebar-list-${sidebarStyles.list}`,
7870
'links' in customization.styling && `links-${customization.styling.links}`,
7971
fontNotoColorEmoji.variable,
80-
!fontData.isCustom ? fontData.fontVariable : '', // Only use fontVariable for default fonts
81-
ibmPlexMono.variable
72+
fontData.type === 'default' ? fontData.cssClassName : 'font-custom'
8273
)}
8374
>
8475
<head>
@@ -87,22 +78,23 @@ export async function CustomizationRootLayout(props: {
8778
) : null}
8879

8980
{/* Font preloading for custom fonts */}
90-
{fontData.isCustom &&
91-
fontData.fontSources.map(({ url, format }) => (
92-
<link
93-
key={url.href}
94-
rel="preload"
95-
href={url.href}
96-
as="font"
97-
type={format ? `font/${format}` : undefined}
98-
crossOrigin="anonymous"
99-
/>
100-
))}
81+
{fontData.type === 'custom'
82+
? fontData.preloadSources.map(({ url, format }) => (
83+
<link
84+
key={url}
85+
rel="preload"
86+
href={url}
87+
as="font"
88+
type={format ? `font/${format}` : undefined}
89+
crossOrigin="anonymous"
90+
/>
91+
))
92+
: null}
10193

10294
{/* Custom font CSS */}
103-
{fontData.isCustom && fontData.fontCSS && (
104-
<style id="custom-font-styles">{fontData.fontCSS}</style>
105-
)}
95+
{fontData.type === 'custom' ? (
96+
<style id="custom-font-styles">{fontData.cssDefinitions}</style>
97+
) : null}
10698

10799
<style
108100
nonce={
@@ -149,9 +141,6 @@ export async function CustomizationRootLayout(props: {
149141
</head>
150142
<body
151143
className={tcls(
152-
fontNotoColorEmoji.className,
153-
hasCustomFont ? 'font-sans' : fonts[customization.styling.font].className,
154-
`${ibmPlexMono.variable}`,
155144
'bg-tint-base',
156145
'theme-muted:bg-tint-subtle',
157146
'theme-bold-tint:bg-tint-subtle',
@@ -286,58 +275,7 @@ function getSemanticColors(
286275
},
287276
};
288277
}
289-
/**
290-
* Define the custom font faces and set the --font-content to the custom font name
291-
*/
292-
// function generateCustomFontFaces(customFont: CustomizationFontDefinition): string {
293-
// const { fontFamily, faces } = customFont;
294-
//
295-
// const regularFont = faces.find((face) => face.weight === 400);
296-
// const boldFont = faces.find((face) => face.weight === 700);
297-
//
298-
// if (!regularFont || !boldFont) {
299-
// throw new Error('Custom font must have a regular and a bold face');
300-
// }
301-
//
302-
// const regular = `
303-
// @font-face {
304-
// font-family: ${fontFamily};
305-
// font-style: normal;
306-
// font-weight: ${regularFont.weight};
307-
// font-display: swap;
308-
// src: url(${regularFont.url});
309-
// }
310-
// `;
311-
//
312-
// // const semiBold = `
313-
// // @font-face {
314-
// // font-family: ${fontFamily};
315-
// // font-style: normal;
316-
// // font-weight: 600;
317-
// // font-display: swap;
318-
// // src: url(${boldFont.url});
319-
// // }
320-
// // `
321-
// // : "";
322-
//
323-
// const bold = `
324-
// @font-face {
325-
// font-family: ${fontFamily};
326-
// font-style: normal;
327-
// font-weight: ${boldFont.weight};
328-
// font-display: swap;
329-
// src: url(${boldFont.url});
330-
// }
331-
// `;
332-
//
333-
// return `
334-
// ${regular}
335-
// ${bold}
336-
// :root {
337-
// --font-content: ${fontFamily};
338-
// }
339-
// `;
340-
// }
278+
341279
type ColorInput = string;
342280
function generateColorVariable(
343281
name: string,

packages/gitbook/src/fonts/customFont.test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { describe, test, expect } from 'bun:test';
1+
import { describe, expect, test } from 'bun:test';
2+
import stylelint from 'stylelint';
23
import {
34
type CustomizationFontDefinition,
45
generateFontFacesCSS,
5-
getCustomFontSources,
6+
getFontSourcesToPreload,
67
} from './customFonts';
7-
import stylelint from 'stylelint';
88

99
const TEST_FONTS = {
1010
basic: {
@@ -281,14 +281,14 @@ describe('getCustomFontPreloadLinks', () => {
281281

282282
preloadTestCases.forEach(({ name, font, expectedCount }) => {
283283
test(`extracts ${expectedCount} URLs from ${name}`, () => {
284-
const result = getCustomFontSources(font);
284+
const result = getFontSourcesToPreload(font);
285285
expect(result).toBeArray();
286286
expect(result.length).toBe(expectedCount);
287287
});
288288
});
289289

290290
test('handles different URL types correctly', () => {
291-
const result = getCustomFontSources(TEST_FONTS.variousURLs);
291+
const result = getFontSourcesToPreload(TEST_FONTS.variousURLs);
292292

293293
expect(result).toBeArray();
294294
expect(result.length).toBe(3);

packages/gitbook/src/fonts/customFonts.ts

+48-26
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type FontWeight = number;
1818
/** A font file referenced within a font-face declaration, specifying the file's location and format. */
1919
export interface FontSource {
2020
/** The absolute or relative URL pointing to the font file. */
21-
url: URL;
21+
url: string;
2222
/** The format of the font file. Prefer 'woff2' for modern browsers. */
2323
format?: 'woff2' | 'woff';
2424
}
@@ -67,7 +67,7 @@ export function generateFontFacesCSS(customFont: CustomizationFontDefinition): s
6767
.map((face) => {
6868
const srcAttr = face.sources
6969
.map((source) => {
70-
let srcDefinition = `url(${source.url.href})`;
70+
let srcDefinition = `url(${source.url})`;
7171

7272
if (source.format) {
7373
srcDefinition += ` format('${source.format}')`;
@@ -92,47 +92,69 @@ export function generateFontFacesCSS(customFont: CustomizationFontDefinition): s
9292
return `
9393
${fontFaceDeclarations}
9494
:root {
95-
--font-content: ${fontFamily};
95+
--font-custom: ${fontFamily};
9696
}
9797
`;
9898
}
9999

100100
/**
101-
* Get the list of font URLs to preload
101+
* Get the list of font sources to preload
102102
*/
103-
export function getCustomFontSources(customFont: CustomizationFontDefinition): FontSource[] {
104-
return customFont.fontFaces.flatMap((face) => face.sources);
103+
export function getFontSourcesToPreload(customFont: CustomizationFontDefinition): FontSource[] {
104+
const allSources = customFont.fontFaces.flatMap((face) => face.sources);
105+
106+
const uniqueSources = new Map<string, FontSource>();
107+
108+
// Add each source to the map, using URL as the key
109+
allSources.forEach((source) => {
110+
const url = source.url.toString();
111+
if (!uniqueSources.has(url)) {
112+
uniqueSources.set(url, source);
113+
}
114+
});
115+
116+
return Array.from(uniqueSources.values());
105117
}
106118

107-
type CustomFontData = {
108-
isCustom: true;
109-
fontCSS: string;
110-
fontSources: FontSource[];
111-
};
119+
/**
120+
* Represents font data for either a default font or a custom font
121+
*/
122+
type FontData = DefaultFontData | CustomFontData;
112123

113-
type DefaultFontData = {
114-
isCustom: false;
115-
fontVariable: string;
116-
};
124+
/**
125+
* Font data for a default font from next/font
126+
*/
127+
interface DefaultFontData {
128+
type: 'default';
129+
cssClassName: string;
130+
}
117131

118132
/**
119-
* Get the font data for a given font
120-
* For default fonts it returns a next/font variable name.
121-
* For custom fonts it returns the CSS for the @font-face definitions and font URLs to preload
133+
* Font data for a custom font with @font-face definitions
122134
*/
123-
export function getFontData(font: CustomizationFont): CustomFontData | DefaultFontData {
124-
const isCustomFont = typeof font !== 'string';
135+
interface CustomFontData {
136+
type: 'custom';
137+
cssDefinitions: string;
138+
preloadSources: FontSource[];
139+
}
125140

126-
if (isCustomFont) {
141+
/**
142+
* Get the appropriate font data for a given font configuration
143+
* @param font Either a predefined font name or a custom font configuration
144+
*/
145+
export function getFontData(font: CustomizationFont): FontData {
146+
if (typeof font === 'string') {
147+
// Default font from next/font
127148
return {
128-
isCustom: true,
129-
fontCSS: generateFontFacesCSS(font as CustomizationFontDefinition),
130-
fontSources: getCustomFontSources(font as CustomizationFontDefinition),
149+
type: 'default',
150+
cssClassName: fonts[font].variable,
131151
};
132152
}
133153

154+
// Custom font with @font-face definitions
134155
return {
135-
isCustom: false,
136-
fontVariable: fonts[font].variable,
156+
type: 'custom',
157+
cssDefinitions: generateFontFacesCSS(font),
158+
preloadSources: getFontSourcesToPreload(font),
137159
};
138160
}

packages/gitbook/tailwind.config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,15 @@ const config: Config = {
7272
'current-page': 'current="page"',
7373
},
7474
fontFamily: {
75-
sans: ['var(--font-content)', 'arial', 'sans-serif'],
75+
sans: ['var(--font-content)'],
7676
mono: ['var(--font-mono)'],
7777
emoji: [
7878
'Apple Color Emoji',
7979
'Noto Color Emoji',
8080
'--font-noto-color-emoji',
8181
'sans-serif',
8282
],
83+
custom: ['var(--font-custom)'],
8384
var: ['var(--font-family)'],
8485
},
8586
colors: {

0 commit comments

Comments
 (0)