Giter Club home page Giter Club logo

react-tags's Introduction

React tags

MIT NPM Version npm downloads Build Statuscode style: prettier

React-tags is a simple tagging component ready to drop in your projects. The component is inspired by GMail's To field in the compose window.

Features

  • Autocomplete based on a suggestion list
  • Keyboard friendly and mouse support
  • Reorder tags using drag and drop
  • Edit tag support
  • Optional clear all button

Why

Started by Prakhar Srivastav and later maintained by Aakansha Doshi.

In Prakhar's words here is why he started itπŸ‘‡πŸ»

Because I was looking for an excuse to build a standalone component and publish it in the wild? To be honest, I needed a tagging component that provided the above features for my React-Surveyman project. Since I was unable to find one which met my requirements (and the fact that I generally enjoy re-inventing the wheel) this is what I came up with.

Demo

img

Check it out here

Installation

You can use npm

npm install --save react-tag-input

or via Yarn

yarn add react-tag-input

make sure you have installed the peer dependencies as well with πŸ‘‡ versions

 "react": "^18.2.0",
 "react-dnd": "^14.0.2",
 "react-dnd-html5-backend": "^14.0.0",
 "react-dom": "^18.2.0"

It is, however, also available to be used separately (dist/ReactTags.min.js). If you prefer this method remember to include ReactDND as a dependancy. Refer to the example to see how this works.

Usage

Here's a sample implementation that initializes the component with a list of initial tags and suggestions list. Apart from this, there are multiple events, handlers for which need to be set. For more details, go through the API.

import React from 'react';
import { createRoot } from 'react-dom/client';
import { StrictMode } from 'react';
import GitHubCorner from './GithubCorner';
import type { Tag } from '../src/components/SingleTag';
import { WithContext as ReactTags, SEPARATORS } from '../src/index';
;

const suggestions = COUNTRIES.map((country) => {
  return {
    id: country,
    text: country,
    className: '',
  };
});

const KeyCodes = {
  comma: 188,
  enter: [10, 13],
};


const App = () => {
  const [tags, setTags] = React.useState<Array<Tag>>([
    { id: 'Thailand', text: 'Thailand', className: '' },
    { id: 'India', text: 'India', className: '' },
    { id: 'Vietnam', text: 'Vietnam', className: '' },
    { id: 'Turkey', text: 'Turkey', className: '' },
  ]);

  const handleDelete = (index: number) => {
    setTags(tags.filter((_, i) => i !== index));
  };

  const onTagUpdate = (index: number, newTag: Tag) => {
    const updatedTags = [...tags];
    updatedTags.splice(index, 1, newTag);
    setTags(updatedTags);
  };

  const handleAddition = (tag: Tag) => {
    setTags((prevTags) => {
      return [...prevTags, tag];
    });
  };

  const handleDrag = (tag: Tag, currPos: number, newPos: number) => {
    const newTags = tags.slice();

    newTags.splice(currPos, 1);
    newTags.splice(newPos, 0, tag);

    // re-render
    setTags(newTags);
  };

  const handleTagClick = (index: number) => {
    console.log('The tag at index ' + index + ' was clicked');
  };

  const onClearAll = () => {
    setTags([]);
  };

  return (
    <div className="app">
      <GitHubCorner />

      <h1> React Tags Example </h1>
      <div>
        <ReactTags
          tags={tags}
          suggestions={suggestions}
          separators={[SEPARATORS.ENTER, SEPARATORS.COMMA]}
          handleDelete={handleDelete}
          handleAddition={handleAddition}
          handleDrag={handleDrag}
          handleTagClick={handleTagClick}
          onTagUpdate={onTagUpdate}
          inputFieldPosition="bottom"
          editable
          clearAll
          onClearAll={onClearAll}
          maxTags={7}
        />
      </div>
    </div>
  );
};
const domNode = document.getElementById('app')!;
const root = createRoot(domNode);

