macOS Finder-like Tagging System in JavaScript – colortag.js

Category: Javascript | June 16, 2025
Authorroromedia
Last UpdateJune 16, 2025
LicenseMIT
Tags
Views67 views
macOS Finder-like Tagging System in JavaScript – colortag.js

colortag.js is a lightweight JavaScript-powered tagging system library that adds macOS Finder-inspired, color-coded tagging functionality to HTML elements.

It can be useful in web applications where users need to categorize, prioritize, or visually organize content items.

Features:

  • Customizable color palettes (use named colors or hex values)
  • Touch-friendly interface with distinct desktop hover effects
  • Event hooks: tagAdded and tagRemoved for backend integration
  • Set initial tags declaratively using data-initial-tags
  • Target specific elements for tagging via CSS selectors
  • Automatic creation of tag container elements if they don’t exist
  • Clean, modern UI using SVG-based icons

How to use it:

1. Download and import colortag.js into your web project.

<link rel="stylesheet" href="css/style.css">
<script src="js/colortag.js"></script>

2. Create HTML elements that you want to make taggable. At a minimum, they need a class (default is taggable-item) and an inner div (default class item-tags) to hold the applied tags.

<div class="taggable-item" id="my-item-1">
  <p>This is the first item I want to tag.</p>
  <div class="item-tags"></div>
</div>
<div class="taggable-item" id="my-item-2" data-initial-tags="Red, #00FF00">
  <p>This item comes with pre-defined tags (Red and a green one).</p>
  <div class="item-tags"></div>
</div>

3. Initialize the library after the DOM is ready:

document.addEventListener('DOMContentLoaded', () => {
  const colorTag = new ColorTag();
  colorTag.init(); // Initializes all elements with 'taggable-item' class
});

4. Available options to customize the tags.

  • colors: An array of color definitions. Each can be a string (hex value, e.g., '#FF0000') or an object ({ name: 'Ruby', color: '#FF0000' }). If you provide only hex values, names are auto-generated.
  • taggableItemClass: Default is 'taggable-item'. Change this if you use a different class for your items.
  • itemTagsClass: Default is 'item-tags'. Change this for the inner tag container.
const colorTag = new ColorTag({
  colors: [
    { name: 'Urgent', color: '#D9534F' },
    { name: 'Pending', color: '#F0AD4E' },
    // ...
  ],
  taggableItemClass: `'taggable-item',
  itemTagsClass: 'item-tags'
});

5. Available parameters for the init() method.

colorTag.init(selectorOrOptions = null, colors = null);
colorTag.init({
  selector: '.document-section .file',
  colors: ['#FF0000', '#00FF00', '#0000FF']
});
colorTag.init('.task-list .task', [
  { name: 'P1', color: '#FF4136' },
  { name: 'P2', color: '#FF851B' }
]);

6. The tagAdded event fires immediately after a user successfully applies a new color tag to an item by selecting a color from the palette. It’s important to note this event does not fire for tags that are present initially through the data-initial-tags attribute when init() is called; it’s specifically for user-driven additions.

// Subscribe to the tagAdded event
colorTag.on('tagAdded', (data) => {
  console.group('tagAdded Event Details:'); // Group console logs for clarity
  console.log('Item Element:', data.itemElement);
  console.log('Item ID:', data.itemId);
  console.log('Newly Added Tag Element:', data.tagElement);
  console.log('Applied Color (Hex):', data.color);
  console.log('Applied Color Name:', data.colorName);
  console.log('Timestamp:', data.timestamp);
  console.groupEnd();
  // Send data to your backend
  // Example:
  // fetch(`/api/items/${data.itemId}/tags`, {
  //     method: 'POST',
  //     headers: { 'Content-Type': 'application/json' },
  //     body: JSON.stringify({
  //         colorName: data.colorName,
  //         colorHex: data.color,
  //         action: 'add'
  //     })
  // })
  // .then(response => response.json())
  // .then(result => console.log('Backend update result:', result))
  // .catch(error => console.error('Error updating backend:', error));
  alert(`Tag "${data.colorName}" added to item "${data.itemId}"! Check the console.`);
});

7. The tagRemoved event fires when a user removes an existing tag from an item.

// Subscribe to the tagRemoved event
ColorTag.on('tagRemoved', (data) => {
  console.group('tagRemoved Event Details:');
  console.log('Item Element:', data.itemElement);
  console.log('Item ID:', data.itemId);
  console.log('Removed Color (Hex):', data.color);
  console.log('Removed Color Name:', data.colorName);
  console.log('Timestamp:', data.timestamp);
  console.groupEnd();
  // Notify your backend of the removal
  // Example:
  // fetch(`/api/items/${data.itemId}/tags`, {
  //     method: 'POST', // Or DELETE, depending on your API design
  //     headers: { 'Content-Type': 'application/json' },
  //     body: JSON.stringify({
  //         colorName: data.colorName,
  //         action: 'remove'
  //     })
  // })
  // .then(response => response.json())
  // .then(result => console.log('Backend update result (removal):', result))
  // .catch(error => console.error('Error updating backend for removal:', error));
  alert(`Tag "${data.colorName}" removed from item "${data.itemId}"! Check the console.`);
});

Changelog:

06/16/2025

  • Fix color processing for color-only objects

You Might Be Interested In:


Leave a Reply