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.
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/