root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

A note about Contexts One of the dependencies of this component is the react-dnd library. Since the 1.0 version, the original author has changed the API and requires the application using any draggable components to have a top-level backend context. So if you're using this component in an existing Application that uses React-DND you will already have a backend defined, in which case, you should require the component without the context.

const ReactTags = require('react-tag-input').WithOutContext;

Otherwise, you can simply import along with the backend itself (as shown above). If you have ideas to make this API better, I'd love to hear.

Options

Option Type Default Description
tags Array [] An array of tags that are displayed as pre-selected.
suggestions Array [] An array of suggestions that are used as basis for showing suggestions.
delimiters Array [13, 9] Specifies which characters keycode should terminate tags input.
separators Array ["Enter", "Tab"] Specifies which characters should terminate tags input
placeholder String Add new tag The placeholder shown for the input.
labelField String text Provide an alternative label property for the tags.
handleAddition Function undefined Function called when the user wants to add a tag (required).
handleDelete Function undefined Function called when the user wants to delete a tag (required).
handleDrag Function undefined Function called when the user drags a tag.
handleFilterSuggestions Function undefined Function called when filtering suggestions.
handleTagClick Function undefined Function called when the user wants to know which tag was clicked.
autofocus Boolean true Boolean value to control whether the text-input should be autofocused on mount.
autoFocus Boolean true Boolean value to control whether the text-input should be autofocused on mount.
allowDeleteFromEmptyInput Boolean true Boolean value to control whether tags should be deleted when the 'Delete' key is pressed in an empty Input Box.
handleInputChange Function undefined Event handler for input onChange.
handleInputFocus Function undefined Event handler for input onFocus.
handleInputBlur Function undefined Event handler for input onBlur.
minQueryLength Number 2 How many characters are needed for suggestions to appear.
removeComponent Function Function to render custom remove component for the tags.
autocomplete Boolean/Number false Ensure the first matching suggestion is automatically converted to a tag when a separator key is pressed.
readOnly Boolean false Read-only mode without the input box and removeComponent and drag-n-drop features disabled.
name String undefined The name attribute added to the input.
id String undefined The id attribute added to the input.
maxLength Number Infinity The maxLength attribute added to the input.
inline Boolean true Render input field and selected tags in-line.
inputFieldPosition String inline Specify position of input field relative to tags
allowUnique Boolean true Boolean value to control whether tags should be unqiue.
allowDragDrop Boolean true Implies whether tags should have drag-n-drop features enabled.
renderSuggestion Function undefined Render prop for rendering your own suggestions.
inputProps Object {} The extra attributes which are passed to the input field.
allowAdditionFromPaste boolean true Implies whether to allow paste action when adding tags.
editable boolean false Implies whether the tags should be editable.
onTagUpdate Function This callback if present is triggered when tag is edited.
clearAll boolean false Implies whether 'clear all' button should be shown.
onClearAll Function This callback if present is triggered when clear all button is clicked.
maxTags number The maximum count of tags to be added

tags

An array of tags that are displayed as pre-selected. Each tag should have an id property, property for the label, which is specified by the labelField and class for label, which is specified by className.

// With default labelField
const tags =  [ { id: "1", text: "Apples" } ]

// With labelField of `name`
const tags =  [ { id: "1", name: "Apples" } ]

// With className
const tags = [ { id: "1", text: "Apples", className: 'red'} ]

suggestions

An array of suggestions that are used as basis for showing suggestions. These objects should follow the same structure as the tags. So if the labelField is name, the following would work:

// With labelField of `name`
const suggestions = [
    { id: "1", name: "mango" },
    { id: "2", name: "pineapple"},
    { id: "3", name: "orange" },
    { id: "4", name: "pear" }
];

delimiters

This prop is deprecated and will be removed in 7.x.x. Please use separators instead. Specifies which characters should terminate tags input. An array of character codes. We export the constant KEYS for convenience.

