Giter Site home page Giter Site logo

react-blessed's Introduction

react-blessed

A React custom renderer for the blessed library.

This renderer should currently be considered as experimental, is subject to change and will only work with React's latest version (17.x.x, using Fiber).

demo

Summary

Installation

You can install react-blessed through npm:

# Be sure to install react>=17.0.0 & blessed>=0.1.81 before
npm install blessed react

# Then just install `react-blessed`
npm install react-blessed

Demo

For a quick demo of what you could achieve with such a renderer you can clone this repository and check some of the examples:

git clone https://github.com/Yomguithereal/react-blessed
cd react-blessed
npm install

# To see which examples you can run:
npm run demo

# Then choose one to run:
npm run demo animation

Usage

Rendering a basic application

import React, {Component} from 'react';
import blessed from 'blessed';
import {render} from 'react-blessed';

// Rendering a simple centered box
class App extends Component {
  render() {
    return (
      <box top="center"
           left="center"
           width="50%"
           height="50%"
           border={{type: 'line'}}
           style={{border: {fg: 'blue'}}}>
        Hello World!
      </box>
    );
  }
}

// Creating our screen
const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: 'react-blessed hello world'
});

// Adding a way to quit the program
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
  return process.exit(0);
});

// Rendering the React app using our screen
const component = render(<App />, screen);

Nodes & text nodes

Any of the blessed widgets can be rendered through react-blessed by using a lowercased tag title.

Text nodes, on the other hand, will be rendered by applying the setContent method with the given text on the parent node.

Refs

As with React's DOM renderer, react-blessed lets you handle the original blessed nodes, if you ever need them, through refs.

class CustomList extends Component {
  componentDidMount() {

    // Focus on the first box
    this.refs.first.focus();
  }

  render() {
    return (
      <element>
        <box ref="first">
          First box.
        </box>
        <box ref="second">
          Second box.
        </box>
      </element>
    );
  }
}

Events

Any blessed node event can be caught through a on-prefixed listener:

class Completion extends Component {
  constructor(props) {
    super(props);

    this.state = {progress: 0, color: 'blue'};

    const interval = setInterval(() => {
      if (this.state.progress >= 100)
        return clearInterval(interval);

      this.setState({progress: this.state.progress + 1});
    }, 50);
  }

  render() {
    const {progress} = this.state,
          label = `Progress - ${progress}%`;

    // See the `onComplete` prop
    return <progressbar label={label}
                        onComplete={() => this.setState({color: 'green'})}
                        filled={progress}
                        style={{bar: {bg: this.state.color}}} />;
  }
}

Classes

For convenience, react-blessed lets you handle classes looking like what react-native proposes.

Just pass object or an array of objects as the class of your components likewise:

// Let's say we want all our elements to have a fancy blue border
const stylesheet = {
  bordered: {
    border: {
      type: 'line'
    },
    style: {
      border: {
        fg: 'blue'
      }
    }
  }
};

class App extends Component {
  render() {
    return (
      <element>
        <box class={stylesheet.bordered}>
          First box.
        </box>
        <box class={stylesheet.bordered}>
          Second box.
        </box>
      </element>
    );
  }
}

You can of course combine classes (note that the given array of classes will be compacted):

// Let's say we want all our elements to have a fancy blue border
const stylesheet = {
  bordered: {
    border: {
      type: 'line'
    },
    style: {
      border: {
        fg: 'blue'
      }
    }
  },
  magentaBackground: {
    style: {
      bg: 'magenta'
    }
  }
};

class App extends Component {
  render() {

    // If this flag is false, then the class won't apply to the second box
    const backgroundForSecondBox = this.props.backgroundForSecondBox;

    return (
      <element>
        <box class={[stylesheet.bordered, stylesheet.magentaBackground]}>
          First box.
        </box>
        <box class={[
          stylesheet.bordered,
          backgroundForSecondBox && stylesheet.magentaBackground
        ]}>
          Second box.
        </box>
      </element>
    );
  }
}

Using blessed forks

Because blessed is not actively maintained in quite a while, you might want to use one of it's forks. To do that, import createBlessedRenderer function instead:

import React, {Component} from 'react';
import blessed from 'neo-blessed';
import {createBlessedRenderer} from 'react-blessed';

const render = createBlessedRenderer(blessed);

Using the devtools

react-blessed can be used along with React's own devtools for convenience. To do so, just install react-devtools in your project and all should work out of the box when running the Electron app, as soon as a react-blessed program is running on one of your shells.

