Giter Site home page Giter Site logo

ink-select-input's Introduction

ink-select-input test

Select input component for Ink

Looking for a version compatible with Ink 2.x? Check out this release.

Install

$ npm install ink-select-input

Usage

import React from 'react';
import {render} from 'ink';
import SelectInput from 'ink-select-input';

const Demo = () => {
	const handleSelect = item => {
		// `item` = { label: 'First', value: 'first' }
	};

	const items = [
		{
			label: 'First',
			value: 'first'
		},
		{
			label: 'Second',
			value: 'second'
		},
		{
			label: 'Third',
			value: 'third'
		}
	];

	return <SelectInput items={items} onSelect={handleSelect} />;
};

render(<Demo />);

Props

items

Type: array
Default: []

Items to display in a list. Each item must be an object and have label and value props, it may also optionally have a key prop. If no key prop is provided, value will be used as the item key.

isFocused

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.

initialIndex

Type: number Default: 0

Index of initially-selected item in items array.

limit

Type: number

Number of items to display.

indicatorComponent

Type: Component

Custom component to override the default indicator component.

itemComponent

Type: Component

Custom component to override the default item component.

onSelect

Type: function

Function to call when user selects an item. Item object is passed to that function as an argument.

onHighlight

Type: function

Function to call when user highlights an item. Item object is passed to that function as an argument.

ink-select-input's People

Contributors

alvarobernalg avatar amitdahan avatar cameronhunter avatar cblanc avatar duncanbeevers avatar kevva avatar khanghoang avatar lujiajing1126 avatar maticzav avatar olingern avatar ptpaterson avatar sebald avatar vadimdemedes avatar waterunderthefridge01 avatar zimme avatar zkat 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

ink-select-input's Issues

Component does not gracefully handle overflow

I think internally it should subscribe to its own height and use that as the limit if no limit is specified. Doing this manually is a huge pain (wrapping it in Box with a ref and using measure, etc) and I sort of expected it to automatically truncate itself if it runs out of space

Or am I misunderstanding how this is supposed to work?

[email protected] introduced a regression preventing ink-select-input to pass tests

Context

Last week, I had a bit of time to upgrade dependencies of an ink based project, hence I tried to move to [email protected] (latest to the date of this post).
On the runtime side, nothing to declare, works like a charm.

Issue

Since PR ink #581, packaged in [email protected], the ink-select-input refuses to pass any test rendering options.
Checking out to this very repo, I tried to launch local tests against ink@>=4.3 and failed with the same output.

