Tag

Component

Interactive examples and API documentation

Basic
Basic usage of Tag. Closable tags support onClose events.
Tag 1 Link Tag 2 Custom Close
Code
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new do %>Tag 1<% end %>
  <%= render HakumiComponents::Tag::Component.new do %>
    <% render HakumiComponents::Icon::Component.new(name: "link") %>
    Link
  <% end %>
  <%= render HakumiComponents::Tag::Component.new(closable: true) do %>Tag 2<% end %>
  <%= render HakumiComponents::Tag::Component.new(closable: true, close_icon: "close-circle") do %>Custom Close<% end %>
<% end %>
Colorful Tag
Preset colors and custom hex colors for different situations.
Preset Colors
magenta red volcano orange gold lime green cyan blue geekblue purple
Custom Colors
#f50 #2db7f5 #87d068 #108ee9
Code
<%= render HakumiComponents::Typography::Title::Component.new(level: 5) do %>Preset Colors<% end %>
<%= render HakumiComponents::Space::Component.new(wrap: true) do %>
  <% %i[magenta red volcano orange gold lime green cyan blue geekblue purple].each do |color| %>
    <%= render HakumiComponents::Tag::Component.new(color: color) do %><%= color %><% end %>
  <% end %>
<% end %>

<%= render HakumiComponents::Divider::Component.new %>

<%= render HakumiComponents::Typography::Title::Component.new(level: 5) do %>Custom Colors<% end %>
<%= render HakumiComponents::Space::Component.new(wrap: true) do %>
  <%= render HakumiComponents::Tag::Component.new(color: "#f50") do %>#f50<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: "#2db7f5") do %>#2db7f5<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: "#87d068") do %>#87d068<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: "#108ee9") do %>#108ee9<% end %>
<% end %>
Status Tag
Five preset status colors: success, processing, error, default, and warning.
success processing error warning default
Code
<%= render HakumiComponents::Space::Component.new(wrap: true) do %>
  <%= render HakumiComponents::Tag::Component.new(color: :success) do %>success<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :processing) do %>processing<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :error) do %>error<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :warning) do %>warning<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :default) do %>default<% end %>
<% end %>
Checkable Tag
CheckableTag works like a checkbox - click to toggle checked state.
Movies Books Music Sports
Code
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new(checkable: true, checked: true) do %>Movies<% end %>
  <%= render HakumiComponents::Tag::Component.new(checkable: true) do %>Books<% end %>
  <%= render HakumiComponents::Tag::Component.new(checkable: true) do %>Music<% end %>
  <%= render HakumiComponents::Tag::Component.new(checkable: true, checked: true) do %>Sports<% end %>
<% end %>
Icon
Tags with icons using the icon slot.
X YouTube Facebook LinkedIn
Code
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new(color: :cyan) do |tag| %>
    <% tag.with_icon do %>
      <%= render HakumiComponents::Icon::Component.new(name: "x") %>
    <% end %>
    X
  <% end %>

  <%= render HakumiComponents::Tag::Component.new(color: :blue) do |tag| %>
    <% tag.with_icon do %>
      <%= render HakumiComponents::Icon::Component.new(name: "youtube") %>
    <% end %>
    YouTube
  <% end %>

  <%= render HakumiComponents::Tag::Component.new(color: :geekblue) do |tag| %>
    <% tag.with_icon do %>
      <%= render HakumiComponents::Icon::Component.new(name: "facebook") %>
    <% end %>
    Facebook
  <% end %>

  <%= render HakumiComponents::Tag::Component.new(color: :purple) do |tag| %>
    <% tag.with_icon do %>
      <%= render HakumiComponents::Icon::Component.new(name: "linkedin") %>
    <% end %>
    LinkedIn
  <% end %>
<% end %>
Variants
Different visual variants: filled (default), outlined, and borderless.
Filled (Default)
Tag Magenta Success
Outlined
Tag Magenta Success
Borderless
Tag Magenta Success
Code
<%= render HakumiComponents::Typography::Title::Component.new(level: 5) do %>Filled (Default)<% end %>
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new do %>Tag<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :magenta) do %>Magenta<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :success) do %>Success<% end %>
<% end %>

<%= render HakumiComponents::Divider::Component.new %>

<%= render HakumiComponents::Typography::Title::Component.new(level: 5) do %>Outlined<% end %>
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new(variant: :outlined) do %>Tag<% end %>
  <%= render HakumiComponents::Tag::Component.new(variant: :outlined, color: :magenta) do %>Magenta<% end %>
  <%= render HakumiComponents::Tag::Component.new(variant: :outlined, color: :success) do %>Success<% end %>
<% end %>

<%= render HakumiComponents::Divider::Component.new %>

<%= render HakumiComponents::Typography::Title::Component.new(level: 5) do %>Borderless<% end %>
<%= render HakumiComponents::Space::Component.new do %>
  <%= render HakumiComponents::Tag::Component.new(bordered: false) do %>Tag<% end %>
  <%= render HakumiComponents::Tag::Component.new(bordered: false, color: :magenta) do %>Magenta<% end %>
  <%= render HakumiComponents::Tag::Component.new(bordered: false, color: :success) do %>Success<% end %>
