Skip to content

Commit 1a8c64d

Browse files
committed
Improve logic that determines ordered list count
Group all "chains" of all blocks with the same type. Then look-up the block id in the given chain.
1 parent 868ba3b commit 1a8c64d

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

src/block.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ export type MapPageUrl = (pageId: string) => string;
4848

4949
interface Block {
5050
block: BlockType;
51-
parentBlock: BlockType;
5251
level: number;
52+
listNumber?: number;
5353
mapPageUrl?: MapPageUrl;
5454
}
5555

5656
export const Block: React.FC<Block> = props => {
57-
const { block, parentBlock, children } = props;
57+
const { block, children, listNumber, level } = props;
5858
const blockValue = block?.value;
5959
switch (blockValue?.type) {
6060
case "page":
61-
if (props.level === 0) return <div className="notion">{children}</div>;
61+
if (level === 0) return <div className="notion">{children}</div>;
6262
else {
6363
if (!blockValue.properties) return null;
6464
return (
@@ -111,14 +111,11 @@ export const Block: React.FC<Block> = props => {
111111
);
112112
case "bulleted_list":
113113
case "numbered_list":
114-
const isTopLevel = block.value.type !== parentBlock?.value?.type;
115-
const itemPosition =
116-
1 + (parentBlock.value.content?.indexOf(block.value.id) || 0);
117-
const wrapList = (content: React.ReactNode) =>
114+
const wrapList = (content: React.ReactNode, start?: number) =>
118115
blockValue.type === "bulleted_list" ? (
119116
<ul className="notion-list notion-list-disc">{content}</ul>
120117
) : (
121-
<ol start={itemPosition} className="notion-list notion-list-numbered">
118+
<ol start={start} className="notion-list notion-list-numbered">
122119
{content}
123120
</ol>
124121
);
@@ -140,7 +137,7 @@ export const Block: React.FC<Block> = props => {
140137
) : null;
141138
}
142139

143-
return isTopLevel ? wrapList(output) : output;
140+
return listNumber !== undefined ? wrapList(output, listNumber) : output;
144141

145142
case "image":
146143
case "embed":

src/renderer.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React from "react";
22
import { BlockMapType } from "./types";
33
import { Block, MapPageUrl } from "./block";
44

5+
import { getListNumber } from "./utils";
6+
57
export interface NotionRendererProps {
68
blockMap: BlockMapType;
79
currentId?: string;
@@ -17,14 +19,22 @@ export const NotionRenderer: React.FC<NotionRendererProps> = ({
1719
}) => {
1820
const id = currentId || Object.keys(blockMap)[0];
1921
const currentBlock = blockMap[id];
20-
if (!currentBlock) return null;
2122
const parentBlock = blockMap[currentBlock.value.parent_id];
23+
24+
if (!currentBlock) return null;
25+
26+
const listNumber =
27+
currentBlock.value.type === "numbered_list" &&
28+
parentBlock.value.type !== "numbered_list"
29+
? getListNumber(id, blockMap)
30+
: undefined;
31+
2232
return (
2333
<Block
2434
key={id}
2535
level={level}
2636
block={currentBlock}
27-
parentBlock={parentBlock}
37+
listNumber={listNumber}
2838
mapPageUrl={mapPageUrl}
2939
>
3040
{currentBlock?.value?.content?.map(contentId => (

src/utils.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,44 @@
1-
import { DecorationType } from "./types";
1+
import { DecorationType, BlockMapType } from "./types";
22

33
export const classNames = (...classes: Array<string | undefined | false>) =>
44
classes.filter(a => !!a).join(" ");
55

66
export const getTextContent = (text: DecorationType[]) => {
77
return text.reduce((prev, current) => prev + current[0], "");
88
};
9+
10+
const groupBlockContent = (blockMap: BlockMapType): string[][] => {
11+
const output: string[][] = [];
12+
13+
let lastType: string | undefined = undefined;
14+
let index = -1;
15+
16+
Object.keys(blockMap).forEach(id => {
17+
blockMap[id].value.content?.forEach(blockId => {
18+
const blockType = blockMap[blockId].value.type;
19+
20+
if (blockType !== lastType) {
21+
index++;
22+
lastType = blockType;
23+
output[index] = [];
24+
}
25+
26+
output[index].push(blockId);
27+
});
28+
29+
lastType = undefined;
30+
});
31+
32+
return output;
33+
};
34+
35+
export const getListNumber = (blockId: string, blockMap: BlockMapType) => {
36+
const groups = groupBlockContent(blockMap);
37+
const group = groups.find(g => g.includes(blockId));
38+
39+
if (!group) {
40+
return;
41+
}
42+
43+
return group.indexOf(blockId) + 1;
44+
};

0 commit comments

Comments
 (0)