Yomguithereal / react-blessed

A react renderer for blessed.
MIT License
4.45k stars 177 forks source link

Render Array of JSX elements? #123

Closed zach-is-my-name closed 2 years ago

zach-is-my-name commented 2 years ago

Edit: At the 11th hour I realized this is likely due to blessed-style positioning. I'll leave the issue open in case you'd like to chime in.

Hi, great library, really does what others can't by combining React AND Blessed... really thrilled to use it

anyway, I'm trying to parse a string interpolated with JSX elements and render it with the help of some libraries: https://github.com/iansinnott/react-string-replace

Will react-blessed consume and array of elements as react-dom does?

For example:

const markdown = "Upcoming dates of note (new/changes in bold):

    * Oct 25 – Dec 13 – {"linkText":"Gitcoin DAO Global hackathon","url":"https://gitcoin.co/hackathon/dao-global/onboard"} (virtual)
    * Nov 1-4 – {"linkText":"NFT.NYC","url":"https://www.nft.nyc/"}
    * Nov 5 – PoW switch off {"linkText":"community call","url":"https://twitter.com/trent_vanepps/status/1452680694698856460"}"
import React from 'react';
import ButtonBox from './ButtonBox'
import LinkButton from './LinkButton'
import {markdown} from './markdown'
const reactStringReplace = require('react-string-replace')

function App() {
  return (
    <box someconfig>
    {extractJsx(markdown)}
    </box>
  );
}
 function extractJsx(string) { 
   const regex = /(\{"linkText":".+?","url":"https?:\/\/.+?"\})/g
   const replaceResult = reactStringReplace(string, regex, (match, index) => {     const urlRegex = /"url":"(https?:\/\/.+?)"/
     const url = match.match(urlRegex)[1]
     const linkTextRegex = /\{"linkText":(.+?)"/
     const linkText = match.match(linkTextRegex)[1]

     return (<ButtonBox linkText={linkText} url={url} key={index} />)
    })
     console.log(replaceResult)
     return replaceResult
 }
}

// console.log( replaceResult) [ 0: "Upcoming dates of note (new/changes in bold):\n Oct 25 – Dec 13 – " 1: {$$typeof: Symbol(react.element), key: '1', ref: null, props: {…}, type: ƒ, …} 2: " (virtual)\n Nov 1-4 – " 3: {$$typeof: Symbol(react.element), key: '2', ref: null, props: {…}, type: ƒ, …} 4: "\n * Nov 5 – PoW switch off " 5: {$$typeof: Symbol(react.element), key: '3', ref: null, props: {…}, type: ƒ, …} 6: "" ]

React-Blessed Screenshot from 2021-10-31 05-56-06

With react-dom this works fine with <div>'s rather than <box>'s

React-Dom Screenshot from 2021-11-01 01-43-59

Yomguithereal commented 2 years ago

Hello @zach-is-my-name. I am not sure I understand all of the issue but I guess your edit holds at least part of the answer which is indeed that blessed elements must have their positioning defined indeed as it does not offer some kind of automatic layout as the HTML/CSS DOM in the browser. Did you try incrementing a y position of the ButtonBox element in your callback? Does it solve your issue?

zach-is-my-name commented 2 years ago

Thanks for the reply, I discoved that my original issue was not an issue. React-Blessed renders an array of elements the same as react-dom.

Did you try incrementing a y position of the ButtonBox element in your callback?

I didn't touch the callback yet but I ran a quick test to confirm what I just mentioned. What I don't get now is why giving a percent to the top property works. But giving an giving an absolute value to top does not. Can you give me a hint?

 let testArr = [] 
testArr.push(<box top='50%' key={1}>test1</box>) 
testArr.push(<box top='60%'  focused={true} key={2}>test2</box>) 
testArr.push(<box top='70%' key={3}>test3</box>) 
  return(
    <box 
    top={"center"}
    left={"center"}
    width={"100%"}
    height={"100%"}  
    tags
    focused={true}
    keyable={true}
    input={true}
    onKeypress={keyHandler}
    mouse 
    onClick={clickHandler}
    scrollable={true}
    ref={mainBoxRef}
    >
     {testArr}
    <Cursor cursorTop={cursorTop} cursorLeft={cursorLeft} />   
    </box>
)

Screenshot from 2021-11-01 06-23-32

 let testArr = [] 
testArr.push(<box top='10' key={1}>test1</box>) 
testArr.push(<box top='20'  focused={true} key={2}>test2</box>) 
testArr.push(<box top='30' key={3}>test3</box>) 
  return(
    <box 
    top={"center"}
    left={"center"}
    width={"100%"}
    height={"100%"}  
    tags
    focused={true}
    keyable={true}
    input={true}
    onKeypress={keyHandler}
    mouse 
    onClick={clickHandler}
    scrollable={true}
    ref={mainBoxRef}
    >
     {testArr}
    <Cursor cursorTop={cursorTop} cursorLeft={cursorLeft} />   
    </box>
)

Screenshot from 2021-11-01 06-28-38

Or even why the 2nd and 3rd elements are visable. If my positioning is broken and the elements are stacking, why do I see two elements and not 1. Confused.

Yomguithereal commented 2 years ago

For absolute position, it should be numbers so <box top={10} /> not <box top='10' />.

zach-is-my-name commented 2 years ago

Thought I tried that, maybe not. Thanks