Skip to content

Commit d8f0805

Browse files
committed
feat: 중첩 컴포넌트 재귀 처리
1 parent cabec6c commit d8f0805

File tree

3 files changed

+67
-27
lines changed

3 files changed

+67
-27
lines changed

packages/notion-to-jsx/src/components/Renderer/components/Block/BlockRenderer.tsx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
} from '../MemoizedComponents';
88
import { CodeBlock } from '../Code';
99
import { Heading1, Heading2, Heading3, Paragraph } from '../Typography';
10-
import { ListItem } from '../List';
1110

1211
export interface Props {
1312
block: any;
@@ -53,20 +52,6 @@ const BlockRenderer: React.FC<Props> = ({ block, onFocus, index }) => {
5352
</Heading3>
5453
);
5554

56-
case 'bulleted_list_item':
57-
return (
58-
<ListItem {...blockProps}>
59-
<MemoizedRichText richTexts={block.bulleted_list_item.rich_text} />
60-
</ListItem>
61-
);
62-
63-
case 'numbered_list_item':
64-
return (
65-
<ListItem {...blockProps}>
66-
<MemoizedRichText richTexts={block.numbered_list_item.rich_text} />
67-
</ListItem>
68-
);
69-
7055
case 'code':
7156
return (
7257
<div {...blockProps}>

packages/notion-to-jsx/src/components/Renderer/components/List/ListBlocksRenderer.tsx

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,67 @@
1-
import { BlockRenderer } from '../Block';
2-
import { List } from './List';
1+
import React from 'react';
2+
import { List, ListItem } from './List';
3+
import { MemoizedRichText } from '../MemoizedComponents';
34

45
export interface Props {
56
blocks: any[];
67
startIndex: number;
78
type: 'bulleted' | 'numbered';
89
}
910

11+
// 리스트 아이템을 렌더링하는 컴포넌트 (중첩 리스트 지원)
12+
const RecursiveListItem: React.FC<{
13+
block: any;
14+
index: number;
15+
}> = ({ block, index }) => {
16+
const blockProps = {
17+
tabIndex: 0,
18+
'data-block-id': block.id,
19+
};
20+
21+
const blockType = block.type;
22+
const richTexts = block[blockType]?.rich_text;
23+
24+
return (
25+
<ListItem {...blockProps}>
26+
<MemoizedRichText richTexts={richTexts} />
27+
{block.children && block.children.length > 0 && (
28+
<RecursiveListGroup
29+
blocks={block.children}
30+
type={blockType.split('_')[0] as 'bulleted' | 'numbered'}
31+
/>
32+
)}
33+
</ListItem>
34+
);
35+
};
36+
37+
// 중첩 리스트 그룹을 렌더링하는 컴포넌트
38+
const RecursiveListGroup: React.FC<{
39+
blocks: any[];
40+
type: 'bulleted' | 'numbered';
41+
}> = ({ blocks, type }) => {
42+
if (!blocks || blocks.length === 0) return null;
43+
44+
// 리스트 타입에 맞는 아이템만 필터링
45+
const listItems = blocks.filter(
46+
(block) => block.type === `${type}_list_item`
47+
);
48+
49+
if (listItems.length === 0) return null;
50+
51+
return (
52+
<List
53+
as={type === 'numbered' ? 'ol' : 'ul'}
54+
type={type}
55+
role="list"
56+
aria-label={type === 'bulleted' ? 'Bulleted list' : 'Numbered list'}
57+
>
58+
{listItems.map((block, index) => (
59+
<RecursiveListItem key={block.id} block={block} index={index} />
60+
))}
61+
</List>
62+
);
63+
};
64+
1065
const ListBlocksRenderer: React.FC<Props> = ({ blocks, startIndex, type }) => {
1166
let consecutiveItems = 0;
1267
for (let i = startIndex; i < blocks.length; i++) {
@@ -18,22 +73,23 @@ const ListBlocksRenderer: React.FC<Props> = ({ blocks, startIndex, type }) => {
1873
break;
1974
}
2075
}
76+
77+
const listItems = blocks.slice(startIndex, startIndex + consecutiveItems);
78+
2179
return (
2280
<List
2381
as={type === 'numbered' ? 'ol' : 'ul'}
2482
type={type}
2583
role="list"
2684
aria-label={type === 'bulleted' ? 'Bulleted list' : 'Numbered list'}
2785
>
28-
{blocks
29-
.slice(startIndex, startIndex + consecutiveItems)
30-
.map((block, index) => (
31-
<BlockRenderer
32-
key={block.id}
33-
block={block}
34-
index={startIndex + index}
35-
/>
36-
))}
86+
{listItems.map((block, index) => (
87+
<RecursiveListItem
88+
key={block.id}
89+
block={block}
90+
index={startIndex + index}
91+
/>
92+
))}
3793
</List>
3894
);
3995
};
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export { List, ListItem } from './List';
21
export { default as ListBlocksRenderer } from './ListBlocksRenderer';

0 commit comments

Comments
 (0)