import * as React from "react" ; import breakLines from "break-styled-lines" ; function makeGetDescriptorsOfChildren ( defaultFontStyle ) { return ( descriptors , children ) : { text : string ; font : string ; } [ ] => { if ( typeof children === "string" ) { return [ ... descriptors , { text : children , font : defaultFontStyle } ] ; } if ( typeof children === "number" ) { return [ ... descriptors , { text : children . toString ( ) , font : defaultFontStyle } ] ; } if ( ! React . isValidElement ( children ) ) { return descriptors ; } if ( isStyledTextElement ( children ) && typeof children . props . children === "string" ) { return [ ... descriptors , { text : children . props . children , font : children . props . fontStyle } ] ; } if ( isStyledTextElement ( children ) ) { return [ ... descriptors , ... React . Children . toArray ( children . props . children ) . reduce ( makeGetDescriptorsOfChildren ( children . props . fontStyle ) , [ ] ) ] ; } return [ ... descriptors , ... React . Children . toArray ( children . props . children ) . reduce ( makeGetDescriptorsOfChildren ( defaultFontStyle ) , [ ] ) ] ; } ; } function reinsertStringsIntoChildren ( [ accChildren , accStrings ] , children ) { if ( typeof children === "string" || typeof children === "number" ) { const [ firstString , ... restStrings ] = accStrings ; return [ [ ... accChildren , firstString ] , restStrings ] ; } if ( ! React . isValidElement ( children ) ) { return [ accChildren , accStrings ] ; } const [ subChildrenAcc , subStringsAcc ] = React . Children . toArray ( children . props . children ) . reduce ( reinsertStringsIntoChildren , [ [ ] , accStrings ] ) ; return [ [ ... accChildren , React . cloneElement ( children , { children : subChildrenAcc } ) ] , subStringsAcc ] ; } type StyledTextProps = { children : React . ReactNode ; fontStyle : string ; } ; function isStyledTextElement ( element ) { return element . type === StyledText ; } export function StyledText ( { children } ) { return < > { children } < />; } type LinebreakerProps = { fontStyle : string ; width : number ; } ; const Linebreaker = ( { children , fontStyle , width } ) => { const childrenArray = React . Children . toArray ( children ) ; const descriptors = childrenArray . reduce ( makeGetDescriptorsOfChildren ( fontStyle ) , [ ] ) ; const transformedStrings = breakLines ( descriptors , width , fontStyle ) ; const [ transformedChildren ] = childrenArray . reduce ( reinsertStringsIntoChildren , [ [ ] , transformedStrings ] ) ; return < div style = { { whiteSpace : "pre" } } > { transformedChildren } < /div>; } ; export default Linebreaker ;