Skip to content

Commit 6feb8fc

Browse files
authored
Support emojis in outline (#3734)
1 parent b8d3cb7 commit 6feb8fc

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

packages/gitbook/e2e/internal.spec.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,10 +1454,7 @@ const testCases: TestsCase[] = [
14541454
locale,
14551455
},
14561456
}),
1457-
run: async (page) => {
1458-
const dialog = page.getByTestId('cookies-dialog');
1459-
await expect(dialog).toBeVisible();
1460-
},
1457+
run: waitForCookiesDialog,
14611458
})),
14621459
},
14631460
{

packages/gitbook/e2e/util.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ export const headerLinks: CustomizationHeaderItem[] = [
143143

144144
export async function waitForCookiesDialog(page: Page) {
145145
const dialog = page.getByTestId('cookies-dialog');
146-
await expect(dialog).toBeVisible();
146+
await expect(dialog).toBeVisible({
147+
// Cookies dialog may take some times to appear
148+
timeout: 10_000,
149+
});
147150
}
148151

149152
export async function waitForNotFound(_page: Page, response: Response | null) {

packages/gitbook/src/lib/document-sections.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import type { GitBookAnyContext } from '@/lib/context';
22
import type { DocumentBlock, JSONDocument } from '@gitbook/api';
33

4+
import type { ReactNode } from 'react';
45
import { getDataOrNull } from './data';
5-
import { getNodeText } from './document';
6+
import { getNodeReactText } from './document';
67
import { resolveOpenAPIOperationBlock } from './openapi/resolveOpenAPIOperationBlock';
78
import { resolveOpenAPISchemasBlock } from './openapi/resolveOpenAPISchemasBlock';
89
import { resolveContentRef } from './references';
910

1011
export interface DocumentSection {
1112
id: string;
1213
tag?: string;
13-
title: string;
14+
title: ReactNode;
1415
depth: number;
1516
deprecated?: boolean;
1617
}
@@ -44,7 +45,7 @@ async function getSectionsFromNodes(
4445
continue;
4546
}
4647
depth = 1;
47-
const title = getNodeText(block);
48+
const title = getNodeReactText(block);
4849
sections.push({
4950
id,
5051
title,
@@ -57,7 +58,7 @@ async function getSectionsFromNodes(
5758
if (!id) {
5859
continue;
5960
}
60-
const title = getNodeText(block);
61+
const title = getNodeReactText(block);
6162
sections.push({
6263
id,
6364
title,

packages/gitbook/src/lib/document.ts renamed to packages/gitbook/src/lib/document.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Emoji } from '@/components/primitives';
12
import type {
23
DocumentBlock,
34
DocumentFragment,
@@ -6,6 +7,7 @@ import type {
67
JSONDocument,
78
} from '@gitbook/api';
89
import assertNever from 'assert-never';
10+
import { Fragment } from 'react';
911

1012
export interface DocumentSection {
1113
id: string;
@@ -88,6 +90,29 @@ export function getNodeText(
8890
}
8991
}
9092

93+
/**
94+
* Get the text of a block/inline as ReactNode.
95+
*/
96+
export function getNodeReactText(
97+
node: JSONDocument | DocumentText | DocumentFragment | DocumentInline | DocumentBlock
98+
): React.ReactNode {
99+
if (node.object === 'inline' && node.type === 'emoji') {
100+
return <Emoji code={node.data.code} />;
101+
}
102+
103+
if (node.object === 'text') {
104+
return getNodeText(node);
105+
}
106+
107+
if (!('nodes' in node)) {
108+
return null;
109+
}
110+
111+
return node.nodes.map((child, index) => {
112+
return <Fragment key={child.key ?? `idx-${index}`}>{getNodeReactText(child)}</Fragment>;
113+
});
114+
}
115+
91116
/**
92117
* Get a fragment by its type in a node.
93118
*/

0 commit comments

Comments
 (0)