Giter VIP home page Giter VIP logo

ink-text-input's Introduction

ink-text-input test

Text input component for Ink.

Install

npm install ink-text-input

Usage

import React, {useState} from 'react';
import {render, Box, Text} from 'ink';
import TextInput from 'ink-text-input';

const SearchQuery = () => {
	const [query, setQuery] = useState('');

	return (
		<Box>
			<Box marginRight={1}>
				<Text>Enter your query:</Text>
			</Box>

			<TextInput value={query} onChange={setQuery} />
		</Box>
	);
};

render(<SearchQuery />);

Props

value

Type: string

Value to display in a text input.

placeholder

Type: string

Text to display when value is empty.

focus

Type: boolean
Default: true

Listen to user's input. Useful in case there are multiple input components at the same time and input must be "routed" to a specific component.

showCursor

Type: boolean
Default: true

Whether to show cursor and allow navigation inside text input with arrow keys.

highlightPastedText

Type: boolean
Default: false

Highlight pasted text.

mask

Type: string

Replace all chars and mask the value. Useful for password inputs.

<TextInput value="Hello" mask="*" />
//=> "*****"

onChange

Type: Function

Function to call when value updates.

onSubmit

Type: Function

Function to call when Enter is pressed, where first argument is a value of the input.

Uncontrolled usage

This component also exposes an uncontrolled version, which handles value changes for you. To receive the final input value, use onSubmit prop. Initial value can be specified via initialValue prop, which is supported only in UncontrolledTextInput component.

import React from 'react';
import {render, Box, Text} from 'ink';
import {UncontrolledTextInput} from 'ink-text-input';

const SearchQuery = () => {
	const handleSubmit = query => {
		// Do something with query
	};

	return (
		<Box>
			<Box marginRight={1}>
				<Text>Enter your query:</Text>
			</Box>

			<UncontrolledTextInput onSubmit={handleSubmit} />
		</Box>
	);
};

render(<SearchQuery />);

ink-text-input's People

Contributors

alcuadrado avatar alvarobernalg avatar amitdahan avatar benfletcher avatar danielmschmidt avatar danikaze avatar goliney avatar ivanross avatar jdeniau avatar marionebl avatar sebald avatar sindresorhus avatar thomas-lebeau avatar vadimdemedes avatar zimme 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

ink-text-input's Issues

Ignore scroll

Currently when scrolling, the input will get weird characters like [A or [B

Rendering a second TextInput doesn't wait for input

When rendering a new TextInput after getting another input from another TextInput the second input does not wait and the app will exit.

e.g.

import React from "react";
import { Box } from "ink/build";
import TextInput from "ink-text-input";

const Input1 = ({ value, onChange }) => (
  <Box>
    Input 1:
    <TextInput value={value ?? ""} onChange={onChange} />
  </Box>
);

const Input2 = ({ value, onChange }) => (
  <Box>
    Input 2:
    <TextInput value={value ?? ""} onChange={onChange} />
  </Box>
);

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      input1: undefined,
      input2: undefined
    };

    this.onFirstInput = this.onFirstInput.bind(this);
    this.onSecondInput = this.onSecondInput.bind(this);
  }

  render() {
    return !this.state.input1 ? (
      <Input1 onChange={this.onFirstInput} />
    ) : (
      <Input2 onChange={this.onSecondInput} />
    );
  }

  onFirstInput(input1) {
    this.setState({
      input1
    });
  }

  onSecondInput(input2) {
    this.setState({
      input2
    });
  }
}

This will render Input 1: and wait for input. After pressing a key it will render Input 2: and then exit.

Does not works in Windows Power Shell 6

I'm getting this error when I run the code example :(

The above error occurred in the <TextInput> component:
    in TextInput (created by Context.Consumer)
    in TextInputWithStdin (created by SearchQuery)
    in div (created by Box)
    in Box (created by SearchQuery)
    in SearchQuery
    in App

