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 @@ + + + + + + List variant + + + + + size: {{ size ?? 'md (default)' }} + + + + + + {{ item.label }} + + + + + 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 @@