Badge
Compact status labels with typed color, variant, and size.
- Source
app/components/nitro_kit/badge.rb- API
NitroKit::Badge.new(label, variant:, size:, color:)
Colors
Every semantic color keeps compact state legible without application classes.
Color matrix
test/dummy/app/components/gallery/components/badge_page.rbGallery::Data.badge_colors.each do |badge|
sample(badge.label, slug: badge.slug) do
render_badge(badge, id: "gallery-badge-color-#{badge.slug}")
end
endVariants and sizes
Both variants and both sizes are closed, visible presentation choices.
Variant matrix
test/dummy/app/components/gallery/components/badge_page.rbGallery::Data.badge_variants.each do |badge|
sample(badge.label, slug: badge.slug) do
render_badge(badge, id: "gallery-badge-variant-#{badge.slug}")
end
endSize scale
test/dummy/app/components/gallery/components/badge_page.rbGallery::Data.badge_sizes.each do |badge|
render_badge(badge, id: "gallery-badge-size-#{badge.slug}")
endContent modes
Scalar, block, numeric, nested icon, and long product labels use the same label slot. Badges keep their label on one line: when the parent is narrower than the label, the badge itself truncates it with an ellipsis.
Label content
test/dummy/app/components/gallery/components/badge_page.rbsample("Scalar", slug: "scalar") do
render NitroKit::Badge.new(
"Ready",
id: "gallery-badge-scalar",
color: :success
)
end
sample("Block", slug: "block") do
render NitroKit::Badge.new(
id: "gallery-badge-block",
variant: :outline,
color: :info
) { "Generated from a Phlex block" }
end
sample("Numeric", slug: "numeric") do
render NitroKit::Badge.new(128, id: "gallery-badge-numeric", color: :neutral)
end
sample("Nested icon", slug: "nested-icon") do
render NitroKit::Badge.new(id: "gallery-badge-nested-icon", color: :success) do
render NitroKit::Icon.new(:lock, id: "gallery-badge-lock-icon", size: :xs)
plain " Secured"
end
end
sample("Long label", slug: "long-label") do
render NitroKit::Badge.new(
"Awaiting production deployment approval from a workspace administrator",
id: "gallery-badge-long-label",
variant: :outline,
color: :warning
)
endRoster composition
Table, Avatar, and Badge compose into a realistic member-status roster.
Workspace roster
| Person | Role | Status |
|---|---|---|
| Ada Lovelace | Owner | Active |
| Grace Hopper | Admin | Active |
| Katherine Johnson | Member | Invited |
test/dummy/app/components/gallery/components/badge_page.rbrender NitroKit::Table.new(
id: "gallery-badge-roster-table",
table_html: { id: "gallery-badge-roster-table-element" }
) do |table|
table.caption("Workspace roster")
table.thead do
table.tr do
table.th("Person")
table.th("Role")
table.th("Status", align: :right)
end
end
table.tbody do
Gallery::Data.members.each do |member|
table.tr do
table.th(scope: :row) do
render NitroKit::Avatar.new(
alt: member.name,
size: :sm,
id: "gallery-badge-roster-avatar-#{member.id}"
)
plain " #{member.name}"
end
table.td(member.role.to_s.humanize)
table.td(align: :right) do
render NitroKit::Badge.new(
member.status.to_s.humanize,
id: "gallery-badge-roster-status-#{member.id}",
color: member_status_color(member.status),
size: :sm
)
end
end
end
end
endComponent contract
Constructor options, rendered root, closed vocabularies, and compound boundary for this component, exactly as shipped.
docs/component_contracts.md · NitroKit::Badge
- Constructor-specific options
- optional text or a content block
variant: :default,size: :md,color: :neutral,id: nil
- Root and closed vocabulary
span[data-nk=badge]; variantsdefault outline; sizesxs sm md; semantic colors plus the decorative palette- Compound contract
- Content has exactly one path: label text or a content block, never both. Blank text raises at construction, the earliest point it is knowable; missing content raises at render. The color axis carries two vocabularies with different jobs. The semantic families
neutral info success warning destructiveresolve to the--nk-palette-{family}tint roles and move with an application's theme; the seventeen decorative hues resolve to the--nk-palette-{hue}roles and stay the color they name.redanddestructiveare therefore independently themeable rather than two spellings of one value.href:anddismissible:are deliberately out of scope; wrap the Badge in a link or pair it with a Button instead.
System rules for coding agents
Instructions for coding agents, repeated on every component page so one fetched page has enough context. Humans can usually skip this section.
test/dummy/app/components/gallery/agent_rules.rb
View agent instructions
- Nitro Kit 2.0 is a gem-owned, Phlex-only UI system for Rails. Render components directly:
render NitroKit::Button.new("Save", variant: :primary). - Compose Nitro components inside application-owned Phlex classes. Public initializers and declared slots are the component API; private methods are not.
- Public options are explicit keywords, and enumerated options are closed vocabularies. Invalid names or values raise
ArgumentError; this component's accepted options are in the contract above. - Pass native attributes through their typed boundary:
html:for HTML,aria:for ARIA, anddata:for application data.classandstyleare forbidden, including insidehtml:. - Nitro owns
NitroKit::Component::RESERVED_DATA_ATTRIBUTES:data-nk,data-slot,data-variant,data-size,data-nk-escape,data-enhanced,data-state,data-disabled,data-required,data-orientation,data-presentation,data-placement,data-layout,data-side,data-field-type,data-dir,data-gap,data-align,data-justify,data-wrap,data-cols,data-mode,data-key. Do not pass them throughdata:.data-action,data-controllerare additive and compose with Nitro behavior. - If an integration truly requires a class, use
desperately_need_a_class:. It requires a non-blank String and marks the exception withdata-nk-escape="class". - Every root emits
data-nk; owned parts emit component-qualifieddata-slotvalues such asfield-controlorcard-title. Select on those attributes, never on classes. - Customize components with documented
--nk-*custom properties in an application stylesheet. Variables beginning with--_nk-*are private component mechanics. - Use
NitroKit::FlexandNitroKit::Gridfor layout. Parents own external placement and available width; components own their intrinsic geometry. - Preserve native elements and accessibility semantics. State is exposed through native semantics and ARIA first, and through
data-statewhen styling or behavior also needs it.