Roadmap

  • Full support (meaning every tags and options should be handled by the renderer).
  • react-blessed-contrib to add some sugar over the blessed-contrib library (probably through full-fledged components).

Faq

  • <list/> : To enable interactions, add mouse={ true } and/or keys={ true }

Contribution

Contributions are obviously welcome.

Be sure to add unit tests if relevant and pass them all before submitting your pull request.

# Installing the dev environment
git clone [email protected]:Yomguithereal/react-blessed.git
cd react-blessed
npm install

# Running the tests
npm test

License

MIT

react-blessed's People

Contributors

chentsulin avatar d4rky-pl avatar dundalek avatar esnunes avatar fterdal avatar gaearon avatar guoshencheng avatar iamdustan avatar joeyespo avatar kabbi avatar kjirou avatar konsumer avatar lins05 avatar mrnice avatar speakingcode avatar vicentedealencar avatar yomguithereal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-blessed's Issues

Cannot find module 'react/lib/ReactInstanceHandles'

I get this error with this demo code:

import React from 'react'
import blessed from 'blessed'
import { render } from 'react-blessed'

export const App = () => (
  <box label='react-blessed demo'
       border={{type: 'line'}}
       style={{border: {fg: 'cyan'}}}>
    Random text here...
  </box>
)

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: 'react-blessed demo app'
})
screen.key(['escape', 'q', 'C-c'], (ch, key) => process.exit(0))

render(<App />, screen)

The Full error follows:

module.js:472
    throw err;
    ^

Error: Cannot find module 'react/lib/ReactInstanceHandles'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/konsumer/WORK/quest/node_modules/react-blessed/dist/render.js:15:37)
    at Module._compile (module.js:571:32)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/konsumer/WORK/quest/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)

npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v7.2.0
npm ERR! npm  v3.10.9
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `babel-node src/index.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script 'babel-node src/index.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the quest package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     babel-node src/index.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs quest
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls quest
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/konsumer/WORK/quest/npm-debug.log

Render diffs

Howdy,

At the moment the react-blessed renderer is recreating the tree with each render call, this differs from react-dom which attempts reconciliation with the dom rather than stamping over it (too much). This means that you can't use top-down data-flow with react-blessed as each render call effectively recreates the entire tree, and, actually, I've noticed a hefty slow down after repeatedly calling render, is there also a clear-up issue?

Am I right with this thinking? And is there a quick-win using one of the component update lifecycles to stop react-blessed from recreating everything each render?

I've stuck a side-by-side with react-dom in this repo, the blessed and browser files are near identical and they just render a list of items, the react-blessed one remounts (which I'm assuming means its recreating) the list each render whereas react-dom reconciles and should just be performing 2 dom ops (unhighlight old selected node, highlight selected node). I think.

Are there any plans to support working out the minimum amount of mutations required for blessed? I had a quick look and I'm guessing it is not an easy task as the blessed components have a richer public api than the dom generally does. Any ideas how to get unidirectional data shizzle working without having to totally recreate the diff-application algorithm?

Unable to scroll or select in <list>

Here is my sample component:

import React, {Component} from 'react'
import faker from 'faker'

const bs = () =>
  `${faker.commerce.productName()} is incredible ${faker.company.bs()}`

export default class App extends Component {
  render() {
    const items = Array(50).fill().map(bs)
    return (
      <element>
        <list
          label="List"
          class={{
            border: { type: 'line'},
            style: { border: { fg: 'blue' } },
          }}
          width="50%"
          height="50%"
          left="25%"
          top="25%"
          style={{
            item: { fg: 'black' },
            selected: { fg: 'white', bg: 'black' },
          }}
          items={ items }
          onSelect={ () => console.error('selected') }
        />
      </element>
    );
  }
}

And the result, as expected:

screenshot at 12-37-30

The only drawback is that there is no interaction, I tried with arrows, mousewheel, vi shortcuts, with or without vi property… Nothing moves :( If I add clickable={ true } onClick={ () => console.log('clicked') } the "clicked" messages appear normally, but still nothing about scrolling or selecting item.

Is there some extra configuration I missed?

conflict tag name with react declare

Hi, is here any support for typescript. i meet a problem.
Use a custom tag should declare namespace JSX. the code may like this

declare namespace JSX {
  interface IntrinsicElements {
    'box': any,
    'listtable': any,
  }
}

It works fine sometimes but when i use button. The tag name is conflict with origin JSX IntrinsicElements definition. any solutions?

Add a formal LICENSE

This code is very interesting, and looking at your package.json looks like you’re releasing it under the MIT license.

Could you please state it in the README and add a proper LICENSE file?

Question, would render to string be possible?

Hi, big fan of React Blessed here.

I've been wondering if it would be possible to render a sub-set of components to string or stdout without attaching the entire screen?

The reason I ask, is that I'd love to be able to use this with commander and inquirer based apps for rendering responses... for example:

console.log(ReactBlessed.renderToString(<FancyLogComponent {...someProps} />))

style instead of class

The current version of react-blessed accepts a class attribute that works in the same way as style of react-native and react itself. I understand the problem of using style because it conflicts with style element attribute however wouldn't be better to support only style and support it as react-native / react?

Publish release

Friendly reminder to publish a release to npm. Looks like the last (001f859) was in November 2015.

Update to latest version of react-reconciler

Even though the README says that this library will work with React's latest v16.x.x, it does not seem that we can use the new lifecycles and context APIs introduced in React v16.3. For example:

  • if I implement the new lifecycle APIs on components, they're not called
  • if I try to mount a component <Consumer>{value => /* renderable */}</Consumer> in the tree, I get an error Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
  • I get an error trying to use React.createRef

I think this is because this library is using an outdated version of react-reconciler. That's where the latter invariant violation originates, and if I look up that invariant in the latest version of react-reconciler, there is logic about the new context API that does not exist in the version used by this library.

Alignment issues

I'm not sure what is going on here, but any help would be appreciated.

My intention is Clyde#0001 BOT

Can't get <terminal> to work

trying to render a doesn't work.

Also, I would love the code behind the demo being shown in the gif. I'm trying to build a simple dashboard like utility that will run multiple watch commands and show them side-by-side.

My first big problem is that all the text rendered by react-blessed is currently white. I'm not sure how to make colors from the output of various commands show up.

Second, I would like to use the element from blessed sometimes, and that doesn't seem to work either.

Lastly, I'm still having trouble making any box scrollable. Any help on one or more of these issues will be very helpful. Thanks!

(Also React-blessed is amazing. Thanks for your work)

props in constructor does not match props in render

Expected:

constructor { foo: 'bar' }
render { foo: 'bar' }

Actual:

constructor { foo: 'bar' }
render {}

Code:

import _ from 'lodash'
import React, {Component} from 'react'
import blessed from 'blessed'
import {render} from 'react-blessed'

export default class PropsExample extends Component {
  constructor (props) {
    super(_.merge({foo: 'bar'}, props))
    console.log('constructor', this.props)
  }
  render () {
    console.log('render', this.props)
    return (
      <box
        top="center"
        left="center"
        width="50%"
        height="50%"
        border={{type: 'line'}}
        style={{border: {fg: 'blue'}}}>
        Hello World!
      </box>
    )
  }
}

var screen = new blessed.Screen()
screen.key('C-q', () => { process.exit() })
render(<PropsExample />, screen)

Can't get mouse events to work

I'm probably missing something obvious but I can't seem to add onPress={this.handlePress} to boxes—they don't respond.

idea: hybrid tui-gui apps

This may be a spin off project, but looking for thoughts

If we take the elements like <box>, <list>, <checkbox>, <table> and so on, most of these can be equated to CSS frameworks like bootstrap - so what if we create a plugin that does just that - renders using blessed in the terminal, and outputs bootstrap DOM structure equivalents for browser rendering

approaches:

Approach Option 1: Hybrid Fundamental Components

instead of using <box>, <list> etc. we supply a <Box>, <List> etc components (e.g. import {Box} from react-blessed). Some kind of transpilation flag (e.g. env=tui or env=gui) supplies either the react-blessed element or a DOM structure

Approach Option 2: React elements plugin

create a library that adds react-blessed element namespaces to react on the gui side, these then render the dom structures. This options requires zero changes to code, other than requiring react-blessed-bootstrap-dom-shim (better name needed) instead of react-blessed - however it's not as clean, there's potential for namespace clashes between dom elements and blessed elements

Doesn't Play Nice with react-dom/server

I have a terminal application that includes a server for rendering html with react. I tried to integrate react-blessed so that I could create a better experience in the terminal using react. Everything works as expected until a request comes in, which causes something to be rendered with react-dom/server.

When that happens, I get the error, "Invalid blessed element "html" which is created in src/ReactBlessedComponent.js on line 110. (after trying to render a component that begins with an tag)

Why is react trying to mount the element using react-blessed when I called ReactDomServer.render()?

I'm guessing it has something to do with the lowercased tags being mapped to blessed widgets but I'm not sure where to look.

If someone can point me in the right direction, I'd be willing to submit a pull request to fix the issue.

Could not redraw empty children now

Hello.

It seems the empty children can not be redrawn.

For example, if you run the following code:

import blessed from 'blessed';
import React, { Component } from 'react';
import { render } from 'react-blessed';

const screen = blessed.screen({
  debug: true,
  smartCSR: true,
});

screen.key(['escape', 'C-c'], function(ch, key) {
  return process.exit(0);
});

class Root extends Component {

  constructor() {
    super();

    this.state = {
      todos: [
        { id: 1, title: 'Foo' },
        { id: 2, title: 'Bar' },
        { id: 3, title: 'Baz' },
      ],
    };
  }

  componentDidMount() {
    // Push "r" key to remove the last row
    this.refs.first.key(['r'], (ch, key) => {
      const newTodos = this.state.todos.slice(0, this.state.todos.length - 1)
      screen.debug('todos:', newTodos.length);
      this.setState({
        todos: newTodos,
      });
    });
    this.refs.first.focus();
  }

  render() {
    return (
      <box {...{
        ref: 'first',
        top: 0,
        left: 0,
        width: 10,
        height: 5,
        style: {
          fg: 'white',
          bg: 'blue',
        },
      }}>
      {
        this.state.todos.map((todo, i) => {
          return <box {...{
            key: 'row-' + i,
            top: i,
            height: 1,
            content: todo.id + todo.title,
          }} />;
        })
      }
      </box>
    );
  }
}

render(<Root />, screen);

Initial display:

Pushed "r":

Pushed "r":

Pushed "r", but it is not redrawn:


Environments:


Thanks!

Invoking setState with a tree that uses <layout> makes screen go blank

Thanks for this awesome library 😄

I tried using the <layout> component from blessed which, although experimental, was a method I found to get inputs that shrink to their content's height rather than setting a percentage height on them.

I notice that the blessed readme calls the layout component experimental, but thought I'd offer a bug report anyway to see where it goes.

Using layout and setState causes the screen to go blank. See below for boilerplate to recreate the problem, with a tree that works next to it.

import React, {Component} from 'react';
import blessed from 'blessed';
import {render} from 'react-blessed';
import { exec } from 'child_process';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      searchFor: '',
      results: 'hiiiiiiiiiiiiiiiiiii'
    };
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState(() => {
        return {
          results: 'hi'
        }
      });
    }, 1000 );
  }

  render() {
    // this will make everything disappear after setState()
    return (
      <form>
        <layout
          width="100%"
          height="shrink"
        >
          <box height="shrink" width="100%" border={{type: 'line'}}>hi</box>
          <box height="shrink" width="100%" border={{type: 'line'}}>
            {this.state.results}
          </box>
        </layout>
      </form>
    );

    // this works
    return (
      <form>
        <box height="50%">hi</box>
        <box height="50%" width="100%" top="50%">
          {this.state.results}
        </box>
      </form>
    );
  }
}

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: 'react-blessed box animation'
});

screen.key(['escape', 'q', 'C-c'], function(ch, key) {
  return process.exit(0);
});

render(<App />, screen);

Implementation of ReactComponentEnvironment.replaceNodeWithMarkupByID

You know that because of react-titanium we share a lot of common pains :)

Well, looks like that:

  1. In [email protected] we still cannot re-inject ReactComponentEnvironment.
  2. In some specific cases we need to implement replaceNodeWithMarkupByID otherwise it will throw errors at us.

A simple test case that worked (which means failed!) for me is:

class Simple extends Component { /* ... */ }
class Advanced extends Component { /* ... */ }

class Root extends Component {
  render() {
    return this.state.something ? <Simple /> : <Advanced />;
  }
}

and then change the value of state.something to a truthy and React will understand that it must completely replace the nodes rendered by Advanced and calls replaceNodeWithMarkupByID which of course doesn’t work in our scenarios.

May I suggest you to check if you need to implement it too?

Add example in vanilla Javascript

Example are written in jsx, and compiled result is imposible to understand. Please add a simple demo in vanilla Node.js javascript to show how it can be used the library, and if possible how to define templates to set the elements too.

Numbers seem to break text nodes

Changing any text node to include a number kills it. (I mean the number type.)
I think, since it works on web, it should work here too, shouldn't it?

Example:

export default class App extends Component {
  render() {
    return (
      <box label='React Blessed Hot Motion'
           border={{type: 'line'}}
           style={{border: {fg: 'cyan'}}}>
        Hey, {42}
      </box>
    );
  }
}

screen shot 2015-08-26 at 14 53 43

label styling isn't working

with blessed, I am able to set the color for the label's style inline, e.g.

var box = blessed.box({
  label: ' {blue-fg}Prompt{/blue-fg} ',
  border: {
    type: 'line'
  }
  }
});

But when I try to do the same from react-blessed, it just includes the style declarations as is, inside of the label itself

image

Is there any way to style the label's color?

Replacing react dependency by using babel transforms

Hey!

Would it be (generally speaking) possible to replace React with the babel-transform-jsx plugin? As far as I understood, react-blessed uses React under the hood, at runtime. This sounds like a huge dependency for just a cli app. Ink for example uses the transform approach, transpiling JSX at compile time to normal function calls.

I am not sure how much reward one would get compared to the time needed to port.

Error: Cannot find module 'react/lib/ReactInstanceHandles' @ React v16

My dependencies:

  "dependencies": {
    "blessed": "^0.1.81",
    "react": "^16.2.0",
    "react-blessed": "^0.2.0",
    "reason-react": "^0.3.0"
  },

My test code:

import React, {Component} from 'react';
import blessed from 'blessed';
import {render} from 'react-blessed';

// Rendering a simple centered box
class App extends Component {
  render() {
    return (
      <box top="center"
           left="center"
           width="50%"
           height="50%"
           border={{type: 'line'}}
           style={{border: {fg: 'blue'}}}>
        Hello World!
      </box>
    );
  }
}

// Creating our screen
const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: 'react-blessed hello world'
});

// Adding a way to quit the program
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
  return process.exit(0);
});

// Rendering the React app using our screen
const component = render(<App />, screen);

Output:

> node test.js
module.js:529
    throw err;
    ^

Error: Cannot find module 'react/lib/ReactInstanceHandles'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/r627543/Code/repohunter/node_modules/react-blessed/dist/render.js:8:29)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)```

