Skip to content
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

V2: start moving a basic component and rendering footer #2801

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion bun.lock
Original file line number Diff line number Diff line change
@@ -120,6 +120,8 @@
"version": "0.0.0",
"dependencies": {
"@gitbook/api": "^0.90.0",
"@gitbook/icons": "workspace:*",
"clsx": "^2.1.1",
"next": "canary",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -1466,7 +1468,7 @@

"clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="],

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

"code-block-writer": ["code-block-writer@13.0.3", "", {}, "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="],

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

"convict/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],

"cva/clsx": ["clsx@2.0.0", "", {}, "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="],

"decamelize-keys/map-obj": ["map-obj@1.0.1", "", {}, "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="],

"deep-equal/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
4 changes: 3 additions & 1 deletion packages/gitbook-v2/package.json
Original file line number Diff line number Diff line change
@@ -5,7 +5,9 @@
"next": "canary",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"@gitbook/api": "^0.90.0"
"@gitbook/api": "^0.90.0",
"@gitbook/icons": "workspace:*",
"clsx": "^2.1.1"
},
"devDependencies": {
"@opennextjs/cloudflare": "^0.4.3"
4 changes: 2 additions & 2 deletions packages/gitbook-v2/src/app/dynamic/url/[...url]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SiteContentLayout } from '@/components/routes/SiteContentLayout';
import { createDynamicSiteContext } from '@/lib/context';
import { SiteContentLayout } from '@v2/components/routes/SiteContentLayout';
import { createDynamicSiteContext } from '@v2/lib/context';