<% end %>
Add & Remove Dynamically
Dynamically add and remove tags using the JavaScript API.
Tag 1 Tag 2 Tag 3
Code
<%= render HakumiComponents::Space::Component.new(direction: :vertical, size: :middle) do %>
  <div id="tag-dynamic-container">
    <%= render HakumiComponents::Space::Component.new(wrap: true, id: "tag-dynamic-tags") do %>
      <%= render HakumiComponents::Tag::Component.new(closable: true) do %>Tag 1<% end %>
      <%= render HakumiComponents::Tag::Component.new(closable: true) do %>Tag 2<% end %>
      <%= render HakumiComponents::Tag::Component.new(closable: true) do %>Tag 3<% end %>
    <% end %>
  </div>

  <%= render HakumiComponents::Button::Component.new(id: "tag-dynamic-add-btn", size: :small) do %>
    <%= render HakumiComponents::Icon::Component.new(name: "plus") %> Add Tag
  <% end %>
<% end %>

<script>
  (() => {
    const tagsContainer = document.getElementById("tag-dynamic-tags")
    const addButton = document.getElementById("tag-dynamic-add-btn")
    if (!tagsContainer || !addButton) return

    let counter = 4
    let wired = false

    const wire = () => {
      if (wired) return true
      if (!window.HakumiComponents?.renderComponent) return false

      addButton.addEventListener("click", async () => {
        await HakumiComponents.renderComponent("tag", {
          target: "#tag-dynamic-tags",
          mode: "append",
          params: {
            closable: true,
            content: `Tag ${counter++}`
          }
        })
      })

      wired = true
      return true
    }

    if (wire()) return
    const interval = setInterval(() => { if (wire()) clearInterval(interval) }, 50)
    setTimeout(() => clearInterval(interval), 5000)
  })()
</script>
Draggable Tags
Drag and drop to reorder tags using SortableJS.
Drag me Sort us Around To reorder The list
Code
<%= render HakumiComponents::Tag::Group::Component.new(sortable: true, id: "tag-draggable-group") do %>
  <%= render HakumiComponents::Tag::Component.new(color: :magenta) do %>Drag me<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :red) do %>Sort us<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :volcano) do %>Around<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :orange) do %>To reorder<% end %>
  <%= render HakumiComponents::Tag::Component.new(color: :gold) do %>The list<% end %>
<% end %>

<script>
  (() => {
    const group = document.getElementById("tag-draggable-group")
    if (!group) return

    let wired = false
    const wire = () => {
      if (wired) return true
      if (!group.hakumiComponent.apiGroup) return false

      group.addEventListener("hakumi--tag-group:sortStart", (e) => {
        console.log("Drag started:", e.detail.item.textContent.trim(), "at index", e.detail.oldIndex)
      })

      group.addEventListener("hakumi--tag-group:sortEnd", (e) => {
        console.log("Drag ended:", e.detail.oldIndex, "->", e.detail.newIndex)
        console.log("New order:", e.detail.values)
      })

      wired = true
      return true
    }

    if (wire()) return
    const interval = setInterval(() => { if (wire()) clearInterval(interval) }, 50)
    setTimeout(() => clearInterval(interval), 5000)
  })()
</script>

Tag API

Prop Type Default Description
color Symbol or String - Tag color. Use preset colors (:magenta, :red, :orange, :gold, :lime, :green, :cyan, :blue, :purple), status colors (:success, :processing, :error, :warning, :default), or custom hex string.
closable Boolean false Whether the tag can be closed
close_icon String close Custom close icon name
bordered Boolean true Whether the tag has border
variant Symbol :filled Visual variant: :filled, :outlined, :borderless
href String - If set, renders as <a> tag with this href
checkable Boolean false Whether the tag is checkable
checked Boolean false Initial checked state (only for checkable tags)
draggable Boolean false Whether the tag is draggable

Tag Slots

Prop Type Default Description
icon Slot - Custom icon to display before the tag content
content Block - The tag content/label

JavaScript API

Access via element.hakumiComponent.api
Prop Type Default Description
close() Function - Closes the tag with animation
toggle() Function - Toggles checked state (checkable only)
check() Function - Sets checked to true (checkable only)
uncheck() Function - Sets checked to false (checkable only)
isChecked() Function - Returns current checked state

Events

Prop Type Default Description
hakumi--tag:close Event - Fired when tag is about to close. Call preventDefault() to cancel.
hakumi--tag:afterClose Event - Fired after tag is removed from DOM
hakumi--tag:change Event - Fired when checked state changes (checkable only). Detail: { checked: Boolean }

Tag.Group API

Prop Type Default Description
sortable Boolean false Enable drag and drop sorting of tags
animation Number 150 Animation duration in ms for drag operations

Tag.Group JavaScript API

Access via element.hakumiComponent.api
Prop Type Default Description
enableSorting() Function - Enable drag sorting
disableSorting() Function - Disable drag sorting
isSortingEnabled() Function - Returns whether sorting is enabled
getTags() Function - Returns array of tag elements
getTagValues() Function - Returns array of tag text values

Tag.Group Events

Prop Type Default Description
hakumi--tag-group:sortStart Event - Fired when drag starts. Detail: { item, oldIndex }
hakumi--tag-group:sortEnd Event - Fired when drag ends. Detail: { item, oldIndex, newIndex, values }