import * as React from 'react' ; import { Block , Fragment , TextFragment } from '@zettel/core' ; import { RenderProps } from './types' ; type TextProps = RenderProps & { block : Block ; } ; const mapTextFramgent = ( props , offset , fragment ) => { const { block , renderStyle : RenderStyle , renderTextFragment : RenderTextFragment , } = props ; const key = `${ block . blockKey }-${ offset }` ; const fragmentProps = props . readOnly ? { } : { key , 'data-block-key' : block . blockKey , 'data-text-fragment' : true , 'data-fragment-start' : offset , 'data-fragment-end' : offset + fragment . text . length } ; const fragmentText = fragment . text ; let textFragment = ( fragment . styles || [ ] ) . reduce ( ( children , val ) => { if ( RenderStyle != null ) { return < RenderStyle key = { `${ fragmentProps . key }-${ val }` } style = { val } > { children } < /RenderStyle>; } else { return children ; } } , < span { ... fragmentProps } key = { `fragment-${ block . blockKey }-${ offset }` } > { fragmentText } < /span>); if ( RenderTextFragment ) { textFragment = < RenderTextFragment data - text - fragment = "true" key = { `block-${ block . blockKey }-${ offset }` } > { textFragment } < /RenderTextFragment>; } return textFragment ; } ; const reduceFragments = ( props , _offset = 0 , fragments ) : { rendered : any [ ] ; offset : number ; } => { return fragments . reduce ( ( { offset , rendered } , fragment ) => { if ( 'fragments' in fragment ) { const reducedFragments = reduceFragments ( props , offset + 1 , fragment . fragments ) ; return { rendered : rendered . concat ( [ reducedFragments . rendered ] ) , offset : reducedFragments . offset + 1 } ; } else { const renderedFragment = mapTextFramgent ( props , offset , fragment ) ; return { offset : offset + fragment . text . length , rendered : rendered . concat ( [ renderedFragment ] ) } ; } } , { offset : _offset , rendered : ( [ ] as any [ ] ) } ) ; } ; export default function EditorText ( props ) { const { block , renderStyle : RenderStyle , renderTextFragment : RenderTextFragment , } = props ; let textFragments = null ; if ( block . value . length > 0 ) { textFragments = reduceFragments ( props , 0 , block . fragments ) . rendered ; } else { textFragments = < span key = { `text-fragments-${ block . blockKey }` } data - text - fragment = "true" data - block - key = { block . blockKey } data - fragment - start = { 0 } data - fragment - end = { 0 } > < br /></span > ; } return < > { textFragments } < />; }