Socket
Socket
Sign inDemoInstall

ink

Package Overview
Dependencies
44
Maintainers
2
Versions
76
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.3.0 to 2.4.0

build/experimental/apply-style.js

8

build/calculate-wrapped-text.js

@@ -8,8 +8,12 @@ "use strict";

var _measureText = _interopRequireDefault(require("./measure-text"));
var _wrapText = _interopRequireDefault(require("./wrap-text"));
var _measureText = _interopRequireDefault(require("./measure-text"));
var _getMaxWidth = _interopRequireDefault(require("./get-max-width"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Since we need to know the width of text container to wrap text, we have to calculate layout twice
// This function is executed after first layout calculation to reassign width and height of text nodes
const calculateWrappedText = node => {

@@ -21,3 +25,3 @@ if (node.textContent && typeof node.parentNode.style.textWrap === 'string') {

const parentYogaNode = node.parentNode.yogaNode;
const maxWidth = parentYogaNode.getComputedWidth() - parentYogaNode.getComputedPadding() * 2;
const maxWidth = (0, _getMaxWidth.default)(parentYogaNode);
const currentWidth = yogaNode.getComputedWidth();

@@ -24,0 +28,0 @@

@@ -8,4 +8,2 @@ "use strict";

var _readline = _interopRequireDefault(require("readline"));
var _react = _interopRequireWildcard(require("react"));

@@ -23,6 +21,8 @@

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 _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } 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; }

@@ -64,4 +64,2 @@

stdin.setRawMode(true);
_readline.default.emitKeypressEvents(stdin);
}

@@ -68,0 +66,0 @@

@@ -14,4 +14,6 @@ "use strict";

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 _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

@@ -75,3 +77,3 @@

flexBasis: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
alignItems: _propTypes.default.oneOf(['flex-start', 'center', 'flex-end']),
alignItems: _propTypes.default.oneOf(['stretch', 'flex-start', 'center', 'flex-end']),
justifyContent: _propTypes.default.oneOf(['flex-start', 'center', 'flex-end', 'space-between', 'space-around']),

@@ -78,0 +80,0 @@ textWrap: _propTypes.default.oneOf(['wrap', 'truncate', 'truncate-start', 'truncate-middle', 'truncate-end']),

@@ -30,2 +30,6 @@ "use strict";

if (children === '') {
return null;
}
const transformChildren = children => {

@@ -53,5 +57,8 @@ Object.keys(colorProps).forEach(method => {

Color.propTypes = {
children: _propTypes.default.node.isRequired
children: _propTypes.default.node
};
Color.defaultProps = {
children: ''
};
var _default = Color;
exports.default = _default;

@@ -14,4 +14,10 @@ "use strict";

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 _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

@@ -25,3 +31,3 @@

// The reason it's called <Static> is it's append-only output. Output from <Static> components
// is written permantently to stdout and is never updated afterwards. If <Static> component
// is written permanently to stdout and is never updated afterwards. If <Static> component
// receives new children, Ink will detect the changes and write them to stdout.

@@ -63,3 +69,6 @@ // In order for this mechanism to work perfectly, <Static> children must never update their output

unstable__static: true,
style: otherProps
style: _objectSpread({
position: 'absolute',
flexDirection: 'column'
}, otherProps)
}, newChildren);

@@ -66,0 +75,0 @@ }

@@ -54,2 +54,8 @@ "use strict";

});
Object.defineProperty(exports, "useInput", {
enumerable: true,
get: function () {
return _useInput.default;
}
});

@@ -72,2 +78,4 @@ var _render = _interopRequireDefault(require("./render"));

