diff --git a/.gitignore b/.gitignore
index 5b6e767..bb833e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
*.log
node_modules
dist
+.idea
diff --git a/README.md b/README.md
index e4aef2b..b0e106d 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ This renderer should currently be considered as experimental, is subject to chan
* [Refs](#refs)
* [Events](#events)
* [Classes](#classes)
+ * [Using blessed forks](#using-blessed-forks)
* [Roadmap](#roadmap)
* [FAQ](#faq)
* [Contribution](#contribution)
@@ -236,6 +237,18 @@ class App extends Component {
}
```
+### Using blessed forks
+
+Because [blessed](https://github.com/chjj/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);
+```
+
## Roadmap
* Full support (meaning every tags and options should be handled by the renderer).
diff --git a/examples/neo-blessed.jsx b/examples/neo-blessed.jsx
new file mode 100644
index 0000000..bc48220
--- /dev/null
+++ b/examples/neo-blessed.jsx
@@ -0,0 +1,29 @@
+import React, {Component} from 'react';
+import blessed from 'neo-blessed';
+import {createBlessedRenderer} from '../src';
+
+const render = createBlessedRenderer(blessed);
+
+class App extends Component {
+ render() {
+ return (
+
+ This example uses neo-blessed fork of blessed library.
+
+ );
+ }
+}
+
+const screen = blessed.screen({
+ autoPadding: true,
+ smartCSR: true,
+ title: 'react-blessed demo app'
+});
+
+screen.key(['escape', 'q', 'C-c'], function(ch, key) {
+ return process.exit(0);
+});
+
+const component = render(, screen);
diff --git a/package.json b/package.json
index 9ce6746..2c2cb90 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"babel-preset-stage-0": "^6.22.0",
"babel-register": "^6.22.0",
"blessed": "^0.1.81",
+ "neo-blessed": "^0.2.0",
"mocha": "^4.0.1",
"react": "^16.2.0"
},
diff --git a/run.js b/run.js
index 3f7d3ea..894181b 100644
--- a/run.js
+++ b/run.js
@@ -7,6 +7,7 @@ const examples = [
'demo',
'form',
'framer',
+ 'neo-blessed',
'progressbar',
'remove',
];
diff --git a/src/fiber/fiber.js b/src/fiber/fiber.js
index cc85c8e..d061af6 100644
--- a/src/fiber/fiber.js
+++ b/src/fiber/fiber.js
@@ -4,7 +4,6 @@ import type { HostConfig, Reconciler } from 'react-fiber-types';
const {
debounce
} = require('lodash');
-const blessed = require('blessed');
const ReactFiberReconciler : (
hostConfig: HostConfig<*, *, *, *, *, *, *, *>
) => Reconciler<*, *, *> = require('react-reconciler');
@@ -21,201 +20,203 @@ const {
const emptyObject = {};
-type Instance = {
- type: string,
- props: Object,
- _eventListener: Function,
- _updating: boolean,
- screen: typeof blessed.Screen,
-};
-
-const BlessedReconciler = ReactFiberReconciler({
- getRootHostContext(rootContainerInstance : Container) : HostContext {
- return emptyObject;
- },
- getChildHostContext(parentHostContext : HostContext, type: string) : HostContext {
- return emptyObject;
- },
- getPublicInstance(instance) {
- return instance;
- },
-
- createInstance(
- type : string,
- props : Props,
- rootContainerInstance : Container,
- hostContext : HostContext,
- internalInstanceHandle : Object
- ) {
- const {children, ...appliedProps} = solveClass(props);
- const instance = blessed[type](appliedProps);
- instance.props = props;
- instance._eventListener = (...args) => eventListener(instance, ...args);
- instance.on('event', instance._eventListener);
-
- return instance;
- },
-
- appendInitialChild(
- parentInstance : Instance,
- child : Instance | TextInstance
- ) : void {
- parentInstance.append(child);
- },
-
- finalizeInitialChildren(
- instance : Instance,
- type : string,
- props : Props,
- rootContainerInstance : Container
- ) : boolean {
- const {children, ...appliedProps} = solveClass(props);
- update(instance, appliedProps);
- instance.props = props;
- return false;
- },
-
- prepareUpdate(
- instance : Instance,
- type : string,
- oldProps : Props,
- newProps : Props,
- rootContainerInstance : Container,
- hostContext : HostContext
- ) : null | Array {
- return solveClass(newProps);
- },
-
- shouldSetTextContent(props : Props) : boolean {
- return false;
- },
-
- shouldDeprioritizeSubtree(type: string, props: Props): boolean {
- return !!props.hidden;
- },
-
- now: Date.now,
-
- createTextInstance(
- text : string,
- rootContainerInstance : Container,
- hostContext : HostContext,
- internalInstanceHandle : OpaqueHandle
- ) : TextInstance {
- return blessed.text({content: text});
- },
+const createBlessedRenderer = function(blessed) {
+ type Instance = {
+ type: string,
+ props: Object,
+ _eventListener: Function,
+ _updating: boolean,
+ screen: typeof blessed.Screen,
+ };
+
+ const BlessedReconciler = ReactFiberReconciler({
+ getRootHostContext(rootContainerInstance : Container) : HostContext {
+ return emptyObject;
+ },
+ getChildHostContext(parentHostContext : HostContext, type: string) : HostContext {
+ return emptyObject;
+ },
+ getPublicInstance(instance) {
+ return instance;
+ },
- scheduleDeferredCallback(a) {
- throw new Error('Unimplemented');
- },
+ createInstance(
+ type : string,
+ props : Props,
+ rootContainerInstance : Container,
+ hostContext : HostContext,
+ internalInstanceHandle : Object
+ ) {
+ const {children, ...appliedProps} = solveClass(props);
+ const instance = blessed[type](appliedProps);
+ instance.props = props;
+ instance._eventListener = (...args) => eventListener(instance, ...args);
+ instance.on('event', instance._eventListener);
- prepareForCommit() {
- // noop
- },
+ return instance;
+ },
- resetAfterCommit() {
- // noop
- },
+ appendInitialChild(
+ parentInstance : Instance,
+ child : Instance | TextInstance
+ ) : void {
+ parentInstance.append(child);
+ },
- mutation: {
- commitMount(
+ finalizeInitialChildren(
instance : Instance,
type : string,
- newProps : Props,
- internalInstanceHandle : Object
- ) {
- throw new Error('commitMount not implemented. Please post a reproducible use case that calls this method at https://github.com/Yomguithereal/react-blessed/issues/new');
- instance.screen.debouncedRender();
- // noop
+ props : Props,
+ rootContainerInstance : Container
+ ) : boolean {
+ const {children, ...appliedProps} = solveClass(props);
+ update(instance, appliedProps);
+ instance.props = props;
+ return false;
},
- commitUpdate(
+ prepareUpdate(
instance : Instance,
- updatePayload : Array,
type : string,
oldProps : Props,
newProps : Props,
- internalInstanceHandle : Object,
- ) : void {
- instance._updating = true;
- update(instance, updatePayload);
- // update event handler pointers
- instance.props = newProps;
- instance._updating = false;
- instance.screen.debouncedRender();
+ rootContainerInstance : Container,
+ hostContext : HostContext
+ ) : null | Array {
+ return solveClass(newProps);
},
- commitTextUpdate(
- textInstance : TextInstance,
- oldText : string,
- newText : string
- ) : void {
- textInstance.setContent(newText);
- textInstance.screen.debouncedRender();
+ shouldSetTextContent(props : Props) : boolean {
+ return false;
},
- appendChild(
- parentInstance : Instance | Container,
- child : Instance | TextInstance
- ) : void {
- parentInstance.append(child);
+ shouldDeprioritizeSubtree(type: string, props: Props): boolean {
+ return !!props.hidden;
},
- appendChildToContainer(
- parentInstance : Instance | Container,
- child : Instance | TextInstance
- ) : void {
- parentInstance.append(child);
- },
+ now: Date.now,
- insertBefore(
- parentInstance : Instance | Container,
- child : Instance | TextInstance,
- beforeChild : Instance | TextInstance
- ) : void {
- // pretty sure everything is absolutely positioned so insertBefore ~= append
- parentInstance.append(child);
+ createTextInstance(
+ text : string,
+ rootContainerInstance : Container,
+ hostContext : HostContext,
+ internalInstanceHandle : OpaqueHandle
+ ) : TextInstance {
+ return blessed.text({content: text});
},
- insertInContainerBefore(
- parentInstance : Instance | Container,
- child : Instance | TextInstance,
- beforeChild : Instance | TextInstance
- ) : void {
- // pretty sure everything is absolutely positioned so insertBefore ~= append
- parentInstance.append(child);
+ scheduleDeferredCallback(a) {
+ throw new Error('Unimplemented');
},
- removeChild(
- parentInstance : Instance | Container,
- child : Instance | TextInstance
- ) : void {
- parentInstance.remove(child);
- child.off('event', child._eventListener);
- child.destroy();
+ prepareForCommit() {
+ // noop
},
- removeChildFromContainer(
- parentInstance : Instance | Container,
- child : Instance | TextInstance
- ) : void {
- parentInstance.remove(child);
- child.off('event', child._eventListener);
- child.destroy();
+ resetAfterCommit() {
+ // noop
},
- resetTextContent(instance : Instance) : void {
- instance.setContent('');
+ mutation: {
+ commitMount(
+ instance : Instance,
+ type : string,
+ newProps : Props,
+ internalInstanceHandle : Object
+ ) {
+ throw new Error('commitMount not implemented. Please post a reproducible use case that calls this method at https://github.com/Yomguithereal/react-blessed/issues/new');
+ instance.screen.debouncedRender();
+ // noop
+ },
+
+ commitUpdate(
+ instance : Instance,
+ updatePayload : Array,
+ type : string,
+ oldProps : Props,
+ newProps : Props,
+ internalInstanceHandle : Object,
+ ) : void {
+ instance._updating = true;
+ update(instance, updatePayload);
+ // update event handler pointers
+ instance.props = newProps;
+ instance._updating = false;
+ instance.screen.debouncedRender();
+ },
+
+ commitTextUpdate(
+ textInstance : TextInstance,
+ oldText : string,
+ newText : string
+ ) : void {
+ textInstance.setContent(newText);
+ textInstance.screen.debouncedRender();
+ },
+
+ appendChild(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance
+ ) : void {
+ parentInstance.append(child);
+ },
+
+ appendChildToContainer(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance
+ ) : void {
+ parentInstance.append(child);
+ },
+
+ insertBefore(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance,
+ beforeChild : Instance | TextInstance
+ ) : void {
+ // pretty sure everything is absolutely positioned so insertBefore ~= append
+ parentInstance.append(child);
+ },
+
+ insertInContainerBefore(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance,
+ beforeChild : Instance | TextInstance
+ ) : void {
+ // pretty sure everything is absolutely positioned so insertBefore ~= append
+ parentInstance.append(child);
+ },
+
+ removeChild(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance
+ ) : void {
+ parentInstance.remove(child);
+ child.off('event', child._eventListener);
+ child.destroy();
+ },
+
+ removeChildFromContainer(
+ parentInstance : Instance | Container,
+ child : Instance | TextInstance
+ ) : void {
+ parentInstance.remove(child);
+ child.off('event', child._eventListener);
+ child.destroy();
+ },
+
+ resetTextContent(instance : Instance) : void {
+ instance.setContent('');
+ },
},
- },
- useSyncScheduling: true,
-});
+ useSyncScheduling: true,
+ });
-BlessedReconciler.injectIntoDevTools(injectIntoDevToolsConfig);
+ BlessedReconciler.injectIntoDevTools(injectIntoDevToolsConfig);
-module.exports = {
- render(element, screen, callback) {
+ const roots = new Map();
+
+ return function render(element, screen, callback) {
let root = roots.get(screen);
if (!root) {
root = BlessedReconciler.createContainer(screen);
@@ -229,6 +230,13 @@ module.exports = {
screen.debouncedRender();
return BlessedReconciler.getPublicRootInstance(root);
}
-};
+}
-const roots = new Map();
+module.exports = {
+ render: function render(element, screen, callback) {
+ const blessed = require('blessed');
+ const renderer = createBlessedRenderer(blessed);
+ return renderer(element, screen, callback);
+ },
+ createBlessedRenderer: createBlessedRenderer
+};
diff --git a/yarn.lock b/yarn.lock
index a372134..63df409 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1473,6 +1473,10 @@ nan@^2.3.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
+neo-blessed@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/neo-blessed/-/neo-blessed-0.2.0.tgz#30f9495fdd104494402b62c6273a9c9b82de4f2b"
+
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"