index.tsx
Overview
This file defines a reusable React functional component named EditTag that provides an editable tag list UI. Users can add new tags by typing them into an input field and remove existing tags by clicking a close icon next to each tag. The component supports multiple tags separated by semicolons during input and uses animated transitions for tag addition and removal. It integrates UI elements from Ant Design Icons, rc-tween-one for animation, and custom UI components such as buttons, inputs, and hover cards.
The primary purpose of this file is to enable tag editing functionality within a form or user interface, allowing other components to control the tag list via props and receive updates through callbacks.
Detailed Explanation
Interfaces
EditTagsProps
Description: Props interface for the
EditTagcomponent.Properties:
value?: string[]
An optional array of string tags representing the current list of tags.onChange?: (tags: string[]) => void
An optional callback function triggered when the tag list changes (on add or remove). It receives the updated array of tags.
Component: EditTag
A React functional component wrapped with React.forwardRef to allow parent components to access its DOM node if needed.
const EditTag = React.forwardRef<HTMLDivElement, EditTagsProps>(
({ value = [], onChange }: EditTagsProps, ref) => { ... }
);
Props
value(optional): Current list of tags.onChange(optional): Callback to notify parent components of tag changes.
State Variables
inputVisible: boolean
Controls whether the input field for adding tags is visible.inputValue: string
Stores the current value of the input field.inputRef: React.RefObject<HTMLInputElement>
Ref to the input element to control focus.
Lifecycle
Uses
useEffectto automatically focus the input element when it becomes visible.
Methods
handleClose(removedTag: string): void
Removes a tag from the list and triggersonChangewith the updated tags.showInput(): void
Sets the input field visible to allow adding a new tag.handleInputChange(e: React.ChangeEvent<HTMLInputElement>): void
UpdatesinputValuestate as the user types.handleInputConfirm(): void
When the input is confirmed (on blur or pressing Enter), splits the input string by semicolons (;), trims whitespace, filters out duplicates or empty tags, appends new tags to the list, triggersonChangecallback, then hides the input and clearsinputValue.forMap(tag: string): JSX.Element
Returns JSX for rendering a single tag with a hover card and a close (X) icon. Clicking the close icon removes the tag.
Render Logic
When
inputVisibleis true, renders an<Input>component where users can type new tags. The input auto-focuses and listens forEnterkey and blur events to confirm input.When
inputVisibleis false, renders a dashed-button with a plus icon (PlusOutlined) to allow showing the input.Renders existing tags using the
forMapfunction wrapped inside aTweenOneGroupcomponent to animate tag appearance and removal.
Usage Example
import React, { useState } from 'react';
import EditTag from './index';
function TagEditor() {
const [tags, setTags] = useState(['react', 'typescript']);
return (
<EditTag
value={tags}
onChange={(newTags) => setTags(newTags)}
/>
);
}
Implementation Details and Algorithms
Tag Addition:
The component accepts multiple tags input separated by semicolons (;). Upon confirmation, it splits the input string, trims whitespace, removes duplicates (compared to existing tags), and adds new tags to the list.Tag Removal:
Clicking the close icon next to a tag removes it from the list.Animations:
UsesTweenOneGroupfromrc-tween-oneto animate tags entering and leaving the view with scale and opacity transitions. This improves UX by visually indicating changes.Hover Cards:
Each tag is wrapped in aHoverCardcomponent, which shows the full tag text on hover to handle long tags gracefully with ellipsis truncation.Focus Management:
The input for adding tags automatically receives focus when shown, improving usability.
Interaction with Other Parts of the System
UI Components:
Uses
Button,Input, andHoverCardcomponents from the local UI library (../ui/button,../ui/input,../ui/hover-card).Uses icons from
@ant-design/icons(PlusOutlined) andlucide-react(X).
Animation Library:
Utilizesrc-tween-onefor animated transitions of tags.Parent Components:
TheEditTagcomponent is designed to be controlled externally via thevalueandonChangeprops, allowing integration into forms or any UI that requires tag editing functionality.
Mermaid Component Diagram
componentDiagram
component EditTag {
+props: EditTagsProps
+state: inputVisible: boolean
+state: inputValue: string
+handleClose(removedTag: string): void
+showInput(): void
+handleInputChange(e): void
+handleInputConfirm(): void
+forMap(tag: string): JSX.Element
}
component Button
component Input
component HoverCard
component TweenOneGroup
component PlusOutlinedIcon
component XIcon
EditTag --> Button : renders
EditTag --> Input : renders conditionally
EditTag --> HoverCard : wraps tags
EditTag --> TweenOneGroup : animates tags
EditTag --> PlusOutlinedIcon : inside Button
EditTag --> XIcon : close icon on tags
Summary
The index.tsx file provides a highly customizable, animated React tag editor component. It handles multi-tag input, tag removal, and smooth UI transitions, making it suitable for tag management in forms or content editing interfaces. Its integration with local design system components and third-party icon and animation libraries ensures consistency and usability within the larger application ecosystem.