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.
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 } |