diff --git a/app/components/DS/pill.html.erb b/app/components/DS/pill.html.erb index 2dc15e0ec..67e051905 100644 --- a/app/components/DS/pill.html.erb +++ b/app/components/DS/pill.html.erb @@ -10,11 +10,15 @@ <% else %> <% if icon %> - <%= helpers.icon(icon, size: "xs", color: "current") %> + <%= helpers.icon(icon, size: icon_size, color: "current") %> <% elsif show_dot %> <% end %> - <%= label %> + <% if truncate || label_testid %> + <%= tag.span label, class: ("min-w-0 truncate" if truncate), data: (label_testid ? { testid: label_testid } : nil) %> + <% else %> + <%= label %> + <% end %> <% end %> diff --git a/app/components/DS/pill.rb b/app/components/DS/pill.rb index c45bf056c..b9ef102db 100644 --- a/app/components/DS/pill.rb +++ b/app/components/DS/pill.rb @@ -16,7 +16,8 @@ class DS::Pill < DesignSystemComponent neutral: :gray }.freeze - attr_reader :label, :tone, :style, :size, :show_dot, :dot_only, :title, :icon, :marker, :custom_color + attr_reader :label, :tone, :style, :size, :show_dot, :dot_only, :title, :icon, :marker, :custom_color, + :truncate, :label_testid, :icon_size # Generic inline pill primitive. Two modes: # @@ -50,8 +51,17 @@ class DS::Pill < DesignSystemComponent # `SEMANTIC_TONE_ALIASES`. # - Sure has full violet / indigo / fuchsia / amber / green / gray / # red ramps in the design system; this component picks named tokens - # at render time. No raw hex. - def initialize(label: nil, tone: :violet, style: :soft, size: :sm, show_dot: nil, dot_only: false, title: nil, icon: nil, marker: true, custom_color: nil) + # at render time. No raw hex — except `custom_color:`, which exists for + # user-defined entities (categories, tags) whose hue is data, not design. + # - `truncate: true` lets the pill shrink inside a `min-w-0` parent and + # ellipsize its label instead of overflowing (dense table cells like the + # transaction row's category column). Default pills stay `shrink-0`. + # - `label_testid:` stamps `data-testid` on the label span for system / + # controller tests that need to target the text node. + # - `icon_size:` passes through to the icon helper (default "xs"; the + # category badge uses "sm" to keep its established glyph size). + def initialize(label: nil, tone: :violet, style: :soft, size: :sm, show_dot: nil, dot_only: false, title: nil, icon: nil, marker: true, custom_color: nil, + truncate: false, label_testid: nil, icon_size: "xs") resolved_tone = SEMANTIC_TONE_ALIASES.fetch(tone.to_sym, tone.to_sym) @label = label || I18n.t("ds.pill.default_label", default: "Beta") @tone = TONES.include?(resolved_tone) ? resolved_tone : :violet @@ -65,6 +75,9 @@ class DS::Pill < DesignSystemComponent @icon = icon @marker = marker @custom_color = custom_color + @truncate = truncate + @label_testid = label_testid + @icon_size = icon_size end def palette @@ -149,7 +162,10 @@ class DS::Pill < DesignSystemComponent def container_classes base = [ - "inline-flex items-center align-middle font-medium whitespace-nowrap shrink-0", + "inline-flex items-center align-middle font-medium", + # Truncating pills must be allowed to shrink (and let the label span + # ellipsize); everything else keeps its intrinsic width. + truncate ? "max-w-full min-w-0" : "whitespace-nowrap shrink-0", "border leading-none" ] diff --git a/app/views/categories/_badge.html.erb b/app/views/categories/_badge.html.erb index 5ab8d6c1d..283c05fc2 100644 --- a/app/views/categories/_badge.html.erb +++ b/app/views/categories/_badge.html.erb @@ -1,17 +1,20 @@ <%# locals: (category:) %> <% category ||= Category.uncategorized %> +<%# Canonical category badge: DS::Pill in badge mode carrying the category's + user-chosen hex (custom_color is the sanctioned escape hatch for hues that + are data, not design). truncate + this min-w-0 wrapper keep long names + ellipsizing inside tight columns (e.g. the transaction row's category + cell) instead of overflowing them. %>
- - <% if category.lucide_icon.present? %> - - <%= icon category.lucide_icon, size: "sm", color: "current" %> - - <% end %> - <%= category.name %> - + <%= render DS::Pill.new( + label: category.name, + custom_color: category.color, + icon: category.lucide_icon.presence, + icon_size: "sm", + marker: false, + size: :md, + truncate: true, + label_testid: "category-name", + title: category.name) %>
diff --git a/app/views/transactions/_transaction.html.erb b/app/views/transactions/_transaction.html.erb index 9aff39d03..9752d6117 100644 --- a/app/views/transactions/_transaction.html.erb +++ b/app/views/transactions/_transaction.html.erb @@ -7,7 +7,7 @@ <%= turbo_frame_tag dom_id(transaction) do %>
"> -
+
<%= check_box_tag dom_id(entry, "selection"), disabled: transaction.transfer.present?, class: "checkbox checkbox--light hidden lg:block", @@ -179,7 +179,7 @@
-