export default async function RootLayout({
params,
4 changes: 2 additions & 2 deletions packages/gitbook-v2/src/app/dynamic/url/[...url]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SiteContentPage } from '@/components/routes/SiteContentPage';
import { createDynamicSiteContext } from '@/lib/context';
import { SiteContentPage } from '@v2/components/routes/SiteContentPage';
import { createDynamicSiteContext } from '@v2/lib/context';

export default async function Page({ params }: { params: Promise<{ url: string[] }> }) {
const { url } = await params;
6 changes: 3 additions & 3 deletions packages/gitbook-v2/src/app/static/url/[...url]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { unstable_cacheTag as cacheTag } from 'next/cache';
import { SiteContentLayout } from '@/components/routes/SiteContentLayout';
import { getSiteCacheTag } from '@/lib/cache';
import { createStaticSiteContext } from '@/lib/context';
import { SiteContentLayout } from '@v2/components/routes/SiteContentLayout';
import { getSiteCacheTag } from '@v2/lib/cache';
import { createStaticSiteContext } from '@v2/lib/context';

export default async function RootLayout({
params,
6 changes: 3 additions & 3 deletions packages/gitbook-v2/src/app/static/url/[...url]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { unstable_cacheTag as cacheTag } from 'next/cache';
import { createStaticSiteContext } from '@/lib/context';
import { getSiteCacheTag } from '@/lib/cache';
import { SiteContentPage } from '@/components/routes/SiteContentPage';
import { createStaticSiteContext } from '@v2/lib/context';
import { getSiteCacheTag } from '@v2/lib/cache';
import { SiteContentPage } from '@v2/components/routes/SiteContentPage';

export default async function Page({ params }: { params: Promise<{ url: string[] }> }) {
'use cache';
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
'use client';

import clsx from 'clsx';

import { Icon } from '@gitbook/icons';
import classNames from 'classnames';
import React from 'react';
import ReactDOM from 'react-dom';

import { tcls } from '@/lib/tailwind';

import styles from './ZoomImage.module.css';

/**
@@ -166,7 +165,7 @@ export function ZoomImage(
startViewTransition(change);
});
}}
className={classNames(
className={clsx(
props.className,
zoomable ? styles.zoomImg : null,
active ? styles.zoomImageActive : null,
@@ -208,63 +207,25 @@ function ZoomImageModal(props: {
return (
<div
data-testid="zoom-image-modal"
className={classNames(
className={clsx(
styles.zoomModal,
tcls(
'fixed',
'inset-0',
'z-50',
'flex',
'items-center',
'justify-center',
'bg-light',
'dark:bg-dark',
'p-8',
),
'fixed inset-0 z-50 flex items-center justify-center bg-light dark:bg-dark p-8',
)}
onClick={onClose}
>
<img
src={src}
alt={alt}
crossOrigin={crossOrigin}
className={tcls(
'max-w-full',
'max-h-full',
'object-contain',
'bg-light',
'dark:bg-dark',
)}
className="max-w-full max-h-full object-contain bg-light dark:bg-dark"
/>

<button
ref={buttonRef}
className={tcls(
'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',
)}
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"
onClick={onClose}
>
<Icon icon="compress-wide" className={tcls('size-5')} />
<Icon icon="compress-wide" className="size-5" />
</button>
</div>
);
24 changes: 17 additions & 7 deletions packages/gitbook-v2/src/components/routes/SiteContentLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GitBookSiteContext } from '@/lib/context';
import { GitBookSiteSpaceContext } from '@v2/lib/context';
import { Footer } from '@/components/Footer';

/**
* Layout component to render the site content.
@@ -7,20 +8,29 @@ export async function SiteContentLayout({
context,
children,
}: {
context: GitBookSiteContext;
context: GitBookSiteSpaceContext;
children: React.ReactNode;
}) {
const { api } = context;
const { data: publishedSite } = await api.orgs.getPublishedContentSite(
context.organizationId,
context.siteId,
);
const [publishedSite, space] = await Promise.all([
context.getPublishedContentSite(
context.organizationId,
context.siteId,
),
context.getSpaceById(context.spaceId, context.siteShareKey),
]);

return (
<html lang="en">
<body>
<h1>{publishedSite.site.title}</h1>
{children}
<Footer
space={space}
customization={
publishedSite.customizations.siteSpaces[context.siteSpaceId] ??
publishedSite.customizations.site
}
/>
</body>
</html>
);
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GitBookSiteContext } from '@/lib/context';
import { GitBookSiteContext } from '@v2/lib/context';

export async function SiteContentPage({ context }: { context: GitBookSiteContext }) {
const { api } = context;
79 changes: 62 additions & 17 deletions packages/gitbook-v2/src/lib/context.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { GitBookAPI } from '@gitbook/api';
import { GITBOOK_API_TOKEN, GITBOOK_API_URL, GITBOOK_USER_AGENT } from '@/lib/env';

/**
* Generic context about rendering content.
*/
export interface GitBookContext {
/**
* API client to fetch data from GitBook.
*/
api: GitBookAPI;
}
import { GITBOOK_API_TOKEN, GITBOOK_API_URL, GITBOOK_USER_AGENT } from '@v2/lib/env';
import { GitBookContext } from '@/lib/v2/context';

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

/**
* Context when rendering a space in a site.
*/
export interface GitBookSiteSpaceContext extends GitBookSiteContext {
/**
* ID of the space.
*/
spaceId: string;

/**
* ID of the site section.
*/
siteSectionId: string | undefined;

/**
* ID of the site space.
*/
siteSpaceId: string;

/**
* Share key of the site.
*/
siteShareKey: string | undefined;
}

/**
* Create a site context, when rendering a static page.
*/
export async function createStaticSiteContext(url: string[]): Promise<GitBookSiteContext> {
export async function createStaticSiteContext(url: string[]): Promise<GitBookSiteSpaceContext> {
const context = createStaticContext();
return fetchSiteContext(url, context);
}

/**
* Create a site context, when rendering a dynamic page.
*/
export async function createDynamicSiteContext(url: string[]): Promise<GitBookSiteContext> {
export async function createDynamicSiteContext(url: string[]): Promise<GitBookSiteSpaceContext> {
const context = await createDynamicContext();
return fetchSiteContext(url, context);
}
@@ -50,7 +66,7 @@ export async function createDynamicSiteContext(url: string[]): Promise<GitBookSi
async function fetchSiteContext(
urlParts: string[],
baseContext: GitBookContext,
): Promise<GitBookSiteContext> {
): Promise<GitBookSiteSpaceContext> {
const { api } = baseContext;
const url = getURLFromParams(urlParts);
const { data } = await api.urls.getPublishedContentByUrl({
@@ -70,6 +86,9 @@ async function fetchSiteContext(
}),
siteId: data.site,
organizationId: data.organization,
siteSectionId: data.siteSection,
siteSpaceId: data.siteSpace,
spaceId: data.space,
};
}

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

return {
api,
};
return createContextFromClient(api);
}

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

return createContextFromClient(api);
}

function createContextFromClient(api: GitBookAPI): GitBookContext {
return {
api,
getLink: (pathname: string) => pathname,
getPublishedContentSite: async (organizationId: string, siteId: string) => {
const { data } = await api.orgs.getPublishedContentSite(organizationId, siteId);
return data;
},
getRevisionFile: async (spaceId: string, revisionId: string, file: string) => {
throw new Error('Not implemented');
},
getUserById: async (userId: string) => {
const { data } = await api.users.getUserById(userId);
return data;
},
getSpaceById: async (spaceId: string, shareKey: string | undefined) => {
const { data } = await api.spaces.getSpaceById(spaceId, { shareKey });
return data;
},
getCollection: async (collectionId: string) => {
const { data } = await api.collections.getCollectionById(collectionId);
return data;
},
getReusableContent: async (spaceId: string, revisionId: string, reusableContentId: string) => {
const { data } = await api.spaces.getReusableContentInRevisionById(spaceId, revisionId, reusableContentId);
return data;
},
};
}

4 changes: 2 additions & 2 deletions packages/gitbook-v2/tsconfig.json
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@
}
],
"paths": {
"@/*": ["./src/*"],
"@v1/*": ["../gitbook/src/*"]
"@v2/*": ["./src/*"],
"@/*": ["../gitbook/src/*"]
}
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
2 changes: 1 addition & 1 deletion packages/gitbook/src/components/utils/Image.tsx
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ import { checkIsHttpURL, getImageSize, getResizedImageURLFactory } from '@/lib/i
import { ClassValue, tcls } from '@/lib/tailwind';

import { PolymorphicComponentProp } from './types';
import { ZoomImage } from './ZoomImage';
import { ZoomImage } from '@v2/components/images/ZoomImage';

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

Loading
Oops, something went wrong.
Loading
Oops, something went wrong.