react-select-or-create

1.2.0 • Public • Published

react-select-or-create

npm version install size license

A customizable select-or-create dropdown for ReactJS

You can view a live demo here or view this project on npm here

Features

  • Highly customizable
  • Supports keyboard shortcuts
  • Designed with a11y in mind
  • Well tested

Usage

Install the package:

yarn install react-select-or-create

In your React component:

import ReactSelectOrCreate from 'react-select-or-create';

const countries = [
  { id: 'JP', name: 'Japan' },
  { id: 'NG', name: 'Nigeria' },
  { id: 'NL', name: 'Netherlands' }
];

<ReactSelectOrCreate items={countries} />

Finally, import the styling. The component ships with minimal styling that you can override as needed.

@import "react-select-or-create/dist/main.css";

Specifying click behavior

The above example renders a simple dropdown, but it's probably not very useful since by default it doesn't do anything when an item is clicked or created.

We can specify this behavior with the onSelect and onCreate function handlers:

import ReactSelectOrCreate from 'react-select-or-create';

const colors = [{ id: 'blue', name: 'Blue' }, { id: 'pink', name: 'Pink' }];

const onSelect = (itemId) => { alert(`Item '${itemId}' clicked!`); };

const onCreate = (itemName, prevItems) => {
  alert(`Adding '${itemName}' to the end of the list!`);

  const id = String.prototype.toLowerCase(itemName);
  return prevItems.concat([{ id: id, name: itemName }]);
};

<ReactSelectOrCreate items={colors} onSelect={onSelect} onCreate={onCreate} />

Specifying asynchronous behavior

It is sometimes useful to asynchronously run the onCreate logic that handles the creation of a new item.

For example, if you are managing a list of "teams" and the user creates a new team (item), you may want to asynchronously send a POST request to your application's server before updating the list.

The onCreate prop allows you to return a Promise which will eventually return an updated list of items.

const onCreate = (itemName, prevItems) => {

  // We use an artificial delay with `setTimeout()` here to
  // mimic a long running async action
  // Reminder: Make sure you `return` your Promise!

  return new Promise((resolve) => setTimeout(resolve, 5000))
  .then(() => {
    const id = String.prototype.toLowerCase(itemName);
    return prevItems.concat([{ id: id, name: itemName }]);
  })
};

Props

items (required)

A list of items to be displayed in the dropdown list

type: {Array}

[
  { id: 1, name: 'Apple' },
  { id: 2, name: 'Banana' }
]

items will be validated as follows:

  • All ids must be unique. If duplicate ids are detected, only the first occurance of the item is used and the remaining duplicate items will be ignored when rendering.
  • ids can not be null or undefined, or they will be ignored when rendering.

onSelect

A function to be called when an item is selected.

type: {Function(String itemId, String itemName)}

default: null

The function will receive the id and name of the clicked item as arguments.

If no function is provided, then by default nothing will happen when an item is clicked.

onCreate

A function to be called when a new item is created

type: {Function(String itemName, Array prevItems)}

default: null (see behavior below)

If no function is provided (e.g. onCreate: null), then any newly created item will be added to the top of the item list with a randomly generated id.

If a function definition is provided, it will receive as arguments the name of the new item and the array of previous items. It must return either:

  • a new array of items to be displayed
  • a Promise that will return a new array of items to be displayed

Please note that it is entirely up to you to determine how to modify the array of previous items to add in the newly created item, as well as how to generate a new unique id for it.

createItemBehaviorOnEmptySearch

Defines the behavior of the "create" button when the search field is blank.

type: {String}

default: 'disabled'

There are 3 possible values:

value description
hidden The button will not be rendered.
disabled The button will be rendered, but disabled. Clicking on the button or using the ENTER key will not trigger the onCreate handler. A special CSS class create-item--disabled will also be added so you can easily style the disabled state.
enabled The button will be rendered as fully functional. Clicking on the button or using the ENTER key will trigger the onCreate handler.

In all cases the button will become enabled and clickable once some text is entered into the search field.

If any other value is provided, it will ignore it and fall back on the default value.

enableSearch

Controls whether the search <input /> is enabled.

type: {Boolean}

default: true

If true (default), the search <input /> will be displayed and enabled.

If false, no search <input /> will be displayed. In this case, remember to explicitly set createItemBehaviorOnEmptySearch={'enabled'} so that the "create" button will still be enabled even with no search <input />.

textForOpenMenuButton

Text to be displayed in the "open" button

type: {String | Function()}

default: 'Open'

If a String is provided it will be automatically wrapped in a <span> tag.

If a Function is provided, it will be called and can return any desired content, from a simple string to JSX.

textForCloseMenuButton

Text to be displayed in the "close" button

type: {String | Function()}

default: 'Close'

If a String is provided it will be automatically wrapped in a <span> tag.

If a Function is provided, it will be called and can return any desired content, from a simple string to JSX.

textForEmptyState

Text to be displayed when the list of items is empty.

type: {String}

default: 'Empty'

textForNoSearchResults

Text to be displayed when no item matches the search query.

type: {String}

default: 'No Results'

textForSearchInputPlaceholder

Text to be displayed as the search input field placeholder

type: {String}

default: 'Search...'

textForCreateItem

Text to display in the create item section. This will be updated as the user types in the search input.

type: {String | Function(String searchValue)}

default: 'Create'

If a String is provided it will be automatically wrapped in a <span> tag.

If a Function is provided, it will be called and can return any desired content, from a simple string to JSX. The function receives the current search string as an argument.

Development

If you'd like to edit or develop the component locally, you can run:

git clone https://github.com/abhchand/react-select-or-create.git

yarn install
yarn run dev

This will open http://localhost:3035 in a browser window. Any changes made to the src/ or to the examples/index.jsx file will be hot reloaded.

Issues / Contributing

  • If you have an issue or feature request, please open an issue here.

  • Contribution is encouraged! But please open an issue first to suggest a new feature and confirm that it will be accepted before filing a pull request.

Changelog

See release notes

Package Sidebar

Install

npm i react-select-or-create

Weekly Downloads

0

Version

1.2.0

License

MIT

Unpacked Size

87.6 kB

Total Files

10

Last publish

Collaborators

  • abhchand