var _useInput = _interopRequireDefault(require("./hooks/use-input"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -22,6 +22,12 @@ "use strict";

var _reconciler2 = _interopRequireDefault(require("./experimental/reconciler"));
var _renderer = _interopRequireDefault(require("./renderer"));
var _dom = require("./dom");
var _renderer2 = _interopRequireDefault(require("./experimental/renderer"));
var dom = _interopRequireWildcard(require("./dom"));
var experimentalDom = _interopRequireWildcard(require("./experimental/dom"));
var _instances = _interopRequireDefault(require("./instances"));

@@ -31,2 +37,6 @@

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -38,7 +48,21 @@

this.options = options;
this.rootNode = (0, _dom.createNode)('root');
this.rootNode.onRender = this.onRender;
this.renderer = (0, _renderer.default)({
terminalWidth: options.stdout.columns
});
if (options.experimental) {
this.rootNode = experimentalDom.createNode('root');
this.rootNode.onRender = options.debug ? this.onRender : (0, _lodash.default)(this.onRender, 16, {
leading: true,
trailing: true
});
this.rootNode.onImmediateRender = this.onRender;
this.renderer = (0, _renderer2.default)({
terminalWidth: options.stdout.columns
});
} else {
this.rootNode = dom.createNode('root');
this.rootNode.onRender = this.onRender;
this.renderer = (0, _renderer.default)({
terminalWidth: options.stdout.columns
});
}
this.log = _logUpdate.default.create(options.stdout);

@@ -56,3 +80,9 @@ this.throttledLog = options.debug ? this.log : (0, _lodash.default)(this.log, {

this.fullStaticOutput = '';
this.container = _reconciler.default.createContainer(this.rootNode, false, false);
if (options.experimental) {
this.container = _reconciler2.default.createContainer(this.rootNode, false, false);
} else {
this.container = _reconciler.default.createContainer(this.rootNode, false, false);
}
this.exitPromise = new Promise((resolve, reject) => {

@@ -98,3 +128,7 @@ this.resolveExitPromise = resolve;

if (!_isCi.default) {
this.log(output);
if (this.options.experimental) {
this.throttledLog(output);
} else {
this.log(output);
}
}

@@ -105,3 +139,3 @@ }

if (!_isCi.default) {
this.throttledLog(output);
this.log(output);
}

@@ -121,3 +155,7 @@

_reconciler.default.updateContainer(tree, this.container);
if (this.options.experimental) {
_reconciler2.default.updateContainer(tree, this.container);
} else {
_reconciler.default.updateContainer(tree, this.container);
}
}

@@ -142,3 +180,7 @@

_reconciler.default.updateContainer(null, this.container);
if (this.options.experimental) {
_reconciler2.default.updateContainer(null, this.container);
} else {
_reconciler.default.updateContainer(null, this.container);
}

@@ -145,0 +187,0 @@ _instances.default.delete(this.options.stdout);

@@ -14,4 +14,6 @@ "use strict";

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
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; }

@@ -18,0 +20,0 @@

@@ -18,47 +18,7 @@ "use strict";

var _measureText = _interopRequireDefault(require("./measure-text"));
var _calculateWrappedText = _interopRequireDefault(require("./calculate-wrapped-text"));
var _wrapText = _interopRequireDefault(require("./wrap-text"));
var _getMaxWidth = _interopRequireDefault(require("./get-max-width"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Since we need to know the width of text container to wrap text, we have to calculate layout twice
// This function is executed after first layout calculation to reassign width and height of text nodes
const calculateWrappedText = node => {
if (node.textContent && typeof node.parentNode.style.textWrap === 'string') {
const {
yogaNode
} = node;
const parentYogaNode = node.parentNode.yogaNode;
const maxWidth = (0, _getMaxWidth.default)(parentYogaNode);
const currentWidth = yogaNode.getComputedWidth();
if (currentWidth > maxWidth) {
const {
textWrap
} = node.parentNode.style;
const wrappedText = (0, _wrapText.default)(node.textContent, maxWidth, {
textWrap
});
const {
width,
height
} = (0, _measureText.default)(wrappedText);
yogaNode.setWidth(width);
yogaNode.setHeight(height);
}
return;
}
if (Array.isArray(node.childNodes) && node.childNodes.length > 0) {
for (const childNode of node.childNodes) {
calculateWrappedText(childNode);
}
}
}; // Since <Static> components can be placed anywhere in the tree, this helper finds and returns them
// Since <Static> components can be placed anywhere in the tree, this helper finds and returns them
const getStaticNodes = element => {

@@ -120,3 +80,3 @@ const staticNodes = [];

staticYogaNode.calculateLayout(_yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.DIRECTION_LTR);
calculateWrappedText(rootNode);
(0, _calculateWrappedText.default)(rootNode);
staticYogaNode.calculateLayout(_yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.DIRECTION_LTR); // Save current Yoga node tree to free up memory later

@@ -142,3 +102,3 @@

yogaNode.calculateLayout(_yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.DIRECTION_LTR);
calculateWrappedText(node);
(0, _calculateWrappedText.default)(node);
yogaNode.calculateLayout(_yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.UNDEFINED, _yogaLayoutPrebuilt.default.DIRECTION_LTR); // Save current node tree to free up memory later

@@ -145,0 +105,0 @@

@@ -1,2 +0,2 @@

import * as React from "react";
import * as React from 'react';

@@ -28,2 +28,9 @@ export interface RenderOptions {

readonly debug?: boolean;
/**
* Enable experimental mode and use a new and faster reconciler and renderer.
* There should be no changes to the output. If there are, please report it.
*
* @default false
*/
readonly experimental?: boolean;
}

@@ -49,2 +56,42 @@

/**
* This hook is used for handling user input.
* It's a more convienient alternative to using `StdinContext` and listening to `data` events.
* The callback you pass to `useInput` is called for each character when user enters any input.
* However, if user pastes text and it's more than one character, the callback will be called only once and the whole string will be passed as `input`.
*
* ```
* import {useInput} from 'ink';
*
* const UserInput = () => {
* useInput((input, key) => {
* if (input === 'q') {
* // Exit program
* }
*
* if (key.leftArrow) {
* // Left arrow key pressed
* }
* });
*
* return …
* };
* ```
*/
export function useInput(
inputHandler: (input: string, key: Key) => void
): void;
export interface Key {
upArrow: boolean
downArrow: boolean
leftArrow: boolean
rightArrow: boolean
return: boolean
escape: boolean
ctrl: boolean
shift: boolean
meta: boolean
}
/**
* Mount a component and render the output.

@@ -145,17 +192,17 @@ */

readonly flexShrink?: number;
readonly flexDirection?: "row" | "row-reverse" | "column" | "column-reverse";
readonly flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
readonly flexBasis?: string | number;
readonly alignItems?: "flex-start" | "center" | "flex-end";
readonly alignItems?: 'flex-start' | 'center' | 'flex-end';
readonly justifyContent?:
| "flex-start"
| "center"
| "flex-end"
| "space-between"
| "space-around";
| 'flex-start'
| 'center'
| 'flex-end'
| 'space-between'
| 'space-around';
readonly textWrap?:
| "wrap"
| "truncate"
| "truncate-start"
| "truncate-middle"
| "truncate-end";
| 'wrap'
| 'truncate'
| 'truncate-start'
| 'truncate-middle'
| 'truncate-end';
}

@@ -215,3 +262,3 @@

*/
readonly setRawMode: NodeJS.ReadStream["setRawMode"];
readonly setRawMode: NodeJS.ReadStream['setRawMode'];
}>;

@@ -218,0 +265,0 @@

{
"name": "ink",
"version": "2.3.0",
"version": "2.4.0",
"description": "React for CLI",

@@ -19,3 +19,3 @@ "license": "MIT",

"prepare": "npm run build",
"test": "xo && FORCE_COLOR=true ava",
"test": "xo && FORCE_COLOR=true EXPERIMENTAL=true ava && FORCE_COLOR=true ava && tsd",
"pretest": "npm run build",

@@ -54,4 +54,4 @@ "cast": "svg-term --command='node media/demo.js' --out=media/demo.svg --from=100 --window --width=50 --height=8 --term=iterm2 --profile=Snazzy"

"prop-types": "^15.6.2",
"react-reconciler": "^0.20.0",
"scheduler": "^0.13.2",
"react-reconciler": "^0.21.0",
"scheduler": "^0.15.0",
"signal-exit": "^3.0.2",

@@ -80,6 +80,7 @@ "slice-ansi": "^1.0.0",

"p-queue": "^3.0.0",
"react": "^16.6.1",
"react": "^16.9.0",
"sinon": "^7.2.7",
"strip-ansi": "^5.2.0",
"svg-term-cli": "^2.1.1",
"tsd": "^0.8.0",
"xo": "^0.24.0"

@@ -122,5 +123,11 @@ },

],
"rules": {
"react/no-unescaped-entities": "off"
},
"overrides": [
{
"files": "src/components/*.js",
"files": [
"src/components/*.js",
"src/hooks/*.js"
],
"rules": {

@@ -127,0 +134,0 @@ "unicorn/filename-case": "off",

@@ -12,3 +12,3 @@ <h1 align="center">

[![Build Status](https://travis-ci.org/vadimdemedes/ink.svg?branch=master)](https://travis-ci.org/vadimdemedes/ink)
![Build Status](https://github.com/vadimdemedes/ink/workflows/tests/badge.svg)

@@ -78,2 +78,4 @@

- [sindresorhus](https://github.com/sindresorhus/sindresorhus) - The Sindre Sorhus CLI.
- [tap](https://node-tap.org) - A Test-Anything-Protocol library for JavaScript.
- [gatsby-cli](https://www.gatsbyjs.org) - Gatsby is a modern web framework for blazing fast websites.

@@ -88,4 +90,6 @@

- [Built-in Components](#built-in-components)
- [Hooks](#hooks)
- [Useful Components](#useful-components)
- [Testing](#testing)
- [Experimental mode](#experimental-mode)

@@ -99,3 +103,3 @@

To ensure all examples work and you can begin your adventure with Ink, make sure to set up Babel with a React preset. After [installing Babel](https://babeljs.io/docs/en/usage), configure it in `package.json`:
To get started with Ink quickly, use [create-ink-app](https://github.com/vadimdemedes/create-ink-app) to quickly scaffold a new Ink-based CLI. Alternatively, here's how to configure Babel to work with Ink. To ensure all examples work and you can begin your adventure, make sure to set up Babel with a React preset. After [installing Babel](https://babeljs.io/docs/en/usage), configure it in `package.json`:

@@ -192,2 +196,9 @@ ```json

###### experimental
Type: `boolean`<br>
Default: `false`
Enables [experimental mode](#experimental-mode).
```jsx

@@ -844,3 +855,84 @@ import React, {Component} from 'react';

## Hooks
### useInput
This hook is used for handling user input.
It's a more convienient alternative to using `StdinContext` and listening to `data` events.
The callback you pass to `useInput` is called for each character when user enters any input.
However, if user pastes text and it's more than one character, the callback will be called only once and the whole string will be passed as `input`.
You can find a full example of using `useInput` at [examples/useinput](examples/useinput/useinput.js).
```jsx
import {useInput} from 'ink';
const UserInput = () => {
useInput((input, key) => {
if (input === 'q') {
// Exit program
}
if (key.leftArrow) {
// Left arrow key pressed
}
});
return …
};
```
The handler function that you pass to `useInput` receives two arguments:
#### input
Type: `string`
The input that the program received.
#### key
Type: `object`
Handy information about a key that was pressed.
##### key.leftArrow
##### key.rightArrow
##### key.upArrow
##### key.downArrow
Type: `boolean`<br>
Default: `false`
If an arrow key was pressed, the corresponding property will be `true`.
For example, if user presses left arrow key, `key.leftArrow` equals `true`.
##### key.return
Type: `boolean`<br>
Default: `false`
Return (Enter) key was pressed.
##### key.ctrl
Type: `boolean`<br>
Default: `false`
Ctrl key was pressed.
##### key.shift
Type: `boolean`<br>
Default: `false`
Shift key was pressed.
##### key.meta
Type: `boolean`<br>
Default: `false`
[Meta key](https://en.wikipedia.org/wiki/Meta_key) was pressed.
## Useful Components

@@ -898,3 +990,17 @@

## Experimental Mode
Ink has experimental mode, which currently enables a more efficient and faster reconciler and renderer.
Instead of shipping it under `next` tag or something similar, Ink ships it as part of a regular release.
It can be enabled simply by passing `experimental` parameter to `render()` function:
```jsx
render(<App/>, {experimental: true});
```
Experimental mode actually includes stable features, but I want to be extra sure that it doesn't introduce regressions before shipping this new code for everyone and making it a default.
Feel free to use experimental mode in development and I would appreciate if you reported any regressions you might see.
## Maintainers

@@ -904,6 +1010,1 @@

- [Sindre Sorhus](https://github.com/sindresorhus)
## License
MIT
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc