vadimdemedes / ink Goto Github PK
View Code? Open in Web Editor NEW๐ React for interactive command-line apps
Home Page: https://term.ink
License: MIT License
๐ React for interactive command-line apps
Home Page: https://term.ink
License: MIT License
Hi guys!
So I am getting this error, been busting my head over it all day, any thought?
Help, much appreciated ๐.
src/index.js
import {h, render, Component} from 'ink'
export default class extends Component {
render() {
return (
<div>a</div>
)
}
}
demo.js
import {h, render} from 'ink'
import Route from './src/index'
// Router
const Demo = () => {
return (
<Route/>
)
}
// Ink
render(<Demo/>)
.babelrc
{
"presets": ["es2015", "stage-2"],
"plugins": [
["transform-class-properties"],
["transform-react-jsx", {
"pragma": "h",
"useBuiltIns": true
}],
["transform-object-rest-spread",
{
"useBuiltIns": true
}]
]
}
package.json
{
"name": "ink-router",
"version": "1.0.0",
"description": "A router component for Ink.",
"license": "MIT",
"main": "dist/index.js",
"scripts": {
"pretest": "npm run build",
"test": "xo",
"start": "babel-node dist/index.js",
"demo": "babel-node demo.js",
"build": "babel src --out-dir=dist",
"prepublish": "npm run build"
},
"engines": {
"node": ">=6"
},
"files": [
"dist"
],
"keywords": [
"ink",
"ink-component"
],
"dependencies": {
"ink": "^0.3.0",
"prop-types": "^15.5.10"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-node6": "^11.0.0",
"babel-preset-stage-2": "^6.24.1",
"eslint-config-xo-react": "^0.13.0",
"eslint-plugin-react": "^7.2.0",
"eslint-plugin-xo": "^1.0.0",
"xo": "^0.18.2"
},
"xo": {
"extends": "xo-react",
"parser": "babel-eslint",
"esnext": true,
"space": true,
"semicolon": false,
"rules": {
"new-cap": 0,
"complexity": 0,
"default-case": 0,
"react/no-unused-prop-types": 1
},
"settings": {
"react": {
"pragma": "h"
}
}
}
}
I wrote a thing to handle exiting processes in ink
Is this something you'd consider putting on the readme?
Comparison to https://github.com/Yomguithereal/react-blessed would be nice.
Hi. Thanks for this amazing library.
Master branch (0.4.1) readme said it contains Bold and Color Component but currently npm published v0.4.1 doesn't contains those Components.
const { Text, Bold, Color } = require('ink');
console.log(Text, Bold, Color) // [Function: Text] undefined undefined
{
...
"dependencies": {
"ink": "^0.4.1"
}
....
}
Thanks!
I copy/pasted example code and tried to use jsx
npm module to run it, transpile it, I also tried to transpile it using Babel but that didn't work either.
How should I run it?
Hey, great work with this package.
I had been planning on writing some Flow type definitions, but I noticed that some exports aren't documented in the README. You already have an open issue for Indent
, but there's also StringComponent
, build
, and diff
. It would be great if these could be documented just to know whether I should include them in the type definitions or not.
Thanks again for ink
!
ink's engines
field specifies Node >= 4 while using features unsupported in Node < 6. This includes default & rest parameters and destructuring ( all things I hate to lose when supporting node 4 ๐ ).
I don't personally use anything but latest
but some might still use Node 4, so the options I'd bet you're aware of already are:
engines
field and drop support for node 4 ahead of its April '18 EOL.I realize ink is < 1.0 but this is a good thing to be aware of.
Hi. I used console.log for debug, but console.log breakdown the ink app.
class Welcome extends Component {
constructor (...args) {
super(...args);
this.state = {
welcome: false,
};
}
componentDidMount () {
setTimeout(() => {
this.setState({ welcome: true });
}, 1000)
}
render () {
console.log('hihi')
if (!this.state.welcome) {
return <Color blue>Intro</Color>
}
return (
<Color green>Main</Color>
)
}
}
without console.log, it works fine.
Maybe ink needs debugging space like ink-console
. (but ink-console doesn't work.)
Thanks.
must be documented here https://github.com/vadimdemedes/ink#built-in-components.
/node_modules/ink/index.js:61
Never seen this one before and googling didn't help much - what's going on here? It's preventing me from running this example from your docs:
`const {h, render, Component} = require('ink');
class Counter extends Component {
constructor() {
super();
this.state = {
i: 0
};
}
render(props, state) {
return `Iteration #${state.i}`;
}
componentDidMount() {
this.timer = setInterval(() => {
this.setState({
i: this.state.i + 1
});
}, 100);
}
componentWillUnmount() {
clearInterval(this.timer);
}
}
const unmount = render();
setTimeout(() => {
// Enough counting
unmount();
}, 1000);`
Since stdin
and stdout
are customizable, all components should have access to them via context to avoid confusion. This is also useful for testing and stubbing those streams.
Before:
componentDidMount() {
process.stdin.on('keypress', ...);
}
After:
componentDidMount() {
this.context.stdin.on('keypress', ...);
}
Maybe those should just be set directly on this
, not this.context
, haven't decided about this yet.
Hi, just wanted to stop by and leave a comment to tell you how awesome I think this package is. I've been messing around with it, and decided to try doing something with it with typescript and redux.
I've pushed ink-typescript-redux-test which is essentially the Counter example, but with more awesomeness.
custom_typings/ink
directory.typescript-fsa
for action creators and typescript-fsa-reducers
for the reducerIf you want to include the typings in your project, feel free.
Is there a specific reason you re-implement the whole react-like API instead of making it a custom renderer? I think about react-blessed here.
If there is no specific reason, how about making it a custom renderer?
When rendering the app to the terminal, there is an extra redundant new line at end of render which is not occupied by anything. I could be doing something wrong, I am not quite sure.
To reproduce:
yo ink-cli
node cli.js
Expected:
$ node cli.js
I love Ink
Actual: having an additional new line at the bottom of the terminal that is not being used
$ node cli.js
I love Ink
The official React 16.3 release is still upcoming, but there are several highly anticipated features whose implementation could start now: https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b
Particularly the new Context API, which could be built on top of the existing API for now.
Also important to implement will be static getDerivedStateFromProps
, which replaces ย componentDidMount
componentWillReceiveProps
(and is allegedly necessary for async rendering).
hi @vadimdemedes
looks your mac terminal theme it's very nice in the readme.md .
would you tell me what's your theme ?
thanks :)
In the yeoman generator, importJsx
is used to require the ui.js
file.
From the ui.js
file, is that needed to import and use locally defined components? (ones not from an npm package)
With the replacement from <Text/>
to <Color/>
, many preexisting components for Ink have lost support, and now provide an obtuse and non-descriptive error message for the deprecated tag:
TypeError: Expected component to be a function, but received undefined. You may have forgotten to export a component.
Unfortunately there didn't seem to be much info out there regarding the breaking change (no changelog for 0.5.0, no major symver change), it's hard for existing users to figure out what went wrong.
I would suggest creating a Text
component and providing a descriptive error in console with the suggested course of action (replacing it with Color
.)
Right now no arguments are passed, but previous props and state should be passed to match React API.
Like rgb()
or hex()
.
Code here.
fileList() {
const { results } = this.state;
return results.map(r => {
const props = (r.res && r.res.status === 200) ? { green: true } : { red: true };
return h(
'div',
{},
h(
Color,
props,
r.url,
)
);
})
}
Screenshot
Color can work when code below, but new line each file is needed:
h(
Color,
props,
r.url,
)
We need when the file uploaded success, show file url with green, otherwise red.
There are 2 Yeoman generators to easily get started with Ink:
Having them in the readme would ease the intro to Ink.
I'm looking to build some full screen layouts, that contain multiple section, much in the same way that react-blessed makes possible with boxes. I note the following #5 that seems promising but I wondered how/if people are doing this with the current feature set?
Great project, loving working with ink.
Loving the concept of Ink but having some issues with the rendering. I'm seeing this duplicated output:
Have you seen this before? Any idea what the issue could be? I'm not sure this is a bug, but I can't seem to nail down the cause. While I'm typing the answers to the questions, it works fine. It only starts to break when it renders the other parts of the UI.
Thanks for your help and happy holidays!
Currently the list is short:
If you are aware of any high quality CLIs built with Ink, please comment in this thread and I'll add it later to the readme! Also, if some CLI gets rejected, no hard feelings please :)
I am curious if there is a way to avoid a transpiler since I like to rely on node's native support for new syntax.
I'm working on a package and I need to render a component temporarily (like renderToString does) but I need the lifecycle events to occur and emit the updates to a stream. However, I don't need the stdin hooks for escape, Ctrl+c etc. Plus, when I call unmount, I don't want the program to exit.
Right now, as a workaround, I call render(<Component />, {stdout, stdin})
with my stdout being the stream I implement, and stdin
being a Noop version of a Readable stream made to look like stdin. To unmount, I have to import call-tree
directly and manually unmount, since calling the returned method of render
ends my process.
I think implementing a method renderToStream
that does the basic functionality without being bound to stdin/stdout is fairly easy, and then render could use that, and add the stdin interactions.
If that sounds like a good idea, I can write a PR.
If there is an easier way to do this that I'm not seeing, let me know.
Also, I think it would make sense to be passing the updated component by itself (without the eraseLine characters that the log-update
uses to clear the terminal)
See #3 (comment).
The problem is demonstrated perfectly when rendering a progress bar:
<div>
<Label/>
<ProgressBar/>
</div>
In order to render a progress bar that takes entire terminal space (width), <ProgressBar>
needs to know how much space <Label>
takes.
I'm short of ideas on how to implement this properly, so any thoughts are welcome!
thank you for this
So we can get rid of the annoying <div>
wrapping requirement.
Thanks for creating this library! I've been trying it out a bit and while using version 0.5.0 I kept encountering this error when using the Spinner, Table, and Select components:
throw new TypeError(`Expected component to be a function, but received ${typeof component}. You may have forgotten to export a component.`);
Downgrading to 0.4.1 enabled each to work, though.
Hi. I'm making ink component using context which is used in ink-redux.
when I use getChildContext
method, render
contains context but constructor
does not.
class Sub extends Component {
constructor (props, context) {
super(props, context);
console.log(context); // {}
}
render (props, state, context) {
console.log(context); // { hi: 'hello' }
return (
<Text blue>Hi</Text>
)
}
}
class Parent extends Component {
getChildContext () {
return {
hi: 'hello'
}
}
render () {
console.log(this.context); // { hi: 'hello'}
return (
<Sub />
);
}
}
thanks!
It makes it sound like it can only color text, but it works on any Ink component, so you could use it to color ink-box
, for example.
We can add separate components for the existing <Text bold>
and <Text underline>
styling: <Bold>
and <Underline>
.
Ran into the following issue, while playing with Ink.
Take the following NodeJS app which prints a green text to stderr and dies
#!/usr/bin/env node
const {h, render, Text} = require('ink');
render(h(Text, {green: true}, "././././."), process.stderr);
Run it as
./index.js # Shows as expected
And all looks as expected. However, if I run as below, all colors are gone.
$(./index.js) # Expecting to see colors, but actually all colors are gone
Note that this is not the default behavior for console. The below works in both cases (from above).
#!/usr/bin/env node
console.error('\x1b[36m%s\x1b[0m', 'I am cyan');
NB. To make the example smaller and not hijack your console, I am printing to stderr, but same applies for stdout.
Thank you!
Many people have questions why does Ink exists, why not use blessed/react-blessed, etc. I need to clarify it in the beginning of readme.
This means that when a nested component needs to rerender, diff only checks the dirty component and its children (basically the whole tree below). In React/Preact, a dirty component means a component that was updated (via setState()
) and needs to be rerendered.
like title. Thanks. : )
This example:
const {h, render, Component, Text} = require('ink')
class Counter extends Component {
constructor() {
super();
this.state = {
i: 0
};
}
render() {
return (
<Text green>
{this.state.i} iterations passed
</Text>
);
}
componentDidMount() {
this.timer = setInterval(() => {
this.setState({
i: this.state.i + 1
});
}, 100);
}
componentWillUnmount() {
clearInterval(this.timer);
}
}
const Demo = () => <div>Petri</div>
//const App = Demo
const App = Counter
const unmount = render(<App/>)
setTimeout(() => {
unmount()
}, 3000)
works with .babelrc
{
"plugins": [
[
"transform-react-jsx",
{ "pragma": "h" }
]
]
}
I would like to use import-syntax instead:
import { h, render, Component, Text } from 'ink'
If I edit .babelrc
to:
{
"presets": ["env"],
"plugins": [
[
"transform-react-jsx",
{ "pragma": "h" }
]
]
}
I get:
.../ink/main.js:81
var _this = _possibleConstructorReturn(this, (Counter.__proto__ || Object.getPrototypeOf(Counter)).call(this));
^
TypeError: Class constructor Component cannot be invoked without 'new'
at new Counter (/Users/petri/src/programming-survey-dsl/ink/main.js:68:16)
at Instance.mount (/Users/petri/src/programming-survey-dsl/ink/node_modules/ink/lib/instance.js:86:21)
at diff (/Users/petri/src/programming-survey-dsl/ink/node_modules/ink/lib/diff.js:40:16)
at build (/Users/petri/src/programming-survey-dsl/ink/node_modules/ink/index.js:27:25)
at update (/Users/petri/src/programming-survey-dsl/ink/node_modules/ink/index.js:64:20)
at exports.render (/Users/petri/src/programming-survey-dsl/ink/node_modules/ink/index.js:80:2)
at Object.<anonymous> (/Users/petri/src/programming-survey-dsl/ink/main.js:101:17)
at Module._compile (module.js:624:30)
at loader (/Users/petri/src/programming-survey-dsl/ink/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/petri/src/programming-survey-dsl/ink/node_modules/babel-register/lib/node.js:154:7)
I'm running on:
$ node -v
v8.5.0
Run the below code
import { h, Text, render, Component, span } from "ink"
class Test1 extends Component {
state = {
text: ""
}
componentDidMount() {
let number = 0
setInterval(() => {
let text = this.state.text;
number++;
text += number + "-"
this.setState({
text
})
}, 100)
}
render() {
return (<Text>{this.state.text}</Text>)
}
}
render(<Test1 />)
When the length of this.state.text
great then the columns of terminal, the output seams not correct, is it ?
The same situation appears on TextInput
, when the input text more then one line, it was repeated again and again when I typed.
class Test extends Component {
state = {
value: ""
}
render() {
return (<TextInput value={this.state.value} onChange={(v) => this.setState({ value: v })} />)
}
}
Really awesome project. Thanks for building it.
I want to make a normal readline-style prompt, complete with the standard cursor. I see ink-text-input but it doesn't render the cursor. Can you point me in the right direction?
Cheers.
https://github.com/vadimdemedes/ink/blob/master/lib/diff.js#L133
let isUpdate = true;
// you make the update call isUpdate is ok
https://github.com/vadimdemedes/ink/blob/master/lib/diff.js#L178
return isUpdate ? prevNode : nextNode;
// but isUpdate == true ? prev
If the Vnode
is need to Update
, should return nextNode
, no prevNode
May you can change isUpdate
to > isPrev
For example, a component like this currently renders all of the items on a single line. Like HTML makes the div have a block-level display (implicitly has a 100% width), perhaps ink's could do something similar?
const Things = ({ things }) => (
<div>
{things.map(item => (
<div>
<Indent size={2} indent={' '}>{item.text}</Indent>
</div>
))}
</div>
);
I noticed the example in the readme requires a Text
property from the ink exports. After reading through the index.js I noticed that there is no such export.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.