Here the output of actual.lastFrame() in test('list', t => {...

  ERROR  stdin.ref is not a function

 node_modules/ink/src/components/App.tsx:166:11

 - value (node_modules/ink/src/components/App.tsx:166:11)
 -  (node_modules/ink/src/hooks/use-input.ts:128:3)
 -commitHookEffectListMoun (node_modules/react-reconciler/cjs/react-reconciler.development.js:14778
                          :26)
 -commitPassiveMountOnFibe (node_modules/react-reconciler/cjs/react-reconciler.development.js:16609
                          :11)
 -commitPassiveMountEffects_comp (node_modules/react-reconciler/cjs/react-reconciler.development.js
  ete                           :16569:9)
 -commitPassiveMountEffects_be (node_modules/react-reconciler/cjs/react-reconciler.development.js:1
  in                          6556:7)
 -commitPassiveMountEffect (node_modules/react-reconciler/cjs/react-reconciler.development.js:16544
                          :3)
 -flushPassiveEffectsImpl (node_modules/react-reconciler/cjs/react-reconciler.development.js:19182:
                         3)
 - flushPassiveEffects (node_modules/react-reconciler/cjs/react-reconciler.development.js:19127:14)
 -performSyncWorkOnRoot (node_modules/react-reconciler/cjs/react-reconciler.development.js:18184:3)

I tried to figure out how to get around the issue by using ink-testing-library along with react-testing-library but divergence between underlaying react-dom and ink custom reconciler makes me think I'm on the wrong path.

I'd be willing to help fixing it with a bit more of guidance on how to diagnose and address the issue.

Add onHighlight prop

Hey there. This and the rest of ink has been really rad, thanks for all your hard work!

It would be pretty nice (and helpful for a current project) to have the ability to pass an onHighlight prop (or something like that) that would be invoked when an item is highlighted, e.g. when the up or down arrows are pressed (but not when enter is pressed), and I'd be happy to get a PR together for it if it's something you're open to. Let me know what you think, thanks!

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-select-input package. But am having issues with using this component.

I'm getting the following error, whenever I try to use the SelectInput 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 SelectInput = require("ink-select-input");

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

  return (
    <Box flexDirection="column">
      <Box>
        <Text>Value:</Text>
      </Box>
      <Box>
        <SelectInput />
      </Box>
    </Box>
  );
};

module.exports = { InputBox };

Typescript: cannot import Item component - type is imported instead

index.test-d.tsx exports types and default value (InkSelectInput):

/**
* Select input component for Ink
*/
export default class InkSelectInput extends React.Component<InkSelectInputProps> {}

However, it doesn't export Item and Indicator components. Because of that, an attempt to import Item from ink-select-input ends up with:

image

Error:

error TS2693: 'Item' only refers to a type, but is being used as a value here.

Code snippet used:

import React from 'react';
import SelectInput, { Item, InkSelectInputProps } from 'ink-select-input';

export function ChoicesComponent({ itemComponent = Item, items, onSubmit }: Props) {
  return <SelectInput 
    itemComponent={itemComponent} 
    items={items} 
    onSelect={onSubmit} 
  />;
}

type ChoiceValue = any;

interface ChoiceOption {
  key?: string;
  label: string;
  value: ChoiceValue;
}

interface Choices {
  message?: string;
  items: ChoiceOption[];
}

interface Props extends Choices {
  onSubmit: () => void;
  itemComponent?: InkSelectInputProps['itemComponent'];
}

Create an option to render horizontally

Can we have the option to render ink-select-input horizontally?

In the SelectInput.js file you can change the alignment by changing line 24 and 41 to key.leftArrow and key.rightArrow respectively and changing the flex direction to "row" on line 75.

See below for examples:

Screen Shot 2020-08-25 at 4 38 40 PM

Screen Shot 2020-08-25 at 4 40 22 PM

And it renders like this:
Screen Shot 2020-08-25 at 4 42 05 PM

stdin.setRawMode is not a function

When trying to spin up a simple example of the SelectInput using the demo code sample, I'm getting

(node:4893) UnhandledPromiseRejectionWarning: TypeError: stdin.setRawMode is not a function
    at App.isEnabled (/Users/hh68154/Desktop/Keep/sites/cli/node_modules/ink/build/components/App.js:47:17)
    at SelectInput.componentDidMount (/Users/hh68154/Desktop/Keep/sites/cli/node_modules/ink-select-input/build/SelectInput.js:153:5)

I'm using "ink": "^2.0.0", and "ink-select-input": "^3.1.0",. Any idea what the problem may be?

How could I change the highlight item's color?

The highlight item's default color is blue, this color is not legibility over black terminal background color. I want to change the highlight color to be more bright.

Hope there are some solution inside this component, thanks.

change highlight color on focus

Related to #13 , I would like to disable or change the highlight color of the selected item depending on whether the select-input currently has focus. With more than one select-input next to each other, it is hard to tell which has focus:

image

I can provide an indicator component and conditionally change that, but all I really need to do is change the highlight color based on whether the input has focus or not.

Would you be open to a PR for an optional highlightColor prop or something along those lines?

Allow to not select anything

I want to use this component to render a list, and only make the user select if they actually press up or down. Sort of like a radiogroup without a value in the browser.

Currently I can set focus={false}, but that just means it doesn't respond to keypresses - it still renders like the top item is selected/highlighted

Ref vadimdemedes/ink#138

React.createElement: type is invalid

Using a fresh install of https://github.com/vadimdemedes/create-ink-app, installing ink-select-input, and running the demo from the README generates the following error:

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

The above error occurred in the <Demo> component:
    in Demo (created by App)
    in div (created by Box)
    in Box (created by App)
    in App
    in App

Check the render method of `Demo`.
    at createFiberFromTypeAndProps (/node_modules/react-reconciler/cjs/react-reconciler.development.js:16627:21)
    at createFiberFromElement (/node_modules/react-reconciler/cjs/react-reconciler.development.js:16650:15)
    at reconcileSingleElement (/node_modules/react-reconciler/cjs/react-reconciler.development.js:5302:23)
    at reconcileChildFibers (/node_modules/react-reconciler/cjs/react-reconciler.development.js:5362:35)
    at reconcileChildren (/node_modules/react-reconciler/cjs/react-reconciler.development.js:7865:28)
    at mountIndeterminateComponent (/node_modules/react-reconciler/cjs/react-reconciler.development.js:8629:5)
    at beginWork$1 (/node_modules/react-reconciler/cjs/react-reconciler.development.js:9938:16)
    at Object.invokeGuardedCallbackImpl (/node_modules/react-reconciler/cjs/react-reconciler.development.js:11563:10)
    at invokeGuardedCallback (/node_modules/react-reconciler/cjs/react-reconciler.development.js:11740:31)
    at beginWork$$1 (/node_modules/react-reconciler/cjs/react-reconciler.development.js:15778:7)

Reset highlight after items change

According to the componentDidUpdate lifecycle method,

if (!isEqual(prevProps.items, this.props.items)) {
.....

The cursor will be reset everytime the items "change" which is not expected
in some cases.

For example, I just change the label properties which is actually displayed
on the screen, without changing value which is the key of the item and represents
real data. If so, the cursor is still reset.

So, I wonder if the condition could be changed. For example, just compare the values
of the items, or at least the length of the array.

Also, the control may be given to the developer by passing some prop as a function of shouldResetCursor?

initialIndex is not working with limit

if there are a list of 20 items and the limit is set as 10,
It is not selecting anything if initialIndex is set as 13

Expected Behaviour:
it would select 13 and the list window is showing the range of item list containning the 13th item

Select element is rendered horizontally

Hej, I’m new to ink. The start was a bit confusing because of the JSX setup.

I finally used the Yeoman generator which ran like expected.

But when using the demo code of this modules readme the select looks different than expected:

image

cli.js:

#!/usr/bin/env node
'use strict';

const importJsx = require('import-jsx');
const {h, render} = require('ink');
const Ui = importJsx('./ui');

render(h(Ui));

ui.js:

'use strict';

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

const Ui = () => {
	const handleSelect = item => {
		// `item` = { label: 'First', value: 'first' }
		console.dir(item);
	};

	const items = [{
		label: 'First',
		value: 'first'
	}, {
		label: 'Second',
		value: 'second'
	}, {
		label: 'Third',
		value: 'third'
	}];

	return <SelectInput items={items} onSelect={handleSelect}/>
};

module.exports = Ui;

The package.json is pretty much like created from the Yeoman generator:

{
	"name": "tweet",
	"version": "0.0.0",
	"description": "An interactive Twitter CLI.",
	"license": "MIT",
	"repository": "mischah/tweet",
	"author": {
		"name": "Michael Kühnel",
		"email": "[email protected]",
		"url": "michael-kuehnel.de"
	},
	"bin": "cli.js",
	"engines": {
		"node": ">=6"
	},
	"scripts": {
		"test": "xo && nyc ava"
	},
	"files": [
		"cli.js",
		"ui.js"
	],
	"keywords": [
		""
	],
	"dependencies": {
		"ink": "^0.2.1",
		"ink-select-input": "^1.1.0",
		"meow": "^3.7.0",
		"prop-types": "^15.5.10"
	},
	"devDependencies": {
		"ava": "^0.20.0",
		"babel-plugin-transform-react-jsx": "^6.24.1",
		"codecov": "^2.2.0",
		"eslint-config-xo-react": "^0.13.0",
		"eslint-plugin-react": "^7.1.0",
		"import-jsx": "^1.2.0",
		"nyc": "^11.0.0",
		"xo": "^0.18.2"
	},
	"ava": {
		"babel": {
			"presets": [
				"@ava/stage-4"
			],
			"plugins": [
				[
					"transform-react-jsx",
					{
						"pragma": "h",
						"useBuiltIns": true
					}
				]
			]
		}
	},
	"xo": {
		"extends": [
			"xo-react"
		],
		"rules": {
			"react/no-unused-prop-types": 1
		},
		"settings": {
			"react": {
				"pragma": "h"
			}
		}
	},
	"nyc": {
		"reporter": [
			"lcov",
			"text"
		]
	}
}

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.