React JS Tags component

I was looking for some light weight Tags component found Tagify to be interesting. But then figured out it got many features which I will not use. So I wanted to create something very minimalist. I found athe following article to follow as I wanted save time while creating this.

https://jerrylowm.medium.com/build-a-tags-input-react-component-from-scratch-1524f02acb9a

But that article was using React component classes as the article is written 3 years back. For reducing the generate code size I also wanted to change to Functional Component. Here I am giving the final code base for any one want to use it.

The Tag Input Functional Component

Tag Input Code – Tag.tsx

import React, { useState, useRef } from "react";
import { FormFieldType } from "../interface";

import "./tags.scss";

const Tags = (props: { item: FormFieldType }) => {
  const [tags, setTags] = useState(props.item.tags);
  const tagInput = useRef(null);

  const removeTag = (i) => {
    const newTags = [...tags];
    newTags.splice(i, 1);
    setTags(newTags);
  };

  const inputKeyDown = (e) => {
    const val = e.target.value;
    if (e.key === "Enter" && val) {
      if (tags.find((tag) => tag.toLowerCase() === val.toLowerCase())) {
        return;
      }

      setTags([...tags, val]);
      tagInput.current.value = null;
    } else if (e.key === "Backspace" && !val) {
      removeTag(tags.length - 1);
    }
  };

  return (
    <div className="input-tag">
      <ul className="input-tag__tags">
        {tags.map((tag, i) => (
          <li key={tag}>
            {tag}
            <button
              type="button"
              onClick={() => {
                removeTag(i);
              }}
            >
              +
            </button>
          </li>
        ))}
        <li className="input-tag__tags__input">
          <input type="text" onKeyDown={inputKeyDown} ref={tagInput} />
        </li>
      </ul>
    </div>
  );
};

export default Tags;

Interface code – FormFieldType.ts

export interface FormFieldType  {
  tags?:Array<string>
};

Style sheet code – tags.scss

.input-tag {
    background: white;
    border: 1px solid #d6d6d6;
    border-radius: 2px;
    display: flex;
    flex-wrap: wrap;
    padding: 5px 5px 0;
}

.input-tag input {
    border: none;
    width: 100%;
}

.input-tag__tags {
    display: inline-flex;
    flex-wrap: wrap;
    margin: 0;
    padding: 0;
    width: 100%;
}

.input-tag__tags li {
    align-items: center;
    background: #85A3BF;
    border-radius: 2px;
    color: white;
    display: flex;
    font-weight: 300;
    list-style: none;
    margin-bottom: 5px;
    margin-right: 5px;
    padding: 5px 10px;
}

.input-tag__tags li button {
    align-items: center;
    appearance: none;
    background: #333333;
    border: none;
    border-radius: 50%;
    color: white;
    cursor: pointer;
    display: inline-flex;
    font-size: 12px;
    height: 15px;
    justify-content: center;
    line-height: 0;
    margin-left: 8px;
    padding: 0;
    transform: rotate(45deg);
    width: 15px;
}

.input-tag__tags li.input-tag__tags__input {
    background: none;
    flex-grow: 1;
    padding: 0;
}

Hope this helped you on your latest project. Credits goes to Jerry Low for the original tutorial. https://jerrylowm.medium.com/

Leave a Comment