Skip to content

Commit d3d240c

Browse files
committed
Move ZoomImage to v2
1 parent 8df1bf1 commit d3d240c

File tree

11 files changed

+148
-75
lines changed

11 files changed

+148
-75
lines changed

bun.lock

+5-1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@
120120
"version": "0.0.0",
121121
"dependencies": {
122122
"@gitbook/api": "^0.90.0",
123+
"@gitbook/icons": "workspace:*",
124+
"clsx": "^2.1.1",
123125
"next": "canary",
124126
"react": "^19.0.0",
125127
"react-dom": "^19.0.0",
@@ -1466,7 +1468,7 @@
14661468

14671469
"clone-response": ["[email protected]", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="],
14681470

1469-
"clsx": ["clsx@2.0.0", "", {}, "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="],
1471+
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
14701472

14711473
"code-block-writer": ["[email protected]", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="],
14721474

@@ -4272,6 +4274,8 @@
42724274

42734275
"convict/yargs-parser": ["[email protected]", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],
42744276

4277+
"cva/clsx": ["[email protected]", "", {}, "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="],
4278+
42754279
"decamelize-keys/map-obj": ["[email protected]", "", {}, "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="],
42764280

42774281
"deep-equal/isarray": ["[email protected]", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],

packages/gitbook-v2/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
"next": "canary",
66
"react": "^19.0.0",
77
"react-dom": "^19.0.0",
8-
"@gitbook/api": "^0.90.0"
8+
"@gitbook/api": "^0.90.0",
9+
"@gitbook/icons": "workspace:*",
10+
"clsx": "^2.1.1"
911
},
1012
"devDependencies": {
1113
"@opennextjs/cloudflare": "^0.4.3"

packages/gitbook/src/components/utils/ZoomImage.tsx packages/gitbook-v2/src/components/images/ZoomImage.tsx

+8-47
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
'use client';
22

3+
import clsx from 'clsx';
4+
35
import { Icon } from '@gitbook/icons';
4-
import classNames from 'classnames';
56
import React from 'react';
67
import ReactDOM from 'react-dom';
78

8-
import { tcls } from '@/lib/tailwind';
9-
109
import styles from './ZoomImage.module.css';
1110

1211
/**
@@ -166,7 +165,7 @@ export function ZoomImage(
166165
startViewTransition(change);
167166
});
168167
}}
169-
className={classNames(
168+
className={clsx(
170169
props.className,
171170
zoomable ? styles.zoomImg : null,
172171
active ? styles.zoomImageActive : null,
@@ -208,63 +207,25 @@ function ZoomImageModal(props: {
208207
return (
209208
<div
210209
data-testid="zoom-image-modal"
211-
className={classNames(
210+
className={clsx(
212211
styles.zoomModal,
213-
tcls(
214-
'fixed',
215-
'inset-0',
216-
'z-50',
217-
'flex',
218-
'items-center',
219-
'justify-center',
220-
'bg-light',
221-
'dark:bg-dark',
222-
'p-8',
223-
),
212+
'fixed inset-0 z-50 flex items-center justify-center bg-light dark:bg-dark p-8',
224213
)}
225214
onClick={onClose}
226215
>
227216
<img
228217
src={src}
229218
alt={alt}
230219
crossOrigin={crossOrigin}
231-
className={tcls(
232-
'max-w-full',
233-
'max-h-full',
234-
'object-contain',
235-
'bg-light',
236-
'dark:bg-dark',
237-
)}
220+
className="max-w-full max-h-full object-contain bg-light dark:bg-dark"
238221
/>
239222

240223
<button
241224
ref={buttonRef}
242-
className={tcls(
243-
'absolute',
244-
'top-5',
245-
'right-5',
246-
'flex',
247-
'flex-row',
248-
'items-center',
249-
'justify-center',
250-
'text-sm',
251-
'text-dark/6',
252-
'dark:text-light/5',
253-
'hover:text-primary',
254-
'p-4',
255-
'dark:text-light/5',
256-
'rounded-full',
257-
'bg-white',
258-
'dark:bg-dark/3',
259-
'shadow-sm',
260-
'hover:shadow-md',
261-
'border-slate-300',
262-
'dark:border-dark/2',
263-
'border',
264-
)}
225+
className="absolute top-5 right-5 flex flex-row items-center justify-center text-sm text-dark/6 dark:text-light/5 hover:text-primary p-4 dark:text-light/5 rounded-full bg-white dark:bg-dark/3 shadow-sm hover:shadow-md border-slate-300 dark:border-dark/2 border dark:text-light/5 hover:text-primary p-4 dark:text-light/5 rounded-full bg-white dark:bg-dark/3 shadow-sm hover:shadow-md border-slate-300 dark:border-dark/2 border"
265226
onClick={onClose}
266227
>
267-
<Icon icon="compress-wide" className={tcls('size-5')} />
228+
<Icon icon="compress-wide" className="size-5" />
268229
</button>
269230
</div>
270231
);

packages/gitbook-v2/src/components/routes/SiteContentLayout.tsx

+17-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { GitBookSiteContext } from '@v2/lib/context';
1+
import { GitBookSiteSpaceContext } from '@v2/lib/context';
2+
import { Footer } from '@/components/Footer';
23

34
/**
45
* Layout component to render the site content.
@@ -7,20 +8,29 @@ export async function SiteContentLayout({
78
context,
89
children,
910
}: {
10-
context: GitBookSiteContext;
11+
context: GitBookSiteSpaceContext;
1112
children: React.ReactNode;
1213
}) {
13-
const { api } = context;
14-
const { data: publishedSite } = await api.orgs.getPublishedContentSite(
15-
context.organizationId,
16-
context.siteId,
17-
);
14+
const [publishedSite, space] = await Promise.all([
15+
context.getPublishedContentSite(
16+
context.organizationId,
17+
context.siteId,
18+
),
19+
context.getSpaceById(context.spaceId, context.siteShareKey),
20+
]);
1821

1922
return (
2023
<html lang="en">
2124
<body>
2225
<h1>{publishedSite.site.title}</h1>
2326
{children}
27+
<Footer
28+
space={space}
29+
customization={
30+
publishedSite.customizations.siteSpaces[context.siteSpaceId] ??
31+
publishedSite.customizations.site
32+
}
33+
/>
2434
</body>
2535
</html>
2636
);

packages/gitbook-v2/src/lib/context.ts

+61-16
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,7 @@ import { headers } from 'next/headers';
22
import { redirect } from 'next/navigation';
33
import { GitBookAPI } from '@gitbook/api';
44
import { GITBOOK_API_TOKEN, GITBOOK_API_URL, GITBOOK_USER_AGENT } from '@v2/lib/env';
5-
6-
/**
7-
* Generic context about rendering content.
8-
*/
9-
export interface GitBookContext {
10-
/**
11-
* API client to fetch data from GitBook.
12-
*/
13-
api: GitBookAPI;
14-
}
5+
import { GitBookContext } from '@/lib/v2/context';
156

167
/**
178
* Context when rendering a site.
@@ -28,18 +19,43 @@ export interface GitBookSiteContext extends GitBookContext {
2819
siteId: string;
2920
}
3021

22+
/**
23+
* Context when rendering a space in a site.
24+
*/
25+
export interface GitBookSiteSpaceContext extends GitBookSiteContext {
26+
/**
27+
* ID of the space.
28+
*/
29+
spaceId: string;
30+
31+
/**
32+
* ID of the site section.
33+
*/
34+
siteSectionId: string | undefined;
35+
36+
/**
37+
* ID of the site space.
38+
*/
39+
siteSpaceId: string;
40+
41+
/**
42+
* Share key of the site.
43+
*/
44+
siteShareKey: string | undefined;
45+
}
46+
3147
/**
3248
* Create a site context, when rendering a static page.
3349
*/
34-
export async function createStaticSiteContext(url: string[]): Promise<GitBookSiteContext> {
50+
export async function createStaticSiteContext(url: string[]): Promise<GitBookSiteSpaceContext> {
3551
const context = createStaticContext();
3652
return fetchSiteContext(url, context);
3753
}
3854

3955
/**
4056
* Create a site context, when rendering a dynamic page.
4157
*/
42-
export async function createDynamicSiteContext(url: string[]): Promise<GitBookSiteContext> {
58+
export async function createDynamicSiteContext(url: string[]): Promise<GitBookSiteSpaceContext> {
4359
const context = await createDynamicContext();
4460
return fetchSiteContext(url, context);
4561
}
@@ -50,7 +66,7 @@ export async function createDynamicSiteContext(url: string[]): Promise<GitBookSi
5066
async function fetchSiteContext(
5167
urlParts: string[],
5268
baseContext: GitBookContext,
53-
): Promise<GitBookSiteContext> {
69+
): Promise<GitBookSiteSpaceContext> {
5470
const { api } = baseContext;
5571
const url = getURLFromParams(urlParts);
5672
const { data } = await api.urls.getPublishedContentByUrl({
@@ -70,6 +86,9 @@ async function fetchSiteContext(
7086
}),
7187
siteId: data.site,
7288
organizationId: data.organization,
89+
siteSectionId: data.siteSection,
90+
siteSpaceId: data.siteSpace,
91+
spaceId: data.space,
7392
};
7493
}
7594

@@ -83,9 +102,7 @@ function createStaticContext(): GitBookContext {
83102
userAgent: GITBOOK_USER_AGENT,
84103
});
85104

86-
return {
87-
api,
88-
};
105+
return createContextFromClient(api);
89106
}
90107

91108
/**
@@ -101,8 +118,36 @@ async function createDynamicContext(): Promise<GitBookContext> {
101118
userAgent: GITBOOK_USER_AGENT,
102119
});
103120

121+
return createContextFromClient(api);
122+
}
123+
124+
function createContextFromClient(api: GitBookAPI): GitBookContext {
104125
return {
105126
api,
127+
getLink: (pathname: string) => pathname,
128+
getPublishedContentSite: async (organizationId: string, siteId: string) => {
129+
const { data } = await api.orgs.getPublishedContentSite(organizationId, siteId);
130+
return data;
131+
},
132+
getRevisionFile: async (spaceId: string, revisionId: string, file: string) => {
133+
throw new Error('Not implemented');
134+
},
135+
getUserById: async (userId: string) => {
136+
const { data } = await api.users.getUserById(userId);
137+
return data;
138+
},
139+
getSpaceById: async (spaceId: string, shareKey: string | undefined) => {
140+
const { data } = await api.spaces.getSpaceById(spaceId, { shareKey });
141+
return data;
142+
},
143+
getCollection: async (collectionId: string) => {
144+
const { data } = await api.collections.getCollectionById(collectionId);
145+
return data;
146+
},
147+
getReusableContent: async (spaceId: string, revisionId: string, reusableContentId: string) => {
148+
const { data } = await api.spaces.getReusableContentInRevisionById(spaceId, revisionId, reusableContentId);
149+
return data;
150+
},
106151
};
107152
}
108153

packages/gitbook-v2/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
],
2121
"paths": {
2222
"@v2/*": ["./src/*"],
23-
"@v1/*": ["../gitbook/src/*"]
23+
"@/*": ["../gitbook/src/*"]
2424
}
2525
},
2626
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],

packages/gitbook/src/components/utils/Image.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { checkIsHttpURL, getImageSize, getResizedImageURLFactory } from '@/lib/i
55
import { ClassValue, tcls } from '@/lib/tailwind';
66

77
import { PolymorphicComponentProp } from './types';
8-
import { ZoomImage } from './ZoomImage';
8+
import { ZoomImage } from '@v2/components/images/ZoomImage';
99

1010
export type ImageSize = { width: number; height: number };
1111

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Collection, GitBookAPI, PublishedContentSite, RevisionFile, RevisionReusableContent, Space, User } from "@gitbook/api";
2+
3+
/**
4+
* Global context for rendering GitBook.
5+
* The context is designed to help migrate from v1 to v2, with components implemented for both versions.
6+
*/
7+
export interface GitBookContext {
8+
/**
9+
* API client to fetch data from GitBook.
10+
*/
11+
api: GitBookAPI;
12+
13+
/**
14+
* Resolve a url/pathname to a link.
15+
*/
16+
getLink(pathname: string): string;
17+
18+
/**
19+
* Get a published site by ID.
20+
*/
21+
getPublishedContentSite(organizationId: string, siteId: string): Promise<PublishedContentSite>;
22+
23+
/**
24+
* Get a file from a revision.
25+
*/
26+
getRevisionFile(spaceId: string, revisionId: string, file: string): Promise<RevisionFile>;
27+
28+
/**
29+
* Get a user by ID.
30+
*/
31+
getUserById(userId: string): Promise<User>;
32+
33+
/**
34+
* Get a space by ID.
35+
*/
36+
getSpaceById(spaceId: string, shareKey: string | undefined): Promise<Space>;
37+
38+
/**
39+
* Get a collection by ID.
40+
*/
41+
getCollection(collectionId: string): Promise<Collection>;
42+
43+
/**
44+
* Get a reusable content by ID.
45+
*/
46+
getReusableContent(spaceId: string, revisionId: string, reusableContentId: string): Promise<RevisionReusableContent>;
47+
}

packages/gitbook/tailwind.config.ts

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ const config: Config = {
5555
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
5656
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
5757
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
58+
59+
// V2
60+
'../gitbook-v2/src/**/*.{js,ts,jsx,tsx,mdx}',
5861
],
5962
theme: {
6063
extend: {

packages/gitbook/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
}
2020
],
2121
"paths": {
22-
"@/*": ["./src/*"]
22+
"@/*": ["./src/*"],
23+
"@v2/*": ["../gitbook-v2/src/*"]
2324
},
2425
"types": [
2526
"bun-types" // add Bun global

0 commit comments

Comments
 (0)