import { WithContext as ReactTags, KEYS } from 'react-tag-input';

<ReactTags
    delimiters={[KEYS.TAB, KEYS.SPACE, KEYS.COMMA]}
 />

separators

Specifies which characters should separate tags. An array of strings. We support the below separators πŸ‘‡

  • Enter
  • Tab
  • Space
  • Comma
  • Semicolon

And we export the constant SEPERATORS for convenience.

import { WithContext as ReactTags, SEPARATORS } from 'react-tag-input';
<ReactTags
    separators={[SEPARATORS.TAB, SEPARATORS.SPACE, SEPARATORS.COMMA]}
 />

placeholder

The placeholder shown for the input.

let placeholder = "Add new country"

labelField

Provide an alternative label property for the tags.

<ReactTags
    tags={tags}
    suggestions={}
    labelField={'name'}
    handleDrag={}
 />

This is useful if your data uses the text property for something else.

handleAddition

Function called when the user wants to add a tag (either a click, a tab press or carriage return)

function(tag) {
    // add the tag to the tag list
}

handleDelete

Function called when the user wants to delete a tag

function(i) {
    // delete the tag at index i
}

handleDrag

If you want tags to be draggable, you need to provide this function. Function called when the user drags a tag.

function(tag, currPos, newPos) {
    // remove tag from currPos and add in newPos
}

handleFilterSuggestions

To assert control over the suggestions filter, you may contribute a function that is executed whenever a filtered set of suggestions is expected. By default, the text input value will be matched against each suggestion, and those that start with the entered text will be included in the filters suggestions list. If you do contribute a custom filter function, you must return an array of suggestions. Please do not mutate the passed suggestions array.

For example, if you prefer to override the default filter behavior and instead match any suggestions that contain the entered text anywhere in the suggestion, your handleFilterSuggestions property may look like this:

function(textInputValue, possibleSuggestionsArray) {
    var lowerCaseQuery = textInputValue.toLowerCase()

    return possibleSuggestionsArray.filter(function(suggestion)  {
        return suggestion.toLowerCase().includes(lowerCaseQuery)
    })
}

Note: The above custom filter uses String.prototype.includes, which was added to JavaScript as part of the ECMAScript 7 specification. If you need to support a browser that does not yet include support for this method, you will need to either refactor the above filter based on the capabilities of your supported browsers, or import a polyfill for String.prototype.includes.

handleTagClick

Function called when the user wants to know which tag was clicked

function(i) {
    // use the tag details at index i
}

autofocus

Optional boolean param to control whether the text-input should be autofocused on mount. This prop is deprecated and will be removed in 7.x.x, please use autoFocus instead.

<ReactTags
    autofocus={false}
    ...>

autoFocus

Optional boolean param to control whether the text-input should be autofocused on mount.

<ReactTags
    autoFocus={false}
    ...>

allowDeleteFromEmptyInput

Optional boolean param to control whether tags should be deleted when the Backspace key is pressed in an empty Input Box. By default this prop is false.

However when input field position is inline, you will be able to delete the tags by pressing Backspace irrespective of the value of this prop.

This prop will likely be removed in future versions.

<ReactTags
    allowDeleteFromEmptyInput={true}
    ...>

handleInputChange

Optional event handler for input onChange

Signature

(value, event) => void

The value denotes the target input value to be added and the event is the original event for onChange.

<ReactTags
    handleInputChange={this.handleInputChange}
    ...>

handleInputFocus

Optional event handler for input onFocus

<ReactTags
    handleInputFocus={this.handleInputFocus}
    ...>

Signature

(value, event) => void

The value denotes the target input value to be added and the event is the original event for onFocus.

handleInputBlur

Optional event handler for input onBlur

Signature

(value, event) => void

The value denotes the target input value to be added and the event is the original event for onBlur.

<ReactTags
    handleInputBlur={this.handleInputBlur}
    ...>

