Skip to content

Commit 8cee68d

Browse files
authored
[FIX]: Use Github Slugger in RichText headings (#90)
* use github slugger * changeset * lock
1 parent b186936 commit 8cee68d

File tree

5 files changed

+21
-59
lines changed

5 files changed

+21
-59
lines changed

.changeset/clever-suits-yawn.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"basehub": patch
3+
---
4+
5+
React RichText component now implements GithubSlugger to generate the headings IDs

packages/basehub/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@
3939
"arg": "5.0.1",
4040
"dotenv-mono": "1.3.10",
4141
"esbuild": "0.19.2",
42+
"github-slugger": "^2.0.0",
4243
"pusher-js": "8.3.0",
4344
"react": "18.2.0",
4445
"react-dom": "18.2.0",
4546
"resolve-pkg": "2.0.0",
46-
"slugify": "1.6.6",
4747
"sonner": "1.4.3",
4848
"zod": "3.22.1"
4949
},

packages/basehub/src/react/rich-text/primitive.tsx

+8-38
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint-disable jsx-a11y/alt-text */
22
/* eslint-disable @next/next/no-img-element */
33
import { type ReactNode } from "react";
4-
import slugify from "slugify";
5-
import { extractTextFromNode, incrementID } from "./util/heading-id";
4+
import GithubSlugger from 'github-slugger'
5+
import { extractTextFromNode } from "./util/heading-id";
66

77
/**
88
* TODOs
@@ -221,18 +221,13 @@ export type RichTextProps<
221221
>;
222222
};
223223

224-
type GeneratedIDsRecord = Record<
225-
number, // level
226-
Array<string>
227-
>;
228-
229224
export const RichText = <
230225
CustomBlocks extends CustomBlocksBase = readonly any[],
231226
>(
232227
props: RichTextProps<CustomBlocks>
233228
): ReactNode => {
234229
const value = props.children as Node[] | undefined;
235-
const generatedIDs: GeneratedIDsRecord = [];
230+
const slugger = new GithubSlugger()
236231

237232
return (
238233
<>
@@ -244,7 +239,7 @@ export const RichText = <
244239
components={props.components}
245240
blocks={props.blocks}
246241
level={0}
247-
generatedIDs={generatedIDs}
242+
slugger={slugger}
248243
/>
249244
);
250245
})}
@@ -337,14 +332,14 @@ const Node = ({
337332
blocks,
338333
parent,
339334
level,
340-
generatedIDs,
335+
slugger,
341336
}: {
342337
node: Node;
343338
components?: Partial<Handlers>;
344339
blocks?: readonly CustomBlockBase[];
345340
parent?: Node;
346341
level: number;
347-
generatedIDs: GeneratedIDsRecord;
342+
slugger: GithubSlugger;
348343
}) => {
349344
const children = node.content?.map((childNode, index) => {
350345
return (
@@ -355,7 +350,7 @@ const Node = ({
355350
components={components}
356351
blocks={blocks}
357352
level={level + 1}
358-
generatedIDs={generatedIDs}
353+
slugger={slugger}
359354
/>
360355
);
361356
});
@@ -415,32 +410,7 @@ const Node = ({
415410
case "heading":
416411
const handlerTag = `h${node.attrs.level}` as keyof Handlers;
417412
handler = components?.[handlerTag] ?? defaultHandlers[handlerTag];
418-
419-
// initialize the array for this level
420-
generatedIDs[level] = generatedIDs[level] ?? [];
421-
422-
function getUniqueID(id: string): string {
423-
// make sure there are no collisions
424-
if (id) {
425-
if (generatedIDs[level]?.includes(id)) {
426-
return getUniqueID(incrementID(id));
427-
}
428-
}
429-
430-
return id;
431-
}
432-
433-
const id = getUniqueID(
434-
slugify(extractTextFromNode(node), {
435-
strict: true,
436-
lower: true,
437-
trim: true,
438-
})
439-
);
440-
441-
if (id) {
442-
generatedIDs[level]?.push(id);
443-
}
413+
const id = slugger.slug(extractTextFromNode(node))
444414

445415
props = { children, id } satisfies ExtractPropsForHandler<Handlers["h1"]>;
446416
break;

packages/basehub/src/react/rich-text/util/heading-id.ts

-12
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,3 @@ export function extractTextFromNode(node?: Node) {
1414

1515
return textContent;
1616
}
17-
18-
export function incrementID(id: string) {
19-
// duplicates are added "-n" at the end.
20-
// if the title already has a "-n" at the end, we'll need to increment it.
21-
const matches = id.match(/-(\d+)$/); // Fixed regex to match "-n" format
22-
if (matches?.[1] !== undefined) {
23-
const number = parseInt(matches[1], 10);
24-
return id.replace(/-(\d+)$/, `-${number + 1}`);
25-
}
26-
27-
return `${id}-1`;
28-
}

pnpm-lock.yaml

+7-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)