@@ -62,7 +62,7 @@ export function PortableText<B extends TypedObject = PortableTextBlock>({
6262 return < > { rendered } </ >
6363}
6464
65- function getNodeRenderer (
65+ function getNodeRenderer (
6666 components : PortableTextReactComponents ,
6767 handleMissingComponent : MissingComponentHandler ,
6868) : NodeRenderer {
@@ -71,23 +71,59 @@ function getNodeRenderer (
7171 const key = node . _key || `node-${ index } `
7272
7373 if ( isPortableTextToolkitList ( node ) ) {
74- return renderList ( node , index , key )
74+ return (
75+ < RenderList
76+ key = { key }
77+ renderNode = { renderNode }
78+ components = { components }
79+ handleMissingComponent = { handleMissingComponent }
80+ node = { node }
81+ index = { index }
82+ />
83+ )
7584 }
7685
7786 if ( isPortableTextListItemBlock ( node ) ) {
78- return renderListItem ( node , index , key )
87+ return (
88+ < RenderListItem
89+ key = { key }
90+ renderNode = { renderNode }
91+ components = { components }
92+ handleMissingComponent = { handleMissingComponent }
93+ node = { node }
94+ index = { index }
95+ />
96+ )
7997 }
8098
8199 if ( isPortableTextToolkitSpan ( node ) ) {
82- return renderSpan ( node , index , key )
100+ return (
101+ < RenderSpan
102+ key = { key }
103+ renderNode = { renderNode }
104+ components = { components }
105+ handleMissingComponent = { handleMissingComponent }
106+ node = { node }
107+ />
108+ )
83109 }
84110
85111 if ( hasCustomComponentForNode ( node ) ) {
86112 return renderCustomBlock ( node , index , key , isInline )
87113 }
88114
89115 if ( isPortableTextBlock ( node ) ) {
90- return renderBlock ( node , index , key , isInline )
116+ return (
117+ < RenderBlock
118+ key = { key }
119+ renderNode = { renderNode }
120+ components = { components }
121+ handleMissingComponent = { handleMissingComponent }
122+ node = { node }
123+ index = { index }
124+ isInline = { isInline }
125+ />
126+ )
91127 }
92128
93129 if ( isPortableTextToolkitTextNode ( node ) ) {
@@ -101,123 +137,6 @@ function getNodeRenderer (
101137 return node . _type in components . types
102138 }
103139
104- function renderListItem ( node : PortableTextListItemBlock , index : number , key : string ) {
105- const tree = serializeBlock ( { node, index, isInline : false , renderNode} )
106- const renderer = components . listItem
107- const handler = typeof renderer === 'function' ? renderer : renderer [ node . listItem ]
108- const Li = handler || components . unknownListItem
109-
110- if ( Li === components . unknownListItem ) {
111- const style = node . listItem || 'bullet'
112- handleMissingComponent ( unknownListItemStyleWarning ( style ) , {
113- type : style ,
114- nodeType : 'listItemStyle' ,
115- } )
116- }
117-
118- let children = tree . children
119- if ( node . style && node . style !== 'normal' ) {
120- // Wrap any other style in whatever the block serializer says to use
121- const { listItem : _listItem , ...blockNode } = node
122- children = renderNode ( {
123- node : blockNode ,
124- index,
125- isInline : false ,
126- renderNode,
127- } )
128- }
129-
130- return (
131- < Li key = { key } value = { node } index = { index } isInline = { false } renderNode = { renderNode } >
132- { children }
133- </ Li >
134- )
135- }
136-
137- function renderList ( node : ReactPortableTextList , index : number , key : string ) {
138- const children = node . children . map ( ( child , childIndex ) =>
139- renderNode ( {
140- node : child . _key ? child : { ...child , _key : `li-${ index } -${ childIndex } ` } ,
141- index : childIndex ,
142- isInline : false ,
143- renderNode,
144- } ) ,
145- )
146-
147- const component = components . list
148- const handler = typeof component === 'function' ? component : component [ node . listItem ]
149- const List = handler || components . unknownList
150-
151- if ( List === components . unknownList ) {
152- const style = node . listItem || 'bullet'
153- handleMissingComponent ( unknownListStyleWarning ( style ) , {
154- nodeType : 'listStyle' ,
155- type : style ,
156- } )
157- }
158-
159- return (
160- < List key = { key } value = { node } index = { index } isInline = { false } renderNode = { renderNode } >
161- { children }
162- </ List >
163- )
164- }
165-
166- function renderSpan ( node : ToolkitNestedPortableTextSpan , _index : number , key : string ) {
167- const { markDef, markType, markKey} = node
168- const Span = components . marks [ markType ] || components . unknownMark
169- const children = node . children . map ( ( child , childIndex ) =>
170- renderNode ( {
171- node : child ,
172- index : childIndex ,
173- isInline : true ,
174- renderNode,
175- } ) ,
176- )
177-
178- if ( Span === components . unknownMark ) {
179- handleMissingComponent ( unknownMarkWarning ( markType ) , {
180- nodeType : 'mark' ,
181- type : markType ,
182- } )
183- }
184-
185- return (
186- < Span
187- key = { key }
188- text = { spanToPlainText ( node ) }
189- value = { markDef }
190- markType = { markType }
191- markKey = { markKey }
192- renderNode = { renderNode }
193- >
194- { children }
195- </ Span >
196- )
197- }
198-
199- function renderBlock ( node : PortableTextBlock , index : number , key : string , isInline : boolean ) {
200- const { _key, ...props } = serializeBlock ( {
201- node,
202- index,
203- isInline,
204- renderNode,
205- } )
206- const style = props . node . style || 'normal'
207- const handler =
208- typeof components . block === 'function' ? components . block : components . block [ style ]
209- const Block = handler || components . unknownBlockStyle
210-
211- if ( Block === components . unknownBlockStyle ) {
212- handleMissingComponent ( unknownBlockStyleWarning ( style ) , {
213- nodeType : 'blockStyle' ,
214- type : style ,
215- } )
216- }
217-
218- return < Block key = { key } { ...props } value = { props . node } renderNode = { renderNode } />
219- }
220-
221140 function renderText ( node : ToolkitTextNode , key : string ) {
222141 if ( node . text === '\n' ) {
223142 const HardBreak = components . hardBreak
@@ -259,6 +178,170 @@ function getNodeRenderer (
259178 return renderNode
260179}
261180
181+ function RenderList ( {
182+ renderNode,
183+ components,
184+ handleMissingComponent,
185+ node,
186+ index,
187+ } : {
188+ renderNode : NodeRenderer
189+ components : PortableTextReactComponents
190+ handleMissingComponent : MissingComponentHandler
191+ node : ReactPortableTextList
192+ index : number
193+ } ) {
194+ const children = node . children . map ( ( child , childIndex ) =>
195+ renderNode ( {
196+ node : child . _key ? child : { ...child , _key : `li-${ index } -${ childIndex } ` } ,
197+ index : childIndex ,
198+ isInline : false ,
199+ renderNode,
200+ } ) ,
201+ )
202+
203+ const component = components . list
204+ const handler = typeof component === 'function' ? component : component [ node . listItem ]
205+ const List = handler || components . unknownList
206+
207+ if ( List === components . unknownList ) {
208+ const style = node . listItem || 'bullet'
209+ handleMissingComponent ( unknownListStyleWarning ( style ) , {
210+ nodeType : 'listStyle' ,
211+ type : style ,
212+ } )
213+ }
214+
215+ return (
216+ < List value = { node } index = { index } isInline = { false } renderNode = { renderNode } >
217+ { children }
218+ </ List >
219+ )
220+ }
221+
222+ function RenderListItem ( {
223+ renderNode,
224+ components,
225+ handleMissingComponent,
226+ node,
227+ index,
228+ } : {
229+ components : PortableTextReactComponents
230+ handleMissingComponent : MissingComponentHandler
231+ renderNode : NodeRenderer
232+ node : PortableTextListItemBlock
233+ index : number
234+ } ) {
235+ const tree = serializeBlock ( { node, index, isInline : false , renderNode} )
236+ const renderer = components . listItem
237+ const handler = typeof renderer === 'function' ? renderer : renderer [ node . listItem ]
238+ const Li = handler || components . unknownListItem
239+
240+ if ( Li === components . unknownListItem ) {
241+ const style = node . listItem || 'bullet'
242+ handleMissingComponent ( unknownListItemStyleWarning ( style ) , {
243+ type : style ,
244+ nodeType : 'listItemStyle' ,
245+ } )
246+ }
247+
248+ let children = tree . children
249+ if ( node . style && node . style !== 'normal' ) {
250+ // Wrap any other style in whatever the block serializer says to use
251+ const { listItem : _listItem , ...blockNode } = node
252+ children = renderNode ( {
253+ node : blockNode ,
254+ index,
255+ isInline : false ,
256+ renderNode,
257+ } )
258+ }
259+
260+ return (
261+ < Li value = { node } index = { index } isInline = { false } renderNode = { renderNode } >
262+ { children }
263+ </ Li >
264+ )
265+ }
266+
267+ function RenderSpan ( {
268+ renderNode,
269+ components,
270+ handleMissingComponent,
271+ node,
272+ } : {
273+ renderNode : NodeRenderer
274+ components : PortableTextReactComponents
275+ handleMissingComponent : MissingComponentHandler
276+ node : ToolkitNestedPortableTextSpan
277+ } ) {
278+ const { markDef, markType, markKey} = node
279+ const Span = components . marks [ markType ] || components . unknownMark
280+ const children = node . children . map ( ( child , childIndex ) =>
281+ renderNode ( {
282+ node : child ,
283+ index : childIndex ,
284+ isInline : true ,
285+ renderNode,
286+ } ) ,
287+ )
288+
289+ if ( Span === components . unknownMark ) {
290+ handleMissingComponent ( unknownMarkWarning ( markType ) , {
291+ nodeType : 'mark' ,
292+ type : markType ,
293+ } )
294+ }
295+
296+ return (
297+ < Span
298+ text = { spanToPlainText ( node ) }
299+ value = { markDef }
300+ markType = { markType }
301+ markKey = { markKey }
302+ renderNode = { renderNode }
303+ >
304+ { children }
305+ </ Span >
306+ )
307+ }
308+
309+ function RenderBlock ( {
310+ renderNode,
311+ components,
312+ handleMissingComponent,
313+ node,
314+ index,
315+ isInline,
316+ } : {
317+ renderNode : NodeRenderer
318+ components : PortableTextReactComponents
319+ handleMissingComponent : MissingComponentHandler
320+ node : PortableTextBlock
321+ index : number
322+ isInline : boolean
323+ } ) {
324+ const { _key, ...props } = serializeBlock ( {
325+ node,
326+ index,
327+ isInline,
328+ renderNode,
329+ } )
330+ const style = props . node . style || 'normal'
331+ const handler =
332+ typeof components . block === 'function' ? components . block : components . block [ style ]
333+ const Block = handler || components . unknownBlockStyle
334+
335+ if ( Block === components . unknownBlockStyle ) {
336+ handleMissingComponent ( unknownBlockStyleWarning ( style ) , {
337+ nodeType : 'blockStyle' ,
338+ type : style ,
339+ } )
340+ }
341+
342+ return < Block { ...props } value = { props . node } renderNode = { renderNode } />
343+ }
344+
262345function serializeBlock ( options : Serializable < PortableTextBlock > ) : SerializedBlock {
263346 const { node, index, isInline, renderNode} = options
264347 const tree = buildMarksTree ( node )
0 commit comments