minQueryLength

Minimum number of characters needed for suggestions to appear. Defaults to 2.

removeComponent

If you'd like to supply your own tag delete/remove element, create a React component and pass it as a property to ReactTags using the removeComponent option. By default, a simple anchor link with an "x" text node as its only child is rendered, but if you'd like to, say, replace this with a <button> element that uses an image instead of text, your markup may look something like this:

import {WithContext as ReactTags} from 'react-tag-input'

class Foo extends React.Component {
   render() {
      return <ReactTags removeComponent={RemoveComponent}/>
   }
}

class RemoveComponent extends React.Component {
   render() {
     const { className, onRemove } = this.props;
      return (
         <button onClick={onRemove} className={className}>
            <img src="my-icon.png" />
         </button>
      )
   }
}

The below props will be passed to the removeComponent. You will need to forward the relevant props to your custom remove component to make it work.

Name Type Description
className string The prop classNames.remove passed to the ReactTags component gets forwarded to the remove component. Defaults to ReactTags__remove
onRemove Function The callback to be triggered when tag is removed, you will need to pass this to the onClick handler of the remove component
onKeyDown Function The callback to be triggered when keydown event occurs. You will need to pass this to onKeyDown handler of the remove component
aria-label string The aria-label to be announced when the tag at an index is deleted
tag
{ id?: string, className: string, key: string }
The tag to be deleted.
index number the index of the tag to be deleted.

autocomplete

This prop is deprecated and will be removed in 7.x.x to simplify the integration and make it more intutive. If you have any concerns regarding this, please share your thoughts in #949.

Useful for enhancing data entry workflows for your users by ensuring the first matching suggestion is automatically converted to a tag when a separator key is pressed (such as the enter key). This option has three possible values:

  • true - when separator key (such as enter) is pressed, first matching suggestion is used.
  • 1 - when separator key (such as enter) is pressed, matching suggestion is used only if there is a single matching suggestion
  • false (default) - tags are not autocompleted on enter/separator key press.

This option has no effect if there are no suggestions.

readOnly

Renders the component in read-only mode without the input box and removeComponent. This also disables the drag-n-drop feature.

name

The name attribute added to the input.

<ReactTags
    name = "inputName"
    ...>

id

The id attribute added to the input.

<ReactTags
    id = "inputId"
    ...>

maxLength

The maxLength attribute added to the input. Specifies the maximum number of characters allowed in the input field.

<ReactTags
    maxLength = "42"
    ...>

inline

The inline attributes decides whether the input fields and selected tags will be rendered in-line.

<ReactTags
    inline
    ...>

img

<ReactTags
    inline={false}
    ...>

img

This attribute is deprecated and will be removed in v7.x.x, see inputFieldPosition.

inputFieldPosition

The inputFieldPosition attribute decides the positioning of the input field relative to the tags. Can be one of inline, top or bottom.

<ReactTags
    inputFieldPosition="inline"
    ...>

img

<ReactTags
    inputFieldPosition="top"
    ...>

img

<ReactTags
    inputFieldPosition="bottom"
    ...>

img

allowUnique

This prop controls whether tags should be unique.

allowDragDrop

This prop controls whether tags should have the drag-n-drop feature enabled.

renderSuggestion

This props allows to provide your own suggestion renderer and override the default one. It receives the suggestion and the query string as parameters. For example:

<ReactTags
    renderSuggestion = {({ text }, query) => <div style={{ textDecoration: 'underline', textDecorationStyle: 'wavy' }}>{text} ({ query })</div>}
    ...>

inputProps

When you want to pass additional attributes to the input element (for example autocomplete, disabled etc) you can use this prop.

<ReactTags
  inputProps = {{
    disabled: true,
    autocomplete: "off"
  }}
/>

allowAdditionFromPaste

This prop implies whether to allow paste action for adding tags. Defaults to true.

editable

