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' ;
3
4
4
5
export interface Props {
5
6
blocks : any [ ] ;
6
7
startIndex : number ;
7
8
type : 'bulleted' | 'numbered' ;
8
9
}
9
10
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
+
10
65
const ListBlocksRenderer : React . FC < Props > = ( { blocks, startIndex, type } ) => {
11
66
let consecutiveItems = 0 ;
12
67
for ( let i = startIndex ; i < blocks . length ; i ++ ) {
@@ -18,22 +73,23 @@ const ListBlocksRenderer: React.FC<Props> = ({ blocks, startIndex, type }) => {
18
73
break ;
19
74
}
20
75
}
76
+
77
+ const listItems = blocks . slice ( startIndex , startIndex + consecutiveItems ) ;
78
+
21
79
return (
22
80
< List
23
81
as = { type === 'numbered' ? 'ol' : 'ul' }
24
82
type = { type }
25
83
role = "list"
26
84
aria-label = { type === 'bulleted' ? 'Bulleted list' : 'Numbered list' }
27
85
>
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
+ ) ) }
37
93
</ List >
38
94
) ;
39
95
} ;
0 commit comments