Thinking about React 15 support

I'd like to help contribute migrating this project to React 15, and I think we could greatly reduce the amount of code necessary. For instance, right now the code is doing a ton of dependency injection since we don't have screen in scope. What if this library looked something like this instead?

import React, { Component } from 'react';
import blessed from 'blessed';
import { Element, Box, render } from 'react-blessed';

export default class TerminalApp extends Component {
  render() {
    return (
      <Element>
        <Box width="100%" height="50%" top="0%">Top</Box>
        <Box width="100%" height="50%" top="50%">Bottom</Box>
      </Element>
    );
  }
}

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
});

render(<TerminalApp />, screen);

Mouse events

In the blessed Program docs:

enableMouse([el]) - Enable mouse events for the screen and optionally an element (automatically called when a form of on('mouse') is bound).

Because react-blessed only listens for 'event', the mouse events are never bound. This causes a lot of interactions, such as focusing an input with a click, to be ignored. Enabling it globally doesn't seemt to affect the children.

Maybe just .on('mouse', noop)? It seems to fix the problem, but I'm not sure if there are any other side effects.

Allow other blessed apps

Given blessed is... somewhat unmaintained, it would be nice to be able to pass in a different function to be used (ie - only require blessed if none is passed). That way we could use forked versions with updated code.