This prop implies whether the tags should be editable. Defaults to false.

onTagUpdate

onTagUpdate(editIndex, tag) => void;

This callback is if present is triggered when tag is updated. The edit index and the tag are passed in the callback. You can update the tags prop in this callback.

clearAll

This props implies whether 'clear all' button should be shown. Defaults to false.

onClearAll

This callback is if present is triggered when "clear all" button is clicked. You can set the tags prop to empty in this callback.

maxTags

This prop specifies the maximum count of tags to be added. Incase the tags exceed, error will show up to convey the maximum tag limit has reached.

Styling

<ReactTags> does not come up with any styles. However, it is very easy to customize the look of the component the way you want it. By default, the component provides the following classes with which you can style -

  • ReactTags__tags
  • ReactTags__tagInput
  • ReactTags__tagInputField
  • ReactTags__selected
  • ReactTags__selected ReactTags__tag
  • ReactTags__selected ReactTags__remove
  • ReactTags__suggestions
  • ReactTags__activeSuggestion
  • ReactTags__editTagInput
  • ReactTags__editTagInputField
  • ReactTags__clearAll

An example can be found in /example/reactTags.css.

If you need to set your own class names on the component, you may pass in a classNames prop.

  <ReactTags
    classNames={{
      tags: 'tagsClass',
      tagInput: 'tagInputClass',
      tagInputField: 'tagInputFieldClass',
      selected: 'selectedClass',
      tag: 'tagClass',
      remove: 'removeClass',
      suggestions: 'suggestionsClass',
      activeSuggestion: 'activeSuggestionClass',
      editTagInput: 'editTagInputClass',
      editTagInputField: 'editTagInputField',
      clearAll: 'clearAllClass',
    }}
    ...>

Support

If you like this library, you can support to help it improve:)

Github-sponsors

Dev

The component is written in ES6 and uses Webpack as its build tool.

Set up instructions

git clone [email protected]:react-tags/react-tags.git
cd react-tags
npm install
npm run precommit
npm run start

open http://localhost:8090/example

Contributing

Got ideas on how to make this better? Open an issue!

Thanks

The autocomplete dropdown is inspired by Lea Verou's awesomeplete library. The Drag and drop functionality is provided by Dan Abramov's insanely useful ReactDND library.

Also thanks to the awesome contributors who've made the library far better!

react-tags's People

Contributors

ad1992 avatar beeant avatar bitdivision avatar budaaaa avatar christowiz avatar cklab avatar dependabot-preview[bot] avatar dependabot[bot] avatar faizanu94 avatar greenkeeper[bot] avatar harshithmullapudi avatar itoldya avatar jandritsch avatar jkusachi avatar johnste avatar jpbufe3 avatar martynaszilinskas avatar mihaiserban avatar morzloof avatar mrdannael avatar not-raspberry avatar prakhar1989 avatar rnicholus avatar stefanfeser avatar tabrath avatar teldosas avatar tommoor avatar vkbansal avatar wildhoney avatar xonev 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-tags's Issues

How to hide suggestion onBlur?

When I add more than one react-tag-input I want to be able to hide suggestions when focus on another input. Is there already a way to do that?

Feedback by Dan Abramov

As reported here

  • It would look better if the currently dragged tag was slightly dimmed.
  • It would behave better if the tags were swapped only after the cursor has reached the half width of the tag it's over. You can use getBoundingClientRect inside the hover handler to do that calculation. Otherwise there's a flicker when moving items with different widths.
  • You probably want to provide a way to style the component.

Example not working

When I try to run the example with react 0.14 I get the following error:
Warning: DragDropContext(ReactTags)(...): React component classes must extend React.Component.
Uncaught Error: Invariant Violation: DragDropContext(ReactTags).render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

Am I missing a point?

Best

Inline Styling

Is it possible to perform inline styling? That doesn't appear to be the case. I think that would be hugely helpful.