React will try to recreate this component tree from scratch using the error boundary you provided, App.
(node:24992) UnhandledPromiseRejectionWarning: Error: Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.      
Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported
    at App.isEnabled (D:\*****\node_modules\ink\build\components\App.js:48:17)
    at TextInput.componentDidMount (D:\*****\node_modules\ink-text-input\build\index.js:171:5)
    at commitLifeCycles (D:\******\node_modules\react-reconciler\cjs\react-reconciler.development.js:12096:22)
    at commitLayoutEffects (D:\*****\node_modules\react-reconciler\cjs\react-reconciler.development.js:15342:7)
    at Object.invokeGuardedCallbackImpl (D:\******\node_modules\react-reconciler\cjs\react-reconciler.development.js:11563:10)
    at invokeGuardedCallback (D:\****\node_modules\react-reconciler\cjs\react-reconciler.development.js:11740:31)
    at commitRootImpl (D:\******\node_modules\react-reconciler\cjs\react-reconciler.development.js:15080:9)
    at unstable_runWithPriority (D:\******\node_modules\scheduler\cjs\scheduler.development.js:697:12)
    at runWithPriority (D:\*****\node_modules\react-reconciler\cjs\react-reconciler.development.js:1881:10)
    at commitRoot (D:\*****\node_modules\react-reconciler\cjs\react-reconciler.development.js:14920:3)
(node:24992) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:24992) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

SO: Windows 10 Pro
Terminal: PowerShell 6
Package versions:

    "ink": "^2.7.1",
    "ink-text-input": "^3.2.2",

Export `Props` Type

This is helpful for users who might want to make a wrapper for a stylised TextInput.

State Update on Unmounted Component

