Input
Tags Input
Below are some key features:
Enter, Comma and NumpadEnter adds input in the list.
Backspace removes last element from the list.
Preview
- React.Js
- Next.Js
Code
./src/components/ashokasec-ui/input/tags-input.tsx
"use client"
import { Plus } from 'lucide-react'
import React, { memo, useState } from 'react';
export interface PillsItemProps {
item: string;
removable?: boolean;
onRemove?: () => void;
}
const PillsListItem: React.FC<PillsItemProps> = ({ item, removable, onRemove }) => {
return (
<li className={`rounded-full leading-none px-4 py-2 h-fit border border-algae ${removable ? "flex items-center justify-center pr-2" : "pr-4"}`}>
{item}
{removable &&
<span
className='rotate-45 ml-2 text-gray-500 rounded-full bg-transparent border border-transparent cursor-pointer hover:border-red-500 hover:bg-red-500/20 hover:text-red-500 transition-all'
onClick={onRemove}
>
<Plus size={18} />
</span>
}
</li>
);
};
const MemoizedPillsListItem = memo(PillsListItem);
MemoizedPillsListItem.displayName = "PillsListItem";
interface PillsListProps {
data: string[];
removable?: boolean;
onRemove?: (index: number) => void;
}
const PillsList: React.FC<PillsListProps> = ({ data, removable, onRemove }) => {
const [inputValue, setInputValue] = useState("")
const [dataList, setDataList] = useState<string[]>(data || [])
const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
const key_value = e.code
if (key_value === "Enter" || key_value === "Comma" || key_value === "NumpadEnter") {
if (inputValue && inputValue !== "") {
const refinedValue = inputValue.trim().replaceAll(",", "")
setDataList((prevData) => [...prevData, refinedValue])
setInputValue("")
}
}
else if (key_value === "Backspace" && inputValue === null) {
setDataList((prevData) => prevData.slice(0, -1))
}
}
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault()
setInputValue(e.target.value)
}
return (
<ul className='flex flex-wrap items-center space-x-3 space-y-3 relative -left-2 -top-2'>
<li></li>
{dataList?.map((item, index) => (
<PillsListItem
item={item}
removable={removable}
key={index}
onRemove={() => onRemove && onRemove(index)}
/>
))}
<input type="text" className='rounded-full leading-none px-4 py-2 h-fit border border-algae font-light outline-none bg-gray-400/15' spellCheck="false" placeholder='Add a fruit...' value={inputValue} onChange={handleInputChange} onKeyUp={handleKeyUp} />
</ul>
);
};
export default PillsList;
Usage Code
./whatever/form.tsx
"use client"
import { Plus } from 'lucide-react'
import React, { memo, useState } from 'react';
export interface PillsItemProps {
item: string;
removable?: boolean;
onRemove?: () => void;
}
const PillsListItem: React.FC<PillsItemProps> = ({ item, removable, onRemove }) => {
return (
<li className={`rounded-full leading-none px-4 py-2 h-fit border border-algae ${removable ? "flex items-center justify-center pr-2" : "pr-4"}`}>
{item}
{removable &&
<span
className='rotate-45 ml-2 text-gray-500 rounded-full bg-transparent border border-transparent cursor-pointer hover:border-red-500 hover:bg-red-500/20 hover:text-red-500 transition-all'
onClick={onRemove}
>
<Plus size={18} />
</span>
}
</li>
);
};
const MemoizedPillsListItem = memo(PillsListItem);
MemoizedPillsListItem.displayName = "PillsListItem";
interface PillsListProps {
data: string[];
removable?: boolean;
onRemove?: (index: number) => void;
}
const PillsList: React.FC<PillsListProps> = ({ data, removable, onRemove }) => {
const [inputValue, setInputValue] = useState("")
const [dataList, setDataList] = useState<string[]>(data || [])
const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
const key_value = e.code
if (key_value === "Enter" || key_value === "Comma" || key_value === "NumpadEnter") {
if (inputValue && inputValue !== "") {
const refinedValue = inputValue.trim().replaceAll(",", "")
setDataList((prevData) => [...prevData, refinedValue])
setInputValue("")
}
}
else if (key_value === "Backspace" && inputValue === null) {
setDataList((prevData) => prevData.slice(0, -1))
}
}
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault()
setInputValue(e.target.value)
}
return (
<ul className='flex flex-wrap items-center space-x-3 space-y-3 relative -left-2 -top-2'>
<li></li>
{dataList?.map((item, index) => (
<PillsListItem
item={item}
removable={removable}
key={index}
onRemove={() => onRemove && onRemove(index)}
/>
))}
<input type="text" className='rounded-full leading-none px-4 py-2 h-fit border border-algae font-light outline-none bg-gray-400/15' spellCheck="false" placeholder='Add a fruit...' value={inputValue} onChange={handleInputChange} onKeyUp={handleKeyUp} />
</ul>
);
};
export default PillsList;
Pushing Pixel Updates in Public
Namaste from ashokasec