Thanks

Feedback and requirements

1. Need option to validate tag, before add.
2. Need option to differentiate tags in color (Red for invalid tags). 
3. Need option to fetch suggestion data from server. May be, we need callback on tag onKeyUp event.
4. There is no option to edit tags. Currently we need to delete and add new tags. It would be better, you double click to edit.
5. Need option to select highlight tags on click event and  press delete key in input field if the input field empty.
6. Need option to allow duplicate.
7. Need navigation using left and right arrow to choose tags. After select tag, if we enter key, it will change to edit mode for correspondent tag like GMAIL to field.

make filteredSuggestions settable by user

It I have a list of suggestions like so:

cat
cats
cars
cards

And i start to type

a

then I will get a suggestion box with all 4 suggestions and the a characters underlined (marked).

If I then type ar 0 suggestions will render.

It I type car then 2 suggestions will render.

I would expect that any suggestion matching the input pattern would render, not just if the suggestion matches on the first characters.

how to set suggestions ID

now suggestions have no ID, they are only string. but they are from database, have ID, and will save ID.

like this:

    getInitialState: function() {
        return {
            tags: [ {id: 25, text: "Apples"} ],
            suggestions: [ {id: 12, text: "Banana"}, {id: 36, text: "Mango"}, {id: 41, text: "Pear"} ],
        }
    },

Fix API

Think how / what to expose in the API so that the component remains flexible and usable.

Tags Validation

Hi guys!

is there a way to validate the tag that the user wants to add?

Thanks,

Async suggestions

Use case: tag suggestions based on (potentially thousands of) tags used elsewhere.

I'm going to fork and implement this, is a PR for this acceptable? Is this api good?

<ReactTags
  tags={tags}
  suggestions={this.state.loading ? this.state.suggestions : []}

  loading={this.state.loading}
  loadingMessage="Loading..."
  onIncompleteInput={(text) => undefined}
  />

If loading is truthy, display an additional item at the end of the suggestions with the loading class.

Additional classes:

  • ReactTags__tagInput--loading
    • use case: spinner on right side of input
  • ReactTags__suggestions--loading
    • use case: change background color, etc.
  • ReactTags__loading-indicator
    • use case: style the loadingMessage (could be an icon or whatever).

Custom Tag Component

Hi,

Looks great! Can I pass a custom component as a prop to customise how tags are rendered?

I've like to embed a date-picker inside the tabs.

Thanks

Syntax error when requiring in the library

I'm getting the following error when adding the following line:

const ReactTags = require('react-tag-input').WithContext;
SyntaxError: Unexpected token {
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:413:25)
    at Object.Module._extensions..js (module.js:452:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/source/components/expedition/ExpeditionForm.tsx:5:19)

To give you a heads up our stack includes TypeScript. Any help would be great!

Thanks in advance

How can I make the tags not draggable?

Is there a way to make the tags not draggable? I'm looking to do something like:

<ReactTags draggable={false} ...>

Great library, thank you for sharing your work!

Allow this.props.onChange for API calls

Any chance this can be added to the input onChange handler? This would be nice to have so that the input can make API requests just in case suggestions are not already pre-loaded. If there is a better way to handle this type of request, please let me know. Thanks!

handleChange: function handleChange(e) {

        // Check if this.props.onChange exists
        if (this.props.onChange){
            this.props.onChange(e.target.value.trim())
        }
        var query = e.target.value.trim();
        var suggestions = this.props.suggestions.filter(function (item) {
            return item.toLowerCase().search(query.toLowerCase()) === 0;
        });

        this.setState({
            query: query,
            suggestions: suggestions
        });
    },

Jayr Camacho

a11y: tab key is ignored when in text input field

