From 3b153a379cd8f3d493ca8359a6ae2e9087d76166 Mon Sep 17 00:00:00 2001 From: Konstantinos Paparas Date: Mon, 27 Apr 2026 21:44:21 +0200 Subject: [PATCH] fix(button): align list-variant label with icon line-box MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighten the list-variant label to `leading-[1.125rem]` so its line-box matches the md icon (`--rui-icon-size: 1.125rem`). Without this, the 20px label line-box (from `leading-5` on the root) is flex-centered against the 18px icon box and the baseline-aligned glyphs visually drift above the icon's optical center — most readable in tight list rows like the rotki UserDropdown menu. Adds a list-variant section to the example app and an e2e assertion that the label and icon centers line up. Closes #515 --- apps/example/e2e/button.spec.ts | 23 +++++++++ .../src/components/buttons/ListButtons.vue | 48 +++++++++++++++++++ apps/example/src/views/ButtonView.vue | 2 + .../buttons/button/button-styles.ts | 8 +++- 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 apps/example/src/components/buttons/ListButtons.vue diff --git a/apps/example/e2e/button.spec.ts b/apps/example/e2e/button.spec.ts index eab68313..9d763749 100644 --- a/apps/example/e2e/button.spec.ts +++ b/apps/example/e2e/button.spec.ts @@ -23,4 +23,27 @@ test.describe('buttons', () => { await expect(disabledButton).toBeDisabled(); await expect(disabledButton).toContainText('0'); }); + + test('list-variant button label shares the icon line-box (issue #515)', async ({ page }) => { + const button = page.getByTestId('list-button-md-settings'); + const label = button.locator('[data-id="btn-label"]'); + const icon = button.locator('svg').first(); + + await expect(button).toBeVisible(); + + // Label line-height collapses to the md icon size (1.125rem = 18px) so the + // label's line-box matches the icon's bounding box; without the fix the + // label inherits leading-5 (20px) and visually drifts above the icon. + await expect(label).toHaveCSS('line-height', '18px'); + + const labelBox = await label.boundingBox(); + const iconBox = await icon.boundingBox(); + expect(labelBox).not.toBeNull(); + expect(iconBox).not.toBeNull(); + + // Centers should line up within ~1px now that the line-boxes match. + const labelCenter = labelBox!.y + labelBox!.height / 2; + const iconCenter = iconBox!.y + iconBox!.height / 2; + expect(Math.abs(labelCenter - iconCenter)).toBeLessThanOrEqual(1); + }); }); diff --git a/apps/example/src/components/buttons/ListButtons.vue b/apps/example/src/components/buttons/ListButtons.vue new file mode 100644 index 00000000..01fcdb5f --- /dev/null +++ b/apps/example/src/components/buttons/ListButtons.vue @@ -0,0 +1,48 @@ + + + diff --git a/apps/example/src/views/ButtonView.vue b/apps/example/src/views/ButtonView.vue index 66863729..dbd0e1eb 100644 --- a/apps/example/src/views/ButtonView.vue +++ b/apps/example/src/views/ButtonView.vue @@ -1,5 +1,6 @@