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 Hakumi::Space::Component.new do %>
  <%= render Hakumi::Tag::Component.new do %>Tag 1<% end %>
  <%= render Hakumi::Tag::Component.new do %>
    <% render Hakumi::Icon::Component.new(name: "link") %>
    Link
  <% end %>
  <%= render Hakumi::Tag::Component.new(closable: true) do %>Tag 2<% end %>
  <%= render Hakumi::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 Hakumi::Typography::Title::Component.new(level: 5) do %>Preset Colors<% end %>
<%= render Hakumi::Space::Component.new(wrap: true) do %>
  <% %i[magenta red volcano orange gold lime green cyan blue geekblue purple].each do |color| %>
    <%= render Hakumi::Tag::Component.new(color: color) do %><%= color %><% end %>
  <% end %>
<% end %>

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

<%= render Hakumi::Typography::Title::Component.new(level: 5) do %>Custom Colors<% end %>
<%= render Hakumi::Space::Component.new(wrap: true) do %>
  <%= render Hakumi::Tag::Component.new(color: "#f50") do %>#f50<% end %>
  <%= render Hakumi::Tag::Component.new(color: "#2db7f5") do %>#2db7f5<% end %>
  <%= render Hakumi::Tag::Component.new(color: "#87d068") do %>#87d068<% end %>
  <%= render Hakumi::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 Hakumi::Space::Component.new(wrap: true) do %>
  <%= render Hakumi::Tag::Component.new(color: :success) do %>success<% end %>
  <%= render Hakumi::Tag::Component.new(color: :processing) do %>processing<% end %>
  <%= render Hakumi::Tag::Component.new(color: :error) do %>error<% end %>
  <%= render Hakumi::Tag::Component.new(color: :warning) do %>warning<% end %>
  <%= render Hakumi::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 Hakumi::Space::Component.new do %>
  <%= render Hakumi::Tag::Component.new(checkable: true, checked: true) do %>Movies<% end %>
  <%= render Hakumi::Tag::Component.new(checkable: true) do %>Books<% end %>
  <%= render Hakumi::Tag::Component.new(checkable: true) do %>Music<% end %>
  <%= render Hakumi::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 Hakumi::Space::Component.new do %>
  <%= render Hakumi::Tag::Component.new(color: :cyan) do |tag| %>
    <% tag.with_icon do %>
      <%= render Hakumi::Icon::Component.new(name: "x") %>
    <% end %>
    X
  <% end %>

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

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

  <%= render Hakumi::Tag::Component.new(color: :purple) do |tag| %>
    <% tag.with_icon do %>
      <%= render Hakumi::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 Hakumi::Typography::Title::Component.new(level: 5) do %>Filled (Default)<% end %>
<%= render Hakumi::Space::Component.new do %>
  <%= render Hakumi::Tag::Component.new do %>Tag<% end %>
  <%= render Hakumi::Tag::Component.new(color: :magenta) do %>Magenta<% end %>
  <%= render Hakumi::Tag::Component.new(color: :success) do %>Success<% end %>
<% end %>

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

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

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

<%= render Hakumi::Typography::Title::Component.new(level: 5) do %>Borderless<% end %>
<%= render Hakumi::Space::Component.new do %>
  <%= render Hakumi::Tag::Component.new(bordered: false) do %>Tag<% end %>
  <%= render Hakumi::Tag::Component.new(bordered: false, color: :magenta) do %>Magenta<% end %>
  <%= render Hakumi::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 Hakumi::Space::Component.new(direction: :vertical, size: :middle) do %>
  <div id="tag-dynamic-container">
    <%= render Hakumi::Space::Component.new(wrap: true, id: "tag-dynamic-tags") do %>
      <%= render Hakumi::Tag::Component.new(closable: true) do %>Tag 1<% end %>
      <%= render Hakumi::Tag::Component.new(closable: true) do %>Tag 2<% end %>
      <%= render Hakumi::Tag::Component.new(closable: true) do %>Tag 3<% end %>
    <% end %>
  </div>

  <%= render Hakumi::Button::Component.new(id: "tag-dynamic-add-btn", size: :small) do %>
    <%= render Hakumi::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 Hakumi::Tag::Group::Component.new(sortable: true, id: "tag-draggable-group") do %>
  <%= render Hakumi::Tag::Component.new(color: :magenta) do %>Drag me<% end %>
  <%= render Hakumi::Tag::Component.new(color: :red) do %>Sort us<% end %>
  <%= render Hakumi::Tag::Component.new(color: :volcano) do %>Around<% end %>
  <%= render Hakumi::Tag::Component.new(color: :orange) do %>To reorder<% end %>
  <%= render Hakumi::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.hakumiTagGroup) 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 (element.hakumiTag)

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 (element.hakumiTagGroup)

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 }