In the handleKeyDown function in reactTags.js, a delimiter key's default action is always prevented. The comment in the code mentions that this is in place to prevent delimiters from becoming part of the tag, which makes perfect sense. However, with the tab key as a delimiter, this prevents keyboard access to the document if the tag input field is focused. This is a significant accessibility issue. To fix this, I think tab characters need to be treated as special. In other words, in handleKeyDown, if the tab key has be pressed and it is a delimiter, only prevent the default action if the field is not empty (which seems to correspond to state.query). With an empty text input, the user can tab and shift-tab to navigate the document, as expected. With a non-empty text input, a tag will be created on tab/shift-tab, and then the next tab/shift-tab will allow the user to navigate the document again.

I'm happy to open up a PR, but wanted to get your thoughts on this solution first.

Correct spelling of "delimeters" prop to "delimiters"

The delimeters props is spelled incorrectly, and this led to a lot of confusion in figuring out why things weren't getting delimited with my custom delimiters.

I was passing in:

<ReactTags
    // ...my other props
    delimiters={ keyCodes } // delimiters spelled correctly because I didn't read closely enough
/>

The component expects:

<ReactTags
    // ...my other props
    delimeters={ keyCodes }
/>

Add animation on drag and drop and a ghost style for the item being dragged

Drag works great, but it looks incomplete from a UX point of view.

It would be great if:

  • There was a ghost style applied to the item being dragged (i.e. so that the user can see it is being dragged). This should be configurable.
  • Would be nice if there was an animation to that showed items re-sequence on drop.

Uncaught TypeError: Cannot set property 'value' of undefined

Thanks for this great component.

I'm encountering this error: "Uncaught TypeError: Cannot set property 'value' of undefined" in relation to

  // focus back on the input box
            input.value = "";
            input.focus();

in the addTag function.

Think this may be because of

var input = this.refs.input;

as I'm also getting this error: "Uncaught Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method,"

Thanks

npm-version is outdated

npm shows 1.0.3 as the latest release. But package.json specifies version 2.0.1.

Could you publish a new version to npm?

Warning: Each child in an array or iterator should have a unique "key" prop

I encountered this problem when I'm trying to add new fresh tags (for example the tags is not saved in database, they don't have tag id)

So I'm thinking if we can add:

{tag.id || i}

in here
https://github.com/prakhar1989/react-tags/blob/master/lib/reactTags.js#L188

I can add tag.id to all the new fresh tags, but I have to clean it back when sending them to the server. Because if I don't it will have conflict with the existing tags with same id.

Thank You

v2.2.6 shouldRenderSuggestions renders when query length is smaller

Small problem in v2.2.6:

shouldRenderSuggestions: function (query) { var props = this.props; var minQueryLength = props.minQueryLength || 2; return (props.query.length < minQueryLength); },

this renders suggestions when the query length is smaller than minQueryLength, while it should be bigger
this also breaks other things, such as all suggestions showing on the initial state

Automatically choose option on trigger key (enter/tab/etc) if only one suggestion matches

During integration of react-tags into our app at Widen, we had a requirement that a proposed tag should be accepted as the matching suggestion if only one match can be found. This would happen when the user hits enter or tab or whatever the trigger key is set to. For example:

  1. Suggestions of "one, two, three"
  2. User starts to type "th"
  3. User hits enter.
  4. Tag is persisted as "three".

This mirrors behavior of other in-the-wild tagging systems, such as what you might see on Slack.

I realize that this should probably not be the default behavior for a library like this, but perhaps as an option? Just asking if you are interested in a PR will this code. If so, I'm interested in what thoughts you might have regarding how this feature should be enabled.

If you are not interested, no big deal. We have implemented this in our wrapper of react-tags.

Read only view

Is there a way to show the tags without the edit mode? Like i do not want to show a delete x or input field to add more tags. Just want to list my tags.

Prevent Delete on Text Input Delete

With some updates to the CSS, one is able to do a 'stacked' approach of the tags rather than have the tags inline with the input field.

screenshot 2015-09-17 10 19 08