Thoughts?

Proposal: <screen /> root component

This is just a quick proposal to change the current render/mount syntax.

The motivation is to remove the need to require both react-blessed and blessed and let react-blessed manage both.

import {Screen, render} from 'react-blessed';

const App = () => (
  <Screen
    autoPadding={true}
    smartCSR={true}
    title="react-blessed hello world"
  >
    <box top="center"
         left="center"
         width="50%"
         height="50%"
         border={{type: 'line'}}
         style={{border: {fg: 'blue'}}}>
      Hello World!
    </box>
  </Screen>
);

render(<App />);

element resizing is not working?

Hello.

I tried to resize a box by like the following code, but it was not working.

import blessed from 'blessed';
import React, { Component } from 'react';
import { render } from 'react-blessed';

const screen = blessed.screen({
  debug: true,
  smartCSR: true,
});

screen.key(['escape', 'C-c'], function(ch, key) {
  return process.exit(0);
});

class Root extends Component {

  constructor() {
    super();

    this.state = {
      top: 0,
      left: 0,
      width: 2,
      height: 1,
    };
  }

  componentDidMount() {
    setInterval(() => {
      this.setState({
        // top and left are applied ..
        top: this.state.top + 1,
        left: this.state.left + 1,
        // .. but width and height are not applied
        width: this.state.width + 1,
        height: this.state.height + 1,
      });
    }, 1000);
  }

