ink
Advanced tools
Comparing version 2.0.3 to 2.0.4
@@ -8,2 +8,4 @@ "use strict"; | ||
var _readline = _interopRequireDefault(require("readline")); | ||
var _react = _interopRequireWildcard(require("react")); | ||
@@ -21,6 +23,6 @@ | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
@@ -32,4 +34,5 @@ | ||
class App extends _react.PureComponent { | ||
constructor(...args) { | ||
super(...args); | ||
constructor() { | ||
super(); // Count how many components enabled raw mode to avoid disabling | ||
// raw mode until all components don't need it anymore | ||
@@ -41,8 +44,20 @@ _defineProperty(this, "handleSetRawMode", isEnabled => { | ||
stdin.setEncoding('utf8'); | ||
stdin.setRawMode(isEnabled); | ||
if (isEnabled) { | ||
stdin.addListener('data', this.handleInput); | ||
stdin.resume(); | ||
} else { | ||
// Ensure raw mode is enabled only once | ||
if (this.rawModeEnabledCount === 0) { | ||
stdin.addListener('data', this.handleInput); | ||
stdin.resume(); | ||
stdin.setRawMode(true); | ||
_readline.default.emitKeypressEvents(stdin); | ||
} | ||
this.rawModeEnabledCount++; | ||
return; | ||
} // Disable raw mode only when no components left that are using it | ||
if (--this.rawModeEnabledCount === 0) { | ||
stdin.setRawMode(false); | ||
stdin.removeListener('data', this.handleInput); | ||
@@ -65,2 +80,4 @@ stdin.pause(); | ||
}); | ||
this.rawModeEnabledCount = 0; | ||
} | ||
@@ -67,0 +84,0 @@ |
247
package.json
{ | ||
"name": "ink", | ||
"version": "2.0.3", | ||
"description": "React for CLI", | ||
"license": "MIT", | ||
"repository": "vadimdemedes/ink", | ||
"author": { | ||
"name": "vdemedes", | ||
"email": "vdemedes@gmail.com", | ||
"url": "github.com/vadimdemedes" | ||
}, | ||
"engines": { | ||
"node": ">=8" | ||
}, | ||
"scripts": { | ||
"build": "babel src --out-dir build", | ||
"prepare": "npm run build", | ||
"test": "xo && FORCE_COLOR=true ava", | ||
"pretest": "npm run build", | ||
"cast": "svg-term --command 'node media/demo.js' --out media/demo.svg --from=100 --window --width=50 --height=8 --term=iterm2 --profile=Snazzy" | ||
}, | ||
"main": "build", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"build", | ||
"index.d.ts" | ||
], | ||
"keywords": [ | ||
"react", | ||
"cli", | ||
"jsx", | ||
"stdout", | ||
"components", | ||
"command-line", | ||
"preact", | ||
"redux", | ||
"print", | ||
"render", | ||
"colors", | ||
"text" | ||
], | ||
"dependencies": { | ||
"@types/react": "^16.8.6", | ||
"arrify": "^1.0.1", | ||
"auto-bind": "^2.0.0", | ||
"chalk": "^2.4.1", | ||
"cli-cursor": "^2.1.0", | ||
"lodash.throttle": "^4.1.1", | ||
"log-update": "^3.0.0", | ||
"prop-types": "^15.6.2", | ||
"react-reconciler": "^0.20.0", | ||
"scheduler": "^0.13.2", | ||
"slice-ansi": "^1.0.0", | ||
"string-length": "^2.0.0", | ||
"widest-line": "^2.0.0", | ||
"yoga-layout-prebuilt": "^1.9.3" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.1.2", | ||
"@babel/core": "^7.1.2", | ||
"@babel/plugin-proposal-class-properties": "^7.1.0", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0", | ||
"@babel/preset-react": "^7.0.0", | ||
"ava": "1.0.0-beta.8", | ||
"babel-eslint": "^10.0.1", | ||
"delay": "^4.1.0", | ||
"eslint-config-xo-react": "^0.17.0", | ||
"eslint-plugin-react": "^7.11.1", | ||
"import-jsx": "^1.3.0", | ||
"ms": "^2.1.1", | ||
"node-pty": "^0.8.1", | ||
"p-queue": "^3.0.0", | ||
"react": "^16.6.1", | ||
"sinon": "^7.2.7", | ||
"strip-ansi": "^4.0.0", | ||
"svg-term-cli": "^2.1.1", | ||
"xo": "^0.24.0" | ||
}, | ||
"babel": { | ||
"plugins": [ | ||
"@babel/plugin-proposal-class-properties", | ||
"@babel/plugin-proposal-object-rest-spread", | ||
"@babel/plugin-transform-modules-commonjs" | ||
], | ||
"presets": [ | ||
"@babel/preset-react" | ||
] | ||
}, | ||
"ava": { | ||
"babel": { | ||
"testOptions": { | ||
"plugins": [ | ||
"@babel/plugin-proposal-class-properties", | ||
"@babel/plugin-proposal-object-rest-spread", | ||
"@babel/plugin-transform-modules-commonjs" | ||
], | ||
"presets": [ | ||
"@babel/preset-react" | ||
] | ||
} | ||
} | ||
}, | ||
"xo": { | ||
"parser": "babel-eslint", | ||
"extends": [ | ||
"xo-react" | ||
], | ||
"plugins": [ | ||
"react" | ||
], | ||
"overrides": [ | ||
{ | ||
"files": "src/components/*.js", | ||
"rules": { | ||
"unicorn/filename-case": 0, | ||
"react/require-default-props": 1 | ||
} | ||
}, | ||
{ | ||
"files": "test/*.js", | ||
"rules": { | ||
"import/default": 0 | ||
} | ||
} | ||
] | ||
} | ||
"name": "ink", | ||
"version": "2.0.4", | ||
"description": "React for CLI", | ||
"license": "MIT", | ||
"repository": "vadimdemedes/ink", | ||
"author": { | ||
"name": "vdemedes", | ||
"email": "vdemedes@gmail.com", | ||
"url": "github.com/vadimdemedes" | ||
}, | ||
"main": "build", | ||
"engines": { | ||
"node": ">=8" | ||
}, | ||
"scripts": { | ||
"build": "babel src --out-dir=build", | ||
"prepare": "npm run build", | ||
"test": "xo && FORCE_COLOR=true ava", | ||
"pretest": "npm run build", | ||
"cast": "svg-term --command='node media/demo.js' --out=media/demo.svg --from=100 --window --width=50 --height=8 --term=iterm2 --profile=Snazzy" | ||
}, | ||
"types": "index.d.ts", | ||
"files": [ | ||
"build", | ||
"index.d.ts" | ||
], | ||
"keywords": [ | ||
"react", | ||
"cli", | ||
"jsx", | ||
"stdout", | ||
"components", | ||
"command-line", | ||
"preact", | ||
"redux", | ||
"print", | ||
"render", | ||
"colors", | ||
"text" | ||
], | ||
"dependencies": { | ||
"@types/react": "^16.8.6", | ||
"arrify": "^1.0.1", | ||
"auto-bind": "^2.0.0", | ||
"chalk": "^2.4.1", | ||
"cli-cursor": "^2.1.0", | ||
"lodash.throttle": "^4.1.1", | ||
"log-update": "^3.0.0", | ||
"prop-types": "^15.6.2", | ||
"react-reconciler": "^0.20.0", | ||
"scheduler": "^0.13.2", | ||
"slice-ansi": "^1.0.0", | ||
"string-length": "^2.0.0", | ||
"widest-line": "^2.0.0", | ||
"yoga-layout-prebuilt": "^1.9.3" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.1.2", | ||
"@babel/core": "^7.1.2", | ||
"@babel/plugin-proposal-class-properties": "^7.1.0", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0", | ||
"@babel/preset-react": "^7.0.0", | ||
"ava": "^1.3.1", | ||
"babel-eslint": "^10.0.1", | ||
"delay": "^4.1.0", | ||
"eslint-config-xo-react": "^0.19.0", | ||
"eslint-plugin-react": "^7.11.1", | ||
"eslint-plugin-react-hooks": "^1.4.0", | ||
"import-jsx": "^1.3.0", | ||
"ms": "^2.1.1", | ||
"node-pty": "^0.8.1", | ||
"p-queue": "^3.0.0", | ||
"react": "^16.6.1", | ||
"sinon": "^7.2.7", | ||
"svg-term-cli": "^2.1.1", | ||
"xo": "^0.24.0" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8.0" | ||
}, | ||
"babel": { | ||
"plugins": [ | ||
"@babel/plugin-proposal-class-properties", | ||
"@babel/plugin-proposal-object-rest-spread", | ||
"@babel/plugin-transform-modules-commonjs" | ||
], | ||
"presets": [ | ||
"@babel/preset-react" | ||
] | ||
}, | ||
"ava": { | ||
"babel": { | ||
"testOptions": { | ||
"plugins": [ | ||
"@babel/plugin-proposal-class-properties", | ||
"@babel/plugin-proposal-object-rest-spread", | ||
"@babel/plugin-transform-modules-commonjs" | ||
], | ||
"presets": [ | ||
"@babel/preset-react" | ||
] | ||
} | ||
} | ||
}, | ||
"xo": { | ||
"parser": "babel-eslint", | ||
"extends": [ | ||
"xo-react" | ||
], | ||
"plugins": [ | ||
"react" | ||
], | ||
"overrides": [ | ||
{ | ||
"files": "src/components/*.js", | ||
"rules": { | ||
"unicorn/filename-case": "off", | ||
"react/require-default-props": "warning" | ||
} | ||
} | ||
] | ||
} | ||
} |
@@ -18,3 +18,3 @@ <h1 align="center"> | ||
``` | ||
$ npm install ink | ||
$ npm install ink react | ||
``` | ||
@@ -76,3 +76,3 @@ | ||
## Table of Contents | ||
## Contents | ||
@@ -85,2 +85,3 @@ - [Getting Started](#getting-started) | ||
- [Useful Components](#useful-components) | ||
- [Testing](#testing) | ||
@@ -131,3 +132,3 @@ | ||
Since Ink is a React renderer, it means that all features of React are supported. | ||
Head over to [React](https://reactjs.org/) website for documentation on how to use it. | ||
Head over to [React](https://reactjs.org) website for documentation on how to use it. | ||
In this readme only Ink's methods will be documented. | ||
@@ -147,5 +148,7 @@ | ||
Type: `Object` | ||
###### stdout | ||
Type: `Stream`<br> | ||
Type: `stream.Writable`<br> | ||
Default: `process.stdout` | ||
@@ -157,3 +160,3 @@ | ||
Type: `Stream`<br> | ||
Type: `stream.Readable`<br> | ||
Default: `process.stdin` | ||
@@ -165,3 +168,3 @@ | ||
Type: `Boolean`<br> | ||
Type: `boolean`<br> | ||
Default: `true` | ||
@@ -174,3 +177,3 @@ | ||
Type: `Boolean`<br> | ||
Type: `boolean`<br> | ||
Default: `false` | ||
@@ -277,3 +280,3 @@ | ||
#### <Box> | ||
#### `<Box>` | ||
@@ -523,3 +526,3 @@ `<Box>` it's an essential Ink component to build your layout. It's like a `<div style="display: flex">` in a browser. | ||
#### <Color> | ||
#### `<Color>` | ||
@@ -551,3 +554,3 @@ The `<Color>` compoment is a simple wrapper around [the `chalk` API](https://github.com/chalk/chalk#api). | ||
#### <Text> | ||
#### `<Text>` | ||
@@ -591,3 +594,3 @@ This component can change the style of the text, make it bold, underline, italic or strikethrough. | ||
#### <Static> | ||
#### `<Static>` | ||
@@ -608,3 +611,3 @@ `<Static>` component allows permanently rendering output to stdout and preserving it across renders. | ||
```jsx | ||
<Fragment> | ||
<> | ||
<Static> | ||
@@ -619,3 +622,3 @@ {tests.map(test => ( | ||
</Box> | ||
</Fragment> | ||
</> | ||
``` | ||
@@ -625,5 +628,5 @@ | ||
#### <AppContext> | ||
#### `<AppContext>` | ||
`<StdinContext>` is a [React context](https://reactjs.org/docs/context.html#reactcreatecontext), which exposes a method to manually exit the app (unmount). | ||
`<AppContext>` is a [React context](https://reactjs.org/docs/context.html#reactcreatecontext), which exposes a method to manually exit the app (unmount). | ||
@@ -653,3 +656,3 @@ Import: | ||
#### <StdinContext> | ||
#### `<StdinContext>` | ||
@@ -666,3 +669,3 @@ `<StdinContext>` is a [React context](https://reactjs.org/docs/context.html#reactcreatecontext), which exposes input stream. | ||
Type: `Stream`<br> | ||
Type: `stream.Readable`<br> | ||
Default: `process.stdin` | ||
@@ -687,4 +690,4 @@ | ||
See [setRawMode](https://nodejs.org/api/tty.html#tty_readstream_setrawmode_mode). | ||
Ink exposes this function via own `<StdinContext>` to be able to handle <kbd>Ctrl</kbd>+<kbd>C</kbd>, that's why you should use Ink's `setRawMode` instead of `process.stdin.setRawMode`. | ||
See [`setRawMode`](https://nodejs.org/api/tty.html#tty_readstream_setrawmode_mode). | ||
Ink exposes this function via own `<StdinContext>` to be able to handle <kbd>Ctrl</kbd>+<kbd>C</kbd>, that's why you should use Ink's `setRawMode` instead of `process.stdin.setRawMode`. Ink also enables `keypress` events via [`readline.emitKeypressEvents()`](https://nodejs.org/api/readline.html#readline_readline_emitkeypressevents_stream_interface) when raw mode is enabled. | ||
@@ -701,3 +704,3 @@ Usage: | ||
#### <StdoutContext> | ||
#### `<StdoutContext>` | ||
@@ -714,3 +717,3 @@ `<StdoutContext>` is a [React context](https://reactjs.org/docs/context.html#reactcreatecontext), which exposes stdout stream, where Ink renders your app. | ||
Type: `Stream`<br> | ||
Type: `stream.Writable`<br> | ||
Default: `process.stdout` | ||
@@ -735,3 +738,3 @@ | ||
- [ink-link](https://github.com/sindresorhus/ink-link) - Link component. | ||
- [ink-box](https://github.com/sindresorhus/ink-box) - Box component. | ||
- [ink-box](https://github.com/sindresorhus/ink-box) - Styled box component. | ||
- [ink-gradient](https://github.com/sindresorhus/ink-gradient) - Gradient color component. | ||
@@ -755,3 +758,2 @@ - [ink-big-text](https://github.com/sindresorhus/ink-big-text) - Awesome text component. | ||
- [ink-router](https://github.com/jimmed/ink-router) - Implementation of react-router for Ink. | ||
- [ink-tab](https://github.com/jdeniau/ink-tab) - Tab component. | ||
- [ink-select](https://github.com/karaggeorge/ink-select) - Select component. | ||
@@ -764,4 +766,29 @@ - [ink-scrollbar](https://github.com/karaggeorge/ink-scrollbar) - Scrollbar component. | ||
## Testing | ||
Ink components are simple to test with [ink-testing-library](https://github.com/vadimdemedes/ink-testing-library). | ||
Here's a simple example that checks how component is rendered: | ||
```jsx | ||
import React from 'react'; | ||
import {Text} from 'ink'; | ||
import {render} from 'ink-testing-library'; | ||
const Test = () => <Text>Hello World</Text>; | ||
const {lastFrame} = render(<Test/>); | ||
lastFrame() === 'Hello World'; //=> true | ||
``` | ||
Visit [ink-testing-library](https://github.com/vadimdemedes/ink-testing-library) for more examples and full documentation. | ||
## Maintainers | ||
- [Vadim Demedes](https://github.com/vadimdemedes) | ||
- [Sindre Sorhus](https://github.com/sindresorhus) | ||
## License | ||
MIT © [Vadim Demedes](https://github.com/vadimdemedes) | ||
MIT |
71115
1286
772
15