In this case however, and tags exist, pressing the "Delete" key on an empty Input Box will delete the most recently added Tag. This is not always desired.

Suggestion: add a property allowDeleteFromInput that has either true or false that controls this.

I can create a PR if you'd like

Suggestion box is always visible

Hi , I am using this library and facing the issue, that the suggestion box is always visible even after selected the data, apart from this everything is working fine. I have also notice that "data-reactid" is not generating in my case because I am using react-dom - 15.0.1 in which no more "data-reactid" will be there. Can any one suggest how to solve this problem. Thank you in advance

Allow to pass style classes as input

Consider something like

<ReactTags
   ...
   classes = {{
      input: 'some-input-class',
      tagInput: 'some-other-class'
   }}
/>

I think it would make it much easier to integrated into existing projects that have existing UI packages in place

Problem with requires on case sensitive OS

Since this commit, I got these errors:

ERROR in ./~/react-tag-input/dist-modules/reactTags.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./tag in node_modules/react-tag-input/dist-modules
 @ ./~/react-tag-input/dist-modules/reactTags.js 5:10-26

ERROR in ./~/react-tag-input/dist-modules/reactTags.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./suggestions in node_modules/react-tag-input/dist-modules
 @ ./~/react-tag-input/dist-modules/reactTags.js 6:18-42

Which is normal because Tag.js and Suggestions.js files are uppercase.

Show suggestions onKeyPress

Hi guys,

I wanted to know if there is a way to show the suggestions when the user press key down.

Thanks in advance.

Use lowercase 'react' in require

Webpack goes bananas because of the difference in the way people would normally require modules (lowercase based on the package name) and the way you require it ('React').

Getting this error on npm install - 5621 error peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!

I am getting this error.

5618 error node v4.4.4
5619 error npm v2.15.1
5620 error code EPEERINVALID
5621 error peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
5621 error peerinvalid Peer [email protected] wants react@>=0.14.0
5621 error peerinvalid Peer [email protected] wants react@^15.0.2
5621 error peerinvalid Peer [email protected] wants react@^0.14.0 || ^15.0.0-0
5621 error peerinvalid Peer [email protected] wants react@^15.0.2
5621 error peerinvalid Peer [email protected] wants react@^0.14.0
5621 error peerinvalid Peer [email protected] wants react@^0.14.0 || ^15.0.0-0
5621 error peerinvalid Peer [email protected] wants react@^0.14.0 || ^15.0.0
5621 error peerinvalid Peer [email protected] wants react@^0.14.3 || ^15.0.1
5622 verbose exit [ 1, true ]

API suggestions

Hey! This is a great library, but I have two suggestions on how we might change the API

  1. handleAddition and handleDelete should be passed the complete set of tags
  2. suggestions should use the same object format {id: ..., text: ...} as the tags themselves.

Let me elaborate on each one:

handleAddition and handleDelete should be passed the complete set of tags

It seems odd to me that the state of the set of tags is "externalized" from this component. My thought is that the library should pass the current set of tags to both of these callbacks. The component already knows the set and it alleviates the consumer of this library from being forced to splice and push on a tags array. (We could add it as the second argument if we want to maintain API backwards compatibility. )

suggestions should use the same object format {id: ..., text: ...} as the tags themselves.

I don't quite understand why the suggestions aren't allowed to have ids. Presumably these tags have ids in an external system and if someone uses a suggestion we'd want to reuse those ids. Furthermore, there is a nice API symmetry to having both tags and suggestions use the same format.

Thanks for your work on this library!

Showing all items

Could you please fix, if I set minQueryLength to 1, on click in the enter area, It would automatically show all the suggestions? Thanks

Add Release

Since Github supports releases, I think it would be good to add them for this repo

Currently releases tab is like the following, even though npm states its 1.0.3 (latest of 11 releases):

screenshot 2015-11-05 11 25 12

Draggability Options

An option to disable draggability would be useful for different implementations.

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.