When using React Router, when ink-text-input become unmounted it throws the following error:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    in TextInput (created by Test)
    in ink-box (created by Box)
    in Box (created by Test)
    in Test (created by Start)
    in ink-box (created by Box)
    in Box (created by Start)
    in ink-box (created by Box)
    in Box (created by Fullscreen)
    in Fullscreen (created by Start)
    in Start (created by Context.Consumer)
    ```

handleInput still receiving data after the component is unmounted

This happens in a corner case when the component is unmounted due to a key input (which makes the component doesn't render anymore) but the event emitter is already iterating the listeners.

The reason this happens is, because the events emitter create a copy of the listeners to iterate them, and the stdin.removeListener call happens after the copy is done, therefore the handleInput listener receives the event and tries to update the state in a unmounted component, triggering a warning/error

Color?

Would be nice to be able to pass props to the Text component like a custom color for example.

Cursor is hidden in input when placeholder is set

If the placeholder prop is set, the cursor becomes invisible, even if showCursor is set to true.

I'm not really sure how I would expect this to be handled, I just noticed that it is slightly confusing, because the app does not look like it is waiting for input.

Is there a particular reason you decided to make it this way? Or am I missing something?

Allow `value` on `UncontrolledTextInput`

Why does UncontrolledTextInput not allow an explicit initial value? For a stateful app, this is painful. I should be able to provide both a placeholder and a value and have it display the placeholder if the value is empty/nullish.

use the Chinese input method

When you use the Chinese input method, you can only input one character at a time, but in fact, I have played several characters.

I created two TextInputs, both update simultaneously

Both are rendered, but when the code runs, there is a cursor in each one, and whatever I type shows up in both. There also doesn't seem to be any way to change focus (sorry, I'm new to Ink!).

Here's the code. There are two files, index.js:

import React from 'react'
import { render } from 'ink'

import App from './App'

try {
  render(<App />)
} catch (err) {
  console.log('index.js main caught', err)
}

And App.js, where the two TextInputs are created and used:

import React from 'react'
import { Box } from 'ink'
import TextInput from 'ink-text-input'

class NumberInput extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      entry: '',
    }

    this.handleChange = this.handleChange.bind(this)
  }

  render() {
    return (
      <Box>
        <Box marginRight={1}>{this.props.title}</Box>

        <TextInput value={this.state.entry} onChange={this.handleChange} />
      </Box>
    )
  }

  handleChange(entry) {
    this.setState({ entry })
    try {
      const num = Number(entry)
      if (!Number.isNaN(num)) {
        this.props.setValue(num)
      }
    } catch (err) {
      console.log('NumberInput.handleChange caught', err)
    }
  }
}

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      first: 0,
      second: 0,
    }

    this.setFirst = this.setFirst.bind(this)
    this.setSecond = this.setSecond.bind(this)
  }

  setFirst(val) {
    this.setState({ first: val })
  }

  setSecond(val) {
    this.setState({ second: val })
  }

  render() {
    return (
      <Box flexDirection="column">
        <Box>Adder</Box>
        <NumberInput
          key={'first'}
          setValue={this.setFirst}
          title="First number:"
        />
        <NumberInput
          key={'second'}
          setValue={this.setSecond}
          title="Second number:"
        />

        <Box>Sum: {this.state.first + this.state.second}</Box>
      </Box>
    )
  }
}

export default App

Input not rendering

Platform: macOS 10.15

The text field never appears to change when I type. This is my entire app so far, so I figure it's a bug in your code, but let me know if I'm doing something wrong. I am using typescript btw. I can post other files as needed

import React, { useState } from 'react';
import { Text } from 'ink';
import { UncontrolledTextInput } from 'ink-text-input';

function App() {
    const [submitted, submit] = useState('');
    
    if (submitted.length) {
        return <Text>{submitted}</Text>
    }
    
    return (<>
        <Text color="green">Please enter some text: </Text>
        <UncontrolledTextInput placeholder="placeholder" onSubmit={submit} />
    </>);
}

export default App;

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Created a new ink app, by using the create-ink-app tool, and installed the ink-text-input package. But am having issues with using this component.

I'm getting the following error, whenever I try to use the TextInput component:

ERROR Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

       Check the render method of `InputBox`.

Example component:

const React = require("react");
const { Box, Text } = require("ink");
const TextInput = require("ink-text-input");

const InputBox = ({}) => {
  const [value, setValue] = React.useState("");

  return (
    <Box flexDirection="column">
      <Box>
        <Text>Value:</Text>
      </Box>
      <Box>
        <TextInput value={value} onChange={setValue} />
      </Box>
    </Box>
  );
};

module.exports = { InputBox };

Add focus property to control if input is editable

Useful when you have multiple text inputs or other components, that accept some sort of input. To prevent all components handling keypress events, they should be unfocused using focus={false}. Should be true by default.

handleSubmit

The quickstart on readme.md mentioned this.handleSubmit = this.handleSubmit.bind(this);, which is empty and will set off error.

Moreover, onChange is handled properly while onSubmit is not.

Maybe we need to handle ENTER?

if(s === ENTER && this.props.onSubmit && value !== originalValue){
  return this.props.onSubmit(value);
}

Clearing value scrambles up cursor

Hi there! I'm currently building something with the TextInput component and when I'm clearing the value the behavior becomes odd and I couldn't really figure out why.

Here's what I'm doing:

const { default: InkTextInput } = require('ink-text-input');
const Example = () => {
  const [content, setContent] = useState('');
  useInput((_, key) => {
    if (key.return) {
      setContent('');
    }
  });

  return (
    <Box>
      <InkTextInput value={content} onChange={setContent} />
    </Box>
  );
};

The first time when I type content into it, it works great. Then when I hit return and it clears it it will first capture the first character and then prepend everything else. For example if I type in 1234 it will the first time write 1234. The second time it will write 2341.

ink: 3.0.3
ink-text-input: 4.0.0

Inputs are not isolated?

If I submit and then switch what Question is rendered the previous values input on the terminal

'use strict';

const { h, render, Component } = require('ink');
const TextInput = require('ink-text-input');

const allQuestions = ['Enter service account', 'enter service key'];

class Question extends Component {
  render(props, state) {
    return (<div>
            {props.question}:
            <TextInput value={state.value || ''} onChange={(value) => this.setState({value})} onSubmit={(val) => {
              props.onSubmit(val);
            //  this.setState({value:''});
            }} />
            </div>);
  }

  shouldComponentUpdate() { return true; }
}

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

		this.state = {
      question: 0,
      responses: [],
		};
	}

	render(props, state) {
    const { questions } = props;
    const { question, responses } = state;
    if (question >= questions.length) return responses.map((val, i) => (<div>Response {i}: {val}</div>));
		return (
        <Question
      question={questions[question]}
      onSubmit={(value) => this.setState({ question: question + 1, responses: responses.concat(value) })} />
		);
	}

}

render(<Gandalf questions={allQuestions}/>);

If you submit and then go to the next question the value sticks on the line and even is included in the value for the next question. The two ways I got around this are either to manually blank out the value or with my new code is to continue to display the question & value, which is a better experience anyway.

Cursor movement handling to the left/right position when being already in most left/right position is wrong

Cursor movement handling to the left/right position when being already in most left/right position is wrong. Being in most left/right position and moving a cursor to the left/right position one more time hides away a cursor but is expected behaviour would be to stay a cursor in the most left/right position constantly. Also there is the following nuance: the next typing chars are printing at wrong location.

ink version: 4.4.1
ink-text-input version: 5.0.1

Let's see it in action in a little demo:
demo

Here is a repo demonstrating this issue.

Allow preserving rawMode in stdin after unmount

Not all applications finish when this component is not rendered, and some applications are managed in rawMode independently of ink.
Adding this prop will allow to properly use this component with this type of applications.

Provide different modes of submission

Some apps might want to use this component to allow users to enter multi-line text. Right now this is not easily achieved as enter is hard-coded to be the "submission key".

My question/proposal would be to add an optional prop that would define what is a submission. Something like the following:

export type Props = {
  // ...

  /**
  * Function that determines if a key press constitutes a submission (which will result in `onSubmit` being called)
  */
  readonly isSubmit?: (key: Key) => boolean;

  // ...
};

function TextInput({
  value: originalValue,
  placeholder = '',
  focus = true,
  mask,
  highlightPastedText = false,
  showCursor = true,
  onChange,
  isSubmit = key => key.return,
  onSubmit
}: Props) {

  // ...

  useInput(
    (input, key) => {
      // ...
      if (isSubmit(key) && onSubmit) {
        onSubmit(originalValue);
	return;
      }
      // ...
  );
  
  // ...
};

This would allow for apps to support multiple-line input, defining what they consider to be the submission (e.g. 3 new lines in a row), all the while being backwards compatible.

Please let me know your thoughts and I can open a PR with the changes.

States should be isolated

I am trying to make a simple app with 2 inputs. One should run after another. But when I try to type, it types on both inputs even though I'm using focus.

ui.tsx

import React from 'react'
import { Box, Text } from 'ink'

import { state } from './state'
import { Input } from './Input'

const App = () => (
	<Box flexDirection="column">
		<Text color="#A78BFA">Compose New Post</Text>

		<Input
			label="Title"
			onSubmit={(title) => {
				state.title = title
			}}
		/>

		<Input
			label="Description"
			onSubmit={(description) => {
				state.description = description
			}}
		/>
	</Box>
)

module.exports = App
export default App

Input.tsx

import React from 'react'
import { Text } from 'ink'
import { UncontrolledTextInput } from 'ink-text-input'

interface IInput {
	label: string
	onSubmit: (s: string) => void
}

export const Input = ({ label, onSubmit }: IInput) => {
	const [submitted, setSubmitted] = React.useState(false)

	const handleSubmit = (q: string) => {
		onSubmit(q)
		setSubmitted(true)
	}

	if (submitted) return null

	return (
		<Text>
			<Text color="#6EE7B7">{label}: </Text>
			<UncontrolledTextInput focus={!submitted} onSubmit={handleSubmit} />
		</Text>
	)
}

Checkout the main branch for a reproducable demo -> https://github.com/deadcoder0904/ink-isolated-state-bug


And the fix branch contains a potential fix -> https://github.com/deadcoder0904/ink-isolated-state-bug/tree/fix

TL;DR of fix branch


It uses a fieldNo variable to move focus from 1 field to another.

App.tsx

import React from 'react'
import { Box, Text, useApp } from 'ink'

import { state } from './state'
import { Input } from './Input'

const App = () => {
	const [fieldNo, setFieldNo] = React.useState(1)
	const { exit } = useApp()

	React.useEffect(() => {
		if (fieldNo === 3) exit()
	}, [fieldNo])

	return (
		<Box flexDirection="column">
			<Text color="#A78BFA">Compose New Post</Text>

			<Input
				label="Title"
				focus={fieldNo === 1}
				onSubmit={(title) => {
					state.title = title
					setFieldNo(2)
				}}
			/>

			<Input
				focus={fieldNo === 2}
				label="Description"
				onSubmit={(description) => {
					state.description = description
					setFieldNo(3)
				}}
			/>
		</Box>
	)
}

module.exports = App
export default App

I don't think this should be needed. Is this how it's supposed to work? Because I'm unable to find any simple examples online using Multiple Text Inputs & I've searched for 2 days now.

Another thing is exit doesn't work here as it should. Am I doing anything wrong? Should I create a new issue?

Duplicate text when pressing the Delete button

Steps to reproduce:

  1. Type some text in the field (length > 0)
  2. move the cursor at the beginning of the string
  3. Press Delete

Expected result:
Nothing happens when you delete from the beginning of the string

Actual result:
The text in the field is duplicated

Usage example doesn't work

Summary

  • Ink works
  • Usage example in ink-text-input does not work
  • Error: "stdin.setRawMode is not a function"

Ink is working as expected

input
a_code_demo

output
a_output_demo

ink-text-input "Usage" example is not working

Error: "stdin.setRawMode is not a function"

input
b_code_TextInput

output
b_output_TextInput

ink-text-input after implementing componentDidCatch

Did this to address the error bounds request in previous error message

input
c_code_componentDidCatch

output
c_output_componentDidCatch1

c_output_componentDidCatch2


Possibly related to vadimdemedes/ink#166

Would be nice to have a hidden-length password

When using * to mask a password, you're still giving away password length (which gives a lot of information to potential bad actors). A lot of command line password-entry tools either do not show any characters of show a static number of ******. It would be nice to have this here also.

Example not working with hooks

Issue

The example does not work with react hooks.

Output

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `UserInfo`.
    in UserInfo (created by Layout)
    in div (created by Box)
    in Box (created by Layout)
    in Layout
    in App
The above error occurred in the <div> component:
    in div (created by Box)
    in Box (created by UserInfo)
    in UserInfo (created by Layout)
    in div (created by Box)
    in Box (created by Layout)
    in Layout
    in App

React will try to recreate this component tree from scratch using the error boundary you provided, App.
Warning: App: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.
(node:9107) UnhandledPromiseRejectionWarning: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `UserInfo`.
    at invariant (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:53:15)
    at createFiberFromTypeAndProps (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:1913:11)
    at createFiberFromElement (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:1934:15)
    at createChild (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:4008:28)
    at reconcileChildrenArray (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:4259:25)
    at reconcileChildFibers (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:4582:14)
    at reconcileChildren (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:6385:28)
    at updateHostComponent (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:6846:3)
    at beginWork (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:7632:14)
    at performUnitOfWork (/Users/hunter/preme-o/node_modules/react-reconciler/cjs/react-reconciler.development.js:11295:12)
(node:9107) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9107) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

UserInfo component

// UserInfo.js
const React = require('react');
const { useState } = require('react');
const { Box } = require('ink');
const TextInput = require('ink-text-input');

const UserInfo = () => {
  const [name, setName] = useState('');

  return (
    <Box>
      <Box marginRight={1}>Enter your query:</Box>
      <TextInput value={name} onChange={() => setName(name)} />
    </Box>
  );
};

module.exports = UserInfo;

Layout component

const React = require('react');
const { Box, render } = require('ink');
const importJsx = require('import-jsx');

const Brand = importJsx('./Brand');
const UserInfo = importJsx('./UserInfo');

const Layout = () => (
  <Box>
    <Brand />
    <UserInfo />
  </Box>
);

render(<Layout />);

index.js

const importJsx = require('import-jsx');

module.exports = importJsx('./components/Layout');

Hope UncontrolledTextInput can clears input after submission

I found UncontrolledTextInput very useful. However, there is an inconvenient place that after UncontrolledTextInput submits the input, the value will stay in the input. This is inconvenient to use, as input in the CLI is usually cleared after submission. I made the following simple adjustments based on your program. Hopefully, you have a comfortable way to add props to the application to control whether it clears its input after submission.

export class UncontrolledTextInput extends PureComponent {
	state = {
		value: ''
	}

	setValue(value) {
		this.setState({value});
	}
	clearValue(value){
		this.props.whenSubmit && this.props.whenSubmit(value)
		this.setState({
			value: ''
		})
	}

	setValue = this.setValue.bind(this);

	render() {
		return <TextInputWithStdin {...this.props} onSubmit={this.clearValue} value={this.state.value} onChange={this.setValue}/>;
	}
}

Thank you for your work!

Error running example in readme

Hi, when I try to run the example in the readme, I get this error:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `SearchQuery`.
    in SearchQuery
    in App
The above error occurred in the <div> component:
    in div (created by Box)
    in Box (created by SearchQuery)
    in SearchQuery
    in App

React will try to recreate this component tree from scratch using the error boundary you provided, App.
Warning: App: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.
(node:64515) UnhandledPromiseRejectionWarning: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of `SearchQuery`.
    at invariant (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:53:15)
    at createFiberFromTypeAndProps (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:1913:11)
    at createFiberFromElement (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:1934:15)
    at createChild (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:4008:28)
    at reconcileChildrenArray (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:4259:25)
    at reconcileChildFibers (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:4582:14)
    at reconcileChildren (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:6385:28)
    at updateHostComponent (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:6846:3)
    at beginWork (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:7632:14)
    at performUnitOfWork (/Users/isaacs/dev/js/tap/node_modules/react-reconciler/cjs/react-reconciler.development.js:11295:12)
(node:64515) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:64515) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Using [email protected], [email protected]. Same on node 8, 10, and 12.

Ignore escape sequences

For example, I have a text input on my screen, but I want to do something when the user presses ^D. I don't want that d to go into the text input.

I don't control the text input so I can't wrap useInput... is what I want to do possible? I feel like if it's not, it should be :)

Ctrl keys are consumed even when they shouldn't

If I design keyboard shortcuts for quick access to specific inputs in my GUI, like: Ctrl+N to jump to some given text field, and one <TextInput> currently has the focus, it will use up and display the n letter (although key.ctrl === true, and my other useInput in the app will be invoked and will correctly pass the focus to where I wish, but... too late).

I would suggest an additional prop to <TextInput>: a keyFilter callback, which would receive the input+key (just as useInput) and would return true if the program should absorb (swallow) that key combination, or let it go through to the regular treatment of TextInput.

I can make a PR if someone else thinks this should exit.
Thanks

Support pasting

Currently if you paste into an empty field, only the last char is displayed. Here's the log of keypress events and output when pasting "atom":

{ sequence: 'a',
  name: 'a',
  ctrl: false,
  meta: false,
  shift: false }
{ sequence: 't',
  name: 't',
  ctrl: false,
  meta: false,
  shift: false }
{ sequence: 'o',
  name: 'o',
  ctrl: false,
  meta: false,
  shift: false }
{ sequence: 'm',
  name: 'm',
  ctrl: false,
  meta: false,
  shift: false }
m
m
m
m

Notice that output follows keypress events, so it seems that keypress events arrive all at once for each char before an update to stdout is written.

Currently batching of setState() isn't supported in Ink, but I don't think it's related / going to help this. Maybe some queueing of keypress events should be implemented in <TextInput>.

UncontrolledTextInput wrong typings & docs

The docs describe the usage of UncontrolledTextInput:

<UncontrolledTextInput onSubmit={handleSubmit} />

With an optional prop initialValue.

The prop typings are wrong. The required/expected prop instead of onSubmit is onChange and it does not accept initialValue at all, instead requires a value.

So the required syntax is:

<UncontrolledTextInput value="whatever" onChange={() => { console.log('whatever')}} />

Also Except should be replaced with Omit to fix:

interface UncontrolledProps extends Omit<Props, 'value' | 'onChange'> {
  /**
   * Initial value.
   */
  initialValue?: string
}

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.