<!-- source-hash: 4570f165151567924d10e97102adf2d3 -->
A full-featured tag management component that provides a searchable, multi-select tag picker with inline create, edit, and delete capabilities via a popover dropdown.

## Key Components

### Interfaces
- **`TagItem`** — Shape of a tag object: `{ id, name, color? }`
- **`TagsManagerProps`** — Full prop contract for the component, including async CRUD callbacks and loading states

### Component
- **`TagsManager`** — The primary exported component; renders a label-anchored popover with a chip-style multi-select input and a scrollable tag list

### Internal Behaviors
- `toggleTag` — Adds or removes a tag ID from the selection
- `handleCreate` — Calls `onCreateTag`, auto-selects the result, and clears search
- `startEdit` / `confirmEdit` / `cancelEdit` — Inline row-level edit flow
- `handleDelete` — Calls `onDeleteTag` and removes the ID from selection if present
- `handleClearAll` — Resets all selected IDs and clears the search input

## Usage Example

```typescript
import { TagsManager, TagItem } from "@/components/ui/tags-manager";

const allTags: TagItem[] = [
  { id: "1", name: "Bug" },
  { id: "2", name: "Feature" },
  { id: "3", name: "Urgent" },
];

function TicketForm() {
  const [selectedIds, setSelectedIds] = React.useState<string[]>(["1"]);

  return (
    <TagsManager
      tags={allTags}
      selectedIds={selectedIds}
      onChange={setSelectedIds}
      onCreateTag={async (name) => {
        const created = await api.tags.create({ name });
        return created; // must return TagItem
      }}
      onUpdateTag={async (id, name) => {
        await api.tags.update(id, { name });
      }}
      onDeleteTag={async (id) => {
        await api.tags.delete(id);
      }}
      label="Ticket Tags"
      searchPlaceholder="Search tags..."
    />
  );
}
```

**Key behaviours to note:**
- Pressing `Backspace` on an empty search removes the last selected tag
- Pressing `Enter` while typing a new (non-existing) name triggers `onCreateTag`
- Edit/delete action buttons appear on row hover and are hidden otherwise
- The popover stays open while interacting inside the anchor container