Files
sure/app/components/DS/pill.html.erb
Guillem Arias Fauste d88d6e9e58 fix(ds): canonical transaction-row — stop category pills truncating (#2147)
* fix(ds): canonical transaction-row — stop category pills truncating (#2137)

The desktop transaction grid gave the name column col-span-8 (67%, usually
half-empty) and the category column only col-span-2 (17%), so the category
pill's name area was clamped to ~44px and ellipsized nearly every value
("Misc...", "Shop...", "Rest...") despite the empty space the audit flagged.

- Rebalance the lg:grid-cols-12 row: name col-span-8 -> 7, category 2 -> 3
  (amount unchanged; still 12). Category gains 50% width from the over-wide
  name column.
- categories/_badge: the pill was `flex w-full` (stretched to fill the column);
  make it `inline-flex max-w-full` so it hugs its content and short names render
  fully, capping + truncating only when genuinely too long.

Verified on /transactions: visible-row category truncation dropped 7/7 -> 2/7
even in the compressed (AI-panel-open) view; Payment / Shopping / Restaurants
now render in full. Fixes both the interactive categories/menu and the static
transfer categories/badge (menu reuses the badge partial).

* feat(ds): lift categories/_badge onto DS::Pill

Addresses the Drift Patrol finding (and jjmata's request) properly
instead of patching the bespoke span: the badge becomes a DS::Pill in
badge mode. The pill primitive grows the three capabilities the badge
needed and the bot's one-liner glossed over:

- truncate: pills that may shrink inside min-w-0 columns drop their
  shrink-0/whitespace-nowrap and ellipsize the label instead of
  overflowing (the transaction-row category cell this PR fixes).
- label_testid: stamps data-testid on the label span; five test files
  target [data-testid='category-name'].
- icon_size: passthrough to the icon helper (badge keeps its
  established sm glyph; default stays xs).

custom_color was already the sanctioned escape hatch for user-chosen
hues. Owned visual deltas from pill standardization: px-1.5/py-1 ->
px-2/py-0.5, gap-1 -> gap-1.5, border mix 10% -> 20%; bg mix, hex text,
radius, text scale, icon size, truncation and testid are parity.

Label wrapper only renders when truncate/label_testid ask for it, so
existing pill DOM (and the find("span", text:) assertions on it) is
unchanged. Four new pill tests + a Lookbook case cover the recipe.
2026-06-06 16:28:22 +02:00

25 lines
1.2 KiB
Plaintext

<% if dot_only %>
<%# Compact dot — no label, no border, just the colored marker. Used on the
collapsed sidebar nav. Keeps tone semantics without taking up label
width. %>
<span role="img"
class="inline-block shrink-0 align-middle rounded-full"
style="width: <%= dot_size_px %>px; height: <%= dot_size_px %>px; background-color: <%= dot_color %>;"
aria-label="<%= title || t("ds.pill.aria_label", label: label) %>"
title="<%= title || t("ds.pill.aria_label", label: label) %>"></span>
<% else %>
<span class="<%= container_classes %>" style="<%= container_styles %>" title="<%= title || label %>">
<% if icon %>
<span class="shrink-0"><%= helpers.icon(icon, size: icon_size, color: "current") %></span>
<% elsif show_dot %>
<span class="inline-block shrink-0 rounded-full"
style="width: <%= dot_size_px %>px; height: <%= dot_size_px %>px; background-color: <%= dot_color %>;"></span>
<% end %>
<% if truncate || label_testid %>
<%= tag.span label, class: ("min-w-0 truncate" if truncate), data: (label_testid ? { testid: label_testid } : nil) %>
<% else %>
<%= label %>
<% end %>
</span>
<% end %>