  render() {

    let boxProps = Object.assign({
      style: {
        fg: 'white',
        bg: 'magenta',
      },
    }, this.state);

    return (
      <box {...{
        top: 0,
        left: 0,
        width: 40,
        height: 20,
        style: {
          fg: 'white',
          bg: 'blue',
        },
      }}>
        <box {...boxProps}/>
      </box>
    );
  }
}

render(<Root />, screen);

So I added width and height to RAW_ATTRIBUTES (https://github.com/Yomguithereal/react-blessed/blob/master/src/update.js#L9), then it seemed to have moved.

Is this change wrong?


Environments:

How do I make interactive applications?

I feel like I'm missing something, but I'm struggling to figure out how to make interactive apps with react-blessed. All of the examples appear to be purely rendering content with zero user interaction. Is there an example somewhere of an interactive app?

Checkbox does not update checked state

For example in this repro case checkbox stays unchecked:

import React, {Component} from 'react';
import blessed from 'blessed';
import {render} from 'react-blessed';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: false
    };
  }

  componentDidMount() {
    setTimeout(() => this.setState({ checked: true }), 10);
  }

  render() {
    return <checkbox checked={this.state.checked} />;
  }
}

const screen = blessed.screen();

screen.key(['escape', 'q', 'C-c'], function(ch, key) {
  return process.exit(0);
});

render(<App />, screen);

From my understading adding checked into RAW_ATTRIBUTES should fix the issue.

As a workaround for now I use <checkbox value={this.state.checked}> and monkeypatch blessed:

blessed.widget.checkbox.prototype.setValue = function(value) {
  if (value) {
    this.check();
  } else {
    this.uncheck();
  }
}

Update to latest version of React: injectEmptyComponent undefined

I know the docs say to use react 0.14.0 but it also says ">="
Is there plans to upgrade to a new version of react?
The part that seems broken for me is that:
ReactInjection.EmptyComponent no longer has function injectEmptyComponent as it now takes a factory function:

var ReactEmptyComponentInjection = {
 injectEmptyComponentFactory: function(factory) {
   emptyComponentFactory = factory;
  },
};

blessed-contrib support

Hey @Yomguithereal!

What are your plans for blessed-contrib support?
Were you thinking of adding its widgets to this module or would you create a different one?

I'm asking this because I wanted to use some of their widgets with react-blessed and didn't find any good way of doing it.

I did a little test where I hacked blessed-contrib into react-blessed and it seems to work fine.

Please let me know what was your idea :)

Question: in the samples, from which module is "box" being imported?

In the samples I see code snippets like this:

class Jobs extends Component {
  render() {
    return <box label="Jobs"
                class={stylesheet.bordered}
                left="60%"
                width="40%"
                height="60%" />;
  }
}

But I don't see where is this box element is imported from. I can't import statements for it, any hints?

focus and tab order

@Yomguithereal Thanks for this great library!

I was looking for ways to put a component in focus but couldn't find it in the documentation. Is there anywhere I can look this up?

Thanks!
Ge

`keys` prop does not work on List component

Example:

import React, { Component } from "react";
import blessed from "blessed";
import { render } from "react-blessed";

class App extends Component {
  render() {
    return (
      <list
        keys={true}
        width="100%"
        height="100%"
        top={0}
        left={0}
        fg="green"
        items={["1", "2", "3", "4"]}
      />
    );
  }
}

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: "react-blessed hello world",
});

screen.key(["escape", "q", "C-c"], function(ch, key) {
  return process.exit(0);
});

const component = render(<App />, screen)

And a working vanilla-blessed solution:

const blessed = require("blessed");

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: "react-blessed hello world",
});

// Adding a way to quit the program
screen.key(["escape", "q", "C-c"], function(ch, key) {
  return process.exit(0);
});

const list = blessed.list({
  parent: screen,
  keys: true,
  left: 0,
  top: 0,
  width: "100%",
  height: "100%",
  fg: "green",
  items: ["1", "2", "3", "4"],
});

screen.render();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.