Files
sure/test/components/DS/pill_test.rb
Guillem Arias Fauste d22ffe5994 fix(ds-pill): default show_dot per mode (badges clean, markers keep dot) (#2107)
Closes #2001.

DS::Pill defaulted show_dot: true for both modes, so every status/category
badge got a leading dot by default — redundant with the pill shape + tone +
label already carrying the signal, and noisy in dense lists. More than half
the marker:false callsites were already passing show_dot: false to fight it.

The default is now mode-aware: marker: true keeps the dot (stage markers),
marker: false (badges) is dot-less. An explicit show_dot: still wins.

Only one in-tree callsite relied on the old default without an icon and wants
the dot: settings/providers/_status_pill (live connection state) — pinned with
show_dot: true. The enable_banking "Beta" badge loses its dot, which is the
desired outcome (ref #1997). Icon-bearing transaction badges are unaffected
(an icon already suppresses the dot).

Left the now-redundant show_dot: false overrides in place to avoid churn and
conflicts with in-flight pill-migration branches; they're harmless (explicit
false == new default).

Adds tests pinning the per-mode default resolution; updates the Lookbook
preview to show the opt-in dot vs the clean default.
2026-06-03 00:01:38 +02:00

94 lines
3.7 KiB
Ruby

require "test_helper"
class DS::PillTest < ViewComponent::TestCase
test "marker mode (default) renders uppercase sub-12px chrome with rounded-md" do
render_inline(DS::Pill.new(label: "Beta", tone: :violet))
pill = page.find("span", text: "Beta")
assert_includes pill[:class], "uppercase"
# Marker keeps sub-12px text via arbitrary value (intentional — see component docs).
assert_match(/text-\[1[01]px\]/, pill[:class])
# Marker uses rounded-md (chip shape).
assert_includes pill[:class], "rounded-md"
refute_includes pill[:class], "rounded-full"
end
test "marker: false renders normal-case DS-scale chrome with rounded-full" do
render_inline(DS::Pill.new(label: "Active", tone: :success, marker: false))
pill = page.find("span", text: "Active")
refute_includes pill[:class], "uppercase"
# Badge mode snaps to text-xs / text-sm — no sub-12px arbitrary values.
assert_match(/text-(xs|sm)/, pill[:class])
refute_match(/text-\[1[01]px\]/, pill[:class])
# Badge uses rounded-full to match the existing _status_pill / _maturity_badge convention.
assert_includes pill[:class], "rounded-full"
refute_includes pill[:class], "rounded-md"
end
test "semantic tone aliases resolve to visual palette tones" do
{
success: :green,
warning: :amber,
error: :red,
destructive: :red,
info: :indigo,
neutral: :gray
}.each do |alias_name, expected_visual|
pill = DS::Pill.new(label: "x", tone: alias_name)
assert_equal expected_visual, pill.tone, "Expected #{alias_name}#{expected_visual}, got #{pill.tone}"
end
end
test "unknown tone falls back to violet" do
pill = DS::Pill.new(label: "x", tone: :nonexistent)
assert_equal :violet, pill.tone
end
test "red tone palette resolves to red-* tokens" do
pill = DS::Pill.new(label: "Failed", tone: :error)
assert_includes pill.palette[:dot], "color-red-500"
assert_includes pill.palette[:bg], "color-red-50"
end
test "marker mode shows the dot by default" do
render_inline(DS::Pill.new(label: "Beta", tone: :violet))
assert_selector "span.inline-block.rounded-full"
end
test "badge mode (marker: false) is dot-less by default" do
render_inline(DS::Pill.new(label: "Member", tone: :neutral, marker: false))
assert_no_selector "span.inline-block.rounded-full"
end
test "badge mode opts back into the dot with show_dot: true" do
render_inline(DS::Pill.new(label: "Active", tone: :success, marker: false, show_dot: true))
assert_selector "span.inline-block.rounded-full"
end
test "marker mode can drop the dot with show_dot: false" do
render_inline(DS::Pill.new(label: "Beta", tone: :violet, show_dot: false))
assert_no_selector "span.inline-block.rounded-full"
end
test "custom color renders dynamic badge styles" do
render_inline(DS::Pill.new(label: "Groceries", marker: false, custom_color: "#f97316"))
pill = page.find("span", text: "Groceries")
assert_includes pill[:style], "color-mix(in oklab, #f97316 10%, transparent)"
assert_includes pill[:style], "color: #f97316"
end
test "icon option renders glyph in place of dot" do
render_inline(DS::Pill.new(label: "Syncing", tone: :info, marker: false, icon: "loader"))
# Lucide icon helper renders the inline SVG; verifying we see at least one <svg>
# is enough — the icon helper is covered by its own tests.
assert_selector "svg"
# And the dot is suppressed when an icon takes its place. The dot is an
# `inline-block` span (parent pill is `inline-flex`), so target it by
# `inline-block.rounded-full` to avoid matching the parent pill.
assert_no_selector "span.inline-block.rounded-full"
end
end