Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/kokonut-labs/kokonutui/llms.txt

Use this file to discover all available pages before exploring further.

A React hook that manages a collection of tags with automatic color assignment, maximum tag limits, and easy add/remove functionality.

Installation

Manually copy the hook from /hooks/use-tags.ts into your project.

Usage

import { useTags } from "@/hooks/use-tags";

function TagInput() {
  const { tags, addTag, removeTag, hasReachedMax } = useTags({
    maxTags: 5,
  });

  const handleAddTag = () => {
    addTag({
      id: Date.now().toString(),
      label: "New Tag",
    });
  };

  return (
    <div>
      <div className="flex flex-wrap gap-2">
        {tags.map(tag => (
          <div key={tag.id} className={tag.color}>
            {tag.label}
            <button onClick={() => removeTag(tag.id)}>×</button>
          </div>
        ))}
      </div>
      <button onClick={handleAddTag} disabled={hasReachedMax}>
        Add Tag
      </button>
    </div>
  );
}

API Reference

Parameters

The hook accepts a configuration object:
ParameterTypeDefaultDescription
onChange(tags: Tag[]) => voidundefinedCallback fired when tags change
defaultTagsTag[][]Initial tags
maxTagsnumber10Maximum number of tags allowed
defaultColorsstring[]See belowArray of Tailwind classes for tag colors

Tag Type

interface Tag {
  id: string;
  label: string;
  color?: string;
}

Default Colors

The hook includes 5 default color schemes:
  • Blue: bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300
  • Purple: bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300
  • Green: bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300
  • Yellow: bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300
  • Red: bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-900

Return Value

Returns an object with:
PropertyTypeDescription
tagsTag[]Current array of tags
setTags(tags: Tag[]) => voidSet tags directly
addTag(tag: Tag) => Tag[] | undefinedAdd a new tag, returns updated array or undefined if max reached
removeTag(tagId: string) => Tag[]Remove tag by ID, returns updated array
removeLastTag() => Tag[] | undefinedRemove the last tag
hasReachedMaxbooleanWhether max tag limit has been reached

Features

  • Automatic color cycling - Colors automatically assigned from default palette
  • Max tag limit - Prevents adding more tags than allowed
  • Change callbacks - Get notified when tags change
  • Keyboard support - removeLastTag for backspace handling
  • Dark mode support - Default colors include dark mode variants

Example: Tag Input with Keyboard

function SmartTagInput() {
  const [input, setInput] = useState("");
  const { tags, addTag, removeLastTag } = useTags({
    maxTags: 10,
    onChange: (tags) => console.log("Tags changed:", tags),
  });

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && input.trim()) {
      e.preventDefault();
      addTag({
        id: Date.now().toString(),
        label: input.trim(),
      });
      setInput("");
    } else if (e.key === "Backspace" && !input) {
      removeLastTag();
    }
  };

  return (
    <div className="flex flex-wrap gap-2 p-2 border rounded">
      {tags.map(tag => (
        <span key={tag.id} className={`px-2 py-1 rounded ${tag.color}`}>
          {tag.label}
        </span>
      ))}
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={handleKeyDown}
        className="flex-1 outline-none"
        placeholder="Add a tag..."
      />
    </div>
  );
}

Example: Custom Colors

function CustomColorTags() {
  const { tags, addTag } = useTags({
    defaultColors: [
      "bg-rose-100 text-rose-700",
      "bg-sky-100 text-sky-700",
      "bg-emerald-100 text-emerald-700",
    ],
  });

  return (
    <div>
      {tags.map(tag => (
        <span key={tag.id} className={tag.color}>
          {tag.label}
        </span>
      ))}
    </div>
  );
}

Example: Controlled Tags

function ControlledTags() {
  const { tags, setTags, addTag, removeTag } = useTags();

  const handleImportTags = () => {
    setTags([
      { id: "1", label: "React" },
      { id: "2", label: "TypeScript" },
      { id: "3", label: "Tailwind" },
    ]);
  };

  const handleClearAll = () => {
    setTags([]);
  };

  return (
    <div>
      <button onClick={handleImportTags}>Import Tags</button>
      <button onClick={handleClearAll}>Clear All</button>
      {/* Render tags */}
    </div>
  );
}

Use Cases

  • Tag input components for forms
  • Category selection interfaces
  • Skill or technology selectors
  • Email recipient chips (like Gmail)
  • Filter tag management
  • Multi-select with visual feedback

Color Assignment

Colors are assigned automatically in a round-robin fashion:
  • Tag 1: First color
  • Tag 2: Second color
  • Tag 6: First color again (cycles)
You can override by passing a color property when adding a tag.

Notes

  • All functions return the updated tags array for chaining
  • addTag returns undefined if max tags reached
  • removeLastTag returns undefined if no tags exist
  • Default colors include dark mode support with Tailwind dark: prefix
  • IDs must be unique strings

Build docs developers (and LLMs) love