({ unique = false })
| 8 | } |
| 9 | |
| 10 | const TagInput: React.FC<TagInputProps> = ({ unique = false }) => { |
| 11 | const [keywords, setKeywords] = useState<string[]>(['ansub', 'syntax']) |
| 12 | |
| 13 | const onKeywordsChange = (newKeywords: string[]) => { |
| 14 | setKeywords(newKeywords) |
| 15 | // Additional actions upon keywords change can be handled here |
| 16 | } |
| 17 | const [inputValue, setInputValue] = useState<string>('') |
| 18 | |
| 19 | // Handles adding new keyword on Enter or comma press, and keyword removal on Backspace |
| 20 | const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { |
| 21 | if ( |
| 22 | (event.key === 'Enter' || event.key === ',') && |
| 23 | inputValue.trim() !== '' |
| 24 | ) { |
| 25 | event.preventDefault() |
| 26 | const newKeyword = inputValue.trim() |
| 27 | const newKeywords = unique |
| 28 | ? [...new Set([...keywords, newKeyword])] |
| 29 | : [...keywords, newKeyword] |
| 30 | |
| 31 | setKeywords(newKeywords) |
| 32 | onKeywordsChange(newKeywords) |
| 33 | setInputValue('') |
| 34 | } else if (event.key === 'Backspace' && inputValue === '') { |
| 35 | event.preventDefault() |
| 36 | const newKeywords = keywords.slice(0, -1) |
| 37 | setKeywords(newKeywords) |
| 38 | onKeywordsChange(newKeywords) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | // Handles pasting keywords separated by commas, new lines, or tabs |
| 43 | const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => { |
| 44 | event.preventDefault() |
| 45 | const paste = event.clipboardData.getData('text') |
| 46 | const keywordsToAdd = paste |
| 47 | .split(/[\n\t,]+/) |
| 48 | .map((keyword) => keyword.trim()) |
| 49 | .filter(Boolean) |
| 50 | if (keywordsToAdd.length) { |
| 51 | const newKeywords = unique |
| 52 | ? [...new Set([...keywords, ...keywordsToAdd])] |
| 53 | : [...keywords, ...keywordsToAdd] |
| 54 | |
| 55 | setKeywords(newKeywords) |
| 56 | onKeywordsChange(newKeywords) |
| 57 | setInputValue('') |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | // Updates the inputValue state as the user types |
| 62 | const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { |
| 63 | setInputValue(event.target.value) |
| 64 | } |
| 65 | // Adds the keyword when the input loses focus, if there's a keyword to add |
| 66 | const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => { |
| 67 | if (inputValue.trim() !== '' && event.relatedTarget?.tagName !== 'BUTTON') { |
nothing calls this directly
no test coverage detected