fix(splits): let category selector size to its content instead of clipping names (#2962)

* fix(splits): let category selector size to its content instead of clipping names

- Replace the fixed md:w-44 column with flex-initial + md:min-w-44/md:max-w-72
  so the button grows with the selected category name
- Truncate the badge label in an inner span with a native title tooltip and a
  max-w-64 cap, keeping the color dot from shrinking
- Widen the dropdown to md:w-80 so option badges stay readable
- select_controller: stop forcing the menu width to 100% inline (the markup's
  width classes now decide) and anchor the menu to the button's right edge
  when it would overflow the scroll container

Fixes #2934

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(splits): render category badges via DS::Pill

- Options render the canonical categories/badge partial; the button renders
  the same DS::Pill directly (a button only allows phrasing content, so the
  partial's div wrapper stays out). category_badge_select's clone selector
  follows the pill markup.
- The client-side row template in split_transaction_controller gets the same
  md:min-w-28 name-field floor as the server-rendered rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Brandon Wolf
2026-08-09 02:10:24 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 440e04b942
commit 5accc90a81
6 changed files with 30 additions and 28 deletions
@@ -370,7 +370,7 @@ export default class extends Controller {
const shouldOpenUp = placement === "up" || (placement === "auto" && spaceBelow < menuHeight && spaceAbove > spaceBelow)
this.menuTarget.style.left = "0"
this.menuTarget.style.width = "100%"
this.menuTarget.style.right = ""
this.menuTarget.style.top = ""
this.menuTarget.style.bottom = ""
this.menuTarget.style.overflowY = "auto"
@@ -382,5 +382,14 @@ export default class extends Controller {
this.menuTarget.style.top = "100%"
this.menuTarget.style.maxHeight = `${Math.max(0, spaceBelow - this.offsetValue)}px`
}
// A menu wider than its anchor (e.g. the split dialog's category select)
// can spill past the scroll container's right edge and force a horizontal
// scrollbar; anchor it to the right edge of the button instead.
const menuRect = this.menuTarget.getBoundingClientRect()
if (menuRect.right > containerRect.right) {
this.menuTarget.style.left = "auto"
this.menuTarget.style.right = "0"
}
}
}