Skip to content

fix(ui): center text inside buttons with min_size across the app#851

Open
lklimek wants to merge 2 commits intov1.0-devfrom
fix/button-text-centering
Open

fix(ui): center text inside buttons with min_size across the app#851
lklimek wants to merge 2 commits intov1.0-devfrom
fix/button-text-centering

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Apr 24, 2026

Summary

Fixes a widespread egui 0.33 behavior where Button::new(text).min_size(size)
inherits horizontal_align from the outer layout (Align::LEFT in default
top_down). Text left-shifts inside the button rect whenever the label is
narrower than the min_size width.

Follow-up to PR #850, which fixed this for one specific callsite
(the disabled Transfer button) at commit 7be4f39b. This PR propagates
the fix across every helper in ComponentStyles AND eliminates the
direct-callsite boilerplate that was duplicating the fix.

Design

Two commits:

  1. refactor(ui): use ui.add_sized in ComponentStyles button helpers
    Swap ui.add(Button::new(text).min_size(size).fill(...)) for
    ui.add_sized(size, Button::new(text).fill(...)) in every helper.
    add_sized wraps the widget in
    allocate_ui_with_layout(size, Layout::centered_and_justified(main_dir))
    horizontal_align=Center, text centers inside the fill rect.
    Important: ui.add_sized treats its size arg as a MAX, but egui's
    horizontal layout expands frame_size to max(desired, available) in
    next_frame_ignore_wrap, so long labels overflow upward instead of
    clipping. Proven by the new kittest button_sizing suite.

  2. refactor(ui): migrate direct Button callsites to ComponentStyles helpers
    Every primary CTA, tab switcher, and toolbar button that was
    constructing Button::new(...).fill(...).min_size(...) manually now
    delegates to the appropriate ComponentStyles helper. All direct
    callsites now delegate to ComponentStyles helpers; no .min_size(...)
    constants remain in the migrated files. Custom widths (120×28 tabs,
    160×36 send, 150×36 toolbar) collapse to the shared
    DIALOG_BUTTON_MIN_SIZE (96×36) floor. Callsites that carry a
    bespoke glass-panel look (the 4 *_subscreen_chooser_panel.rs files
    plus grovestark_screen.rs mode tabs) keep their direct Button
    construction but drop .min_size(...) entirely — buttons size to
    content there.

Changes

Commit 1 — src/ui/theme.rs, src/ui/wallets/wallets_screen/dialogs.rs

  • add_primary_button, add_secondary_button, add_danger_button,
    add_toolbar_button, add_primary_button_enabled all go through
    ui.add_sized(DIALOG_BUTTON_MIN_SIZE, btn).
  • One external caller in dialogs.rs that dispatched via
    ui.add_enabled(...) switches to
    ui.add_enabled_ui(..., |ui| ui.add_sized(DIALOG_BUTTON_MIN_SIZE, btn)).

Commit 2 — migration to helpers (17 files, -214 lines net)

Primary CTA (add_primary_button / add_primary_button_enabled):
dashpay/mod.rs, my_tokens.rs (Import/Refresh), token_creator.rs
(Load Identity / Create Token / Register Token Contract / View JSON),
top_up by_platform_address.rs, send_screen.rs (2 sends),
single_key_send_screen.rs, withdraw_screen.rs,
network_chooser_screen.rs (Connect).

Danger (add_danger_button): network_chooser_screen.rs (Disconnect).

Tabs (primary/secondary swap for active/inactive): contacts_list.rs
(My Contacts / Requests), contact_requests.rs (Incoming / Outgoing),
transfer_screen.rs (Identity / Platform Address).

Bucket 7 — keep direct Button, drop .min_size(...) and add_sized,
use plain ui.add
: the 4 *_subscreen_chooser_panel.rs files
(DashPay, DPNS, Tokens, Tools) and grovestark_screen.rs (Generate /
Verify tabs). Custom glass-panel styling doesn't map to any existing
helper; buttons now content-size.

New tests — tests/kittest/button_sizing.rs (5 tests)

Locks in the correct semantics of the helpers:

  • Long labels ("Register Token Contract", "Create Asset Lock Transaction",
    "Remove From Local Database") grow past the 96px floor.
  • Short labels ("OK") stay at the ~96×36 floor.
  • Covers add_primary_button, add_primary_button_enabled,
    add_secondary_button, add_danger_button.

Test plan

  • cargo +nightly fmt --all — clean
  • cargo clippy --all-features --all-targets -- -D warnings — clean
  • cargo test --test kittest --all-features — 77/77 pass (including
    5 new button_sizing tests)
  • CI: Clippy + Tests.
  • Manual:
    • Any disabled primary button (e.g., Transfer before form is complete)
      — text centered in fill.
    • Toolbar buttons (Import Token, Refresh, Back, Close) — text centered.
    • Tab switchers (Contacts/Requests, Incoming/Outgoing, Identity/Platform
      Address, Generate/Verify Proof) — text centered.
    • Network chooser Connect/Disconnect — text centered.
    • Subscreen chooser panels (DashPay, DPNS, Tokens, Tools nav) — buttons
      now size to content (previously fixed 150×28); confirm no visual
      regression.

Summary by CodeRabbit

  • Bug Fixes

    • Improved button layout responsiveness by removing enforced fixed minimum sizes, allowing buttons to size according to content rather than rigid constraints.
  • Refactor

    • Consolidated button styling to use centralized helpers for consistent appearance across the app.
  • Tests

    • Added button sizing verification tests.

Button::new(text).min_size(size) inherits horizontal_align from the
outer layout (Align::LEFT in top_down). Text left-shifted inside the
button rect across every callsite whose label is narrower than the
min_size width — visible on disabled primary buttons and every
toolbar/tab-switcher element.

Swap to ui.add_sized(size, Button::new(text).fill(...)...), which wraps
the widget in allocate_ui_with_layout with Layout::centered_and_justified.
horizontal_align=Center; text centers inside the fill rect.

Affects ~60 callsites that go through ComponentStyles helpers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

The PR systematically refactors button UI construction across multiple screens by removing fixed minimum size constraints from button definitions and consolidating button styling through centralized ComponentStyles helpers. Button sizing is relocated from style constructors to callsites using ui.add_sized(), with new tests verifying sizing behavior.

Changes

Cohort / File(s) Summary
Subscreen Chooser Panels
src/ui/components/dashpay_subscreen_chooser_panel.rs, dpns_subscreen_chooser_panel.rs, tokens_subscreen_chooser_panel.rs, tools_subscreen_chooser_panel.rs, src/ui/tools/grovestark_screen.rs
Removed explicit min_size(150x28) constraints from active and inactive subscreen chooser buttons, allowing sizing to be determined by Egui layout behavior instead of fixed dimensions.
DashPay UI Refactoring
src/ui/dashpay/contact_requests.rs, contacts_list.rs, mod.rs
Refactored tab and action button rendering to use centralized ComponentStyles helpers (add_primary_button, add_secondary_button) instead of inline egui::Button construction with conditional styling.
Identity Screen Refactoring
src/ui/identities/top_up_identity_screen/by_platform_address.rs, transfer_screen.rs, withdraw_screen.rs
Replaced inline button construction and conditional fill/styling logic with ComponentStyles helpers (add_primary_button, add_primary_button_enabled, add_secondary_button) for top-up, destination-type selector, and withdraw buttons.
Tokens UI Refactoring
src/ui/tokens/tokens_screen/my_tokens.rs, token_creator.rs
Consolidated "Import Token", "Refresh", "Load Identity", "Register Token Contract", "View JSON", and "Create Token" buttons to use ComponentStyles helpers, removing manual RichText styling and conditional fill logic.
Wallets/Send Screen Refactoring
src/ui/wallets/send_screen.rs, single_key_send_screen.rs, src/ui/wallets/wallets_screen/dialogs.rs
Refactored send and fund buttons to use ComponentStyles::add_primary_button_enabled and add_sized for constrained sizing, replacing inline RichText styling and conditional fill() logic.
Network Connection UI
src/ui/network_chooser_screen.rs
Refactored "Connect" and "Disconnect" button rendering to use ComponentStyles::add_primary_button and add_danger_button with add_enabled_ui wrapping, replacing inline button construction and min_size constraints.
Theme/Styling System
src/ui/theme.rs
Relocated button minimum sizing from style constructors (primary_button, secondary_button, danger_button, toolbar_button) to callsites via ui.add_sized() and `add_enabled_ui(
Button Sizing Tests
tests/kittest/button_sizing.rs, tests/kittest/main.rs
Added new test module exercising ComponentStyles button helpers via egui_kittest::Harness, verifying that long text labels produce widths above specified thresholds and short labels meet minimum dimensions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Buttons align themselves with grace,
No more fixed sizes holding place,
Helpers centralize the style,
Making layouts reconcile,
Sizing shifts from rule to call—
Egui flows much more enthrall! 🎨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately reflects the main change: it addresses button text centering by removing fixed min_size constraints and using ui.add_sized instead, which is implemented consistently across all affected files and ComponentStyles helpers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/button-text-centering
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix/button-text-centering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thepastaclaw
Copy link
Copy Markdown
Collaborator

thepastaclaw commented Apr 24, 2026

✅ Review complete (commit f9f24d3)

Supersedes the mechanical ui.add_sized fix from the prior version of
this PR. Each primary CTA, tab switcher, and toolbar button that was
constructing Button::new(...).fill(...).min_size(...) manually now
delegates to the appropriate ComponentStyles helper. Helpers already
go through ui.add_sized after 8428fb3, so the centering bug is fixed
at the source — callsites stop carrying the boilerplate.

Accepts the DIALOG_BUTTON_MIN_SIZE (96×36) default for every callsite;
the custom widths (120×28 tabs, 160×36 send, 150×36 toolbar) are
dropped in favor of one source of truth.

Migrations by bucket:
- Primary CTA (add_primary_button / add_primary_button_enabled):
  dashpay/mod.rs, my_tokens.rs (Import/Refresh), token_creator.rs
  (Load Identity / Create Token / Register Token Contract / View
  JSON), top_up by_platform_address.rs, send_screen.rs (2 sends),
  single_key_send_screen.rs, withdraw_screen.rs, network_chooser
  (Connect).
- Danger (add_danger_button): network_chooser Disconnect.
- Tab switch (primary/secondary swap): contacts_list.rs,
  contact_requests.rs, transfer_screen.rs.
- Bucket 7 (custom glass-panel styling — keep direct Button, drop
  .min_size and add_sized, plain ui.add): the 4 *_subscreen_chooser
  panels and grovestark_screen mode tabs.

Also adds a kittest suite (tests/kittest/button_sizing.rs) that
verifies the helpers do NOT cap button max width — long labels
("Register Token Contract") grow beyond the 96px floor; short labels
("OK") stay at the floor. This locks in the correct semantics of
ui.add_sized: it treats its arg as a MAX, but egui's horizontal
layout expands frame_size to max(desired, available) in
next_frame_ignore_wrap, so content overflows upward rather than
clipping. Future reviewers can rerun the tests instead of re-reading
egui internals.

Net diff: 17 files, -214 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lklimek lklimek force-pushed the fix/button-text-centering branch from 4f66fad to f9f24d3 Compare April 24, 2026 19:49
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/kittest/button_sizing.rs (2)

92-110: Add a disabled-path sizing check for add_primary_button_enabled.

This file currently verifies only enabled = true; adding enabled = false coverage would better protect the exact branch this PR also updates.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/kittest/button_sizing.rs` around lines 92 - 110, Add a companion test
that covers the disabled path of ComponentStyles::add_primary_button_enabled:
create a new test (e.g., primary_button_disabled_does_not_shrink_for_long_label
or primary_button_disabled_grows_for_long_label) that mirrors
primary_button_enabled_grows_for_long_label but calls add_primary_button_enabled
with enabled = false, builds the same Harness with the long label "Register
Token Contract", obtains the rect via button_rect(&mut harness, "Register Token
Contract"), and asserts the expected sizing behaviour (same width threshold as
the enabled test or an appropriate threshold for disabled state). This ensures
the disabled branch of add_primary_button_enabled is exercised alongside the
existing enabled test.

41-50: Tighten floor assertions to the shared min-size constant.

The current >= 90 / >= 30 checks are a bit too permissive and can pass if the 96x36 floor regresses.

Proposed test hardening
 fn primary_button_floors_short_label() {
@@
     let rect = button_rect(&mut harness, "OK");
+    let min = ComponentStyles::DIALOG_BUTTON_MIN_SIZE;
     assert!(
-        rect.width() >= 90.0,
-        "short label must still honor ~96px min width (actual: {})",
+        rect.width() >= min.x - 0.5,
+        "short label must honor min width {} (actual: {})",
+        min.x,
         rect.width()
     );
     assert!(
-        rect.height() >= 30.0,
-        "short label must honor ~36px min height (actual: {})",
+        rect.height() >= min.y - 0.5,
+        "short label must honor min height {} (actual: {})",
+        min.y,
         rect.height()
     );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/kittest/button_sizing.rs` around lines 41 - 50, The tests use loose
numeric floors (>= 90.0 and >= 30.0) that can hide regressions; update the two
assertions in tests/kittest/button_sizing.rs to compare against the shared
min-size constant(s) instead of hardcoded numbers — e.g., replace 90.0 with the
app's BUTTON_MIN_WIDTH (or MIN_BUTTON_SIZE.width) and 30.0 with
BUTTON_MIN_HEIGHT (or MIN_BUTTON_SIZE.height), import or reference the module
constant used by the UI layout code, and keep the existing
rect.width()/rect.height() checks and message formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/kittest/button_sizing.rs`:
- Around line 92-110: Add a companion test that covers the disabled path of
ComponentStyles::add_primary_button_enabled: create a new test (e.g.,
primary_button_disabled_does_not_shrink_for_long_label or
primary_button_disabled_grows_for_long_label) that mirrors
primary_button_enabled_grows_for_long_label but calls add_primary_button_enabled
with enabled = false, builds the same Harness with the long label "Register
Token Contract", obtains the rect via button_rect(&mut harness, "Register Token
Contract"), and asserts the expected sizing behaviour (same width threshold as
the enabled test or an appropriate threshold for disabled state). This ensures
the disabled branch of add_primary_button_enabled is exercised alongside the
existing enabled test.
- Around line 41-50: The tests use loose numeric floors (>= 90.0 and >= 30.0)
that can hide regressions; update the two assertions in
tests/kittest/button_sizing.rs to compare against the shared min-size
constant(s) instead of hardcoded numbers — e.g., replace 90.0 with the app's
BUTTON_MIN_WIDTH (or MIN_BUTTON_SIZE.width) and 30.0 with BUTTON_MIN_HEIGHT (or
MIN_BUTTON_SIZE.height), import or reference the module constant used by the UI
layout code, and keep the existing rect.width()/rect.height() checks and message
formatting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2df0d3a8-e0cb-4c2f-97f0-6098f5dfba31

📥 Commits

Reviewing files that changed from the base of the PR and between 22e2103 and f9f24d3.

📒 Files selected for processing (20)
  • src/ui/components/dashpay_subscreen_chooser_panel.rs
  • src/ui/components/dpns_subscreen_chooser_panel.rs
  • src/ui/components/tokens_subscreen_chooser_panel.rs
  • src/ui/components/tools_subscreen_chooser_panel.rs
  • src/ui/dashpay/contact_requests.rs
  • src/ui/dashpay/contacts_list.rs
  • src/ui/dashpay/mod.rs
  • src/ui/identities/top_up_identity_screen/by_platform_address.rs
  • src/ui/identities/transfer_screen.rs
  • src/ui/identities/withdraw_screen.rs
  • src/ui/network_chooser_screen.rs
  • src/ui/theme.rs
  • src/ui/tokens/tokens_screen/my_tokens.rs
  • src/ui/tokens/tokens_screen/token_creator.rs
  • src/ui/tools/grovestark_screen.rs
  • src/ui/wallets/send_screen.rs
  • src/ui/wallets/single_key_send_screen.rs
  • src/ui/wallets/wallets_screen/dialogs.rs
  • tests/kittest/button_sizing.rs
  • tests/kittest/main.rs
💤 Files with no reviewable changes (5)
  • src/ui/components/dashpay_subscreen_chooser_panel.rs
  • src/ui/components/dpns_subscreen_chooser_panel.rs
  • src/ui/components/tokens_subscreen_chooser_panel.rs
  • src/ui/components/tools_subscreen_chooser_panel.rs
  • src/ui/tools/grovestark_screen.rs

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The two UI commits at this SHA mechanically swap from Button::min_size(...) to ui.add_sized(...) in ComponentStyles helpers and 17 direct Button::new(...) callsites to fix text centering. The change is semantically intentional and documented in the helper doc comments, but ships without a kittest harness locking in the new sizing contract. No correctness or security defects.

Reviewed commit: 4f66fad

🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/ui/theme.rs`:
- [SUGGESTION] lines 848-915: Add a kittest harness for the new add_sized button-sizing contract
  `add_primary_button`, `add_primary_button_enabled`, `add_secondary_button`, and `add_danger_button` now route every callsite through `ui.add_sized(DIALOG_BUTTON_MIN_SIZE, ...)` instead of `Button::min_size(...)`. `add_sized` wraps the widget in a `centered_and_justified` inner layout — that is exactly what fixes the text-centering bug, but it is not a drop-in replacement for `min_size`: it imposes a fixed size from the parent rather than a floor on the widget's own desired size. The doc comments on these helpers correctly explain the new semantics, but with 17 direct `Button::new(...)` callsites also migrated and `tests/kittest/button_sizing.rs` not present at this SHA, there is nothing in the repo that fails when a future cleanup reverts to `.min_size(...)` or drops `add_sized`. A small kittest covering at least one of each helper plus a long-label case (label wider than `DIALOG_BUTTON_MIN_SIZE`) and a short-label case would lock in both the centering fix and the expected min footprint.

Comment thread src/ui/theme.rs
Comment on lines 848 to 915
@@ -877,25 +879,38 @@ impl ComponentStyles {
.fill(DashColors::BUTTON_DISABLED)
.stroke(egui::Stroke::NONE)
.corner_radius(egui::CornerRadius::same(Shape::RADIUS_SM))
.min_size(Self::DIALOG_BUTTON_MIN_SIZE)
};
ui.add_enabled(enabled, button)
.on_hover_cursor(CursorIcon::PointingHand)
// `add_sized` wraps the widget in a `centered_and_justified` inner layout so the
// button's `AtomLayout` inherits `horizontal_align = Center`. This keeps the text
// centered within the fill rect for both the enabled and disabled branches, matching
// footprints so swapping between states doesn't jitter the cursor.
ui.add_enabled_ui(enabled, |ui| {
ui.add_sized(Self::DIALOG_BUTTON_MIN_SIZE, button)
})
.inner
.on_hover_cursor(CursorIcon::PointingHand)
}

/// Add a secondary button to the UI with pointer cursor on hover.
///
/// See `add_primary_button` for why `add_sized` is used.
pub fn add_secondary_button(
ui: &mut egui::Ui,
label: impl Into<WidgetText>,
dark_mode: bool,
) -> egui::Response {
ui.add(Self::secondary_button(label, dark_mode))
.on_hover_cursor(CursorIcon::PointingHand)
ui.add_sized(
Self::DIALOG_BUTTON_MIN_SIZE,
Self::secondary_button(label, dark_mode),
)
.on_hover_cursor(CursorIcon::PointingHand)
}

/// Add a danger button to the UI with pointer cursor on hover.
///
/// See `add_primary_button` for why `add_sized` is used.
pub fn add_danger_button(ui: &mut egui::Ui, label: impl Into<WidgetText>) -> egui::Response {
ui.add(Self::danger_button(label))
ui.add_sized(Self::DIALOG_BUTTON_MIN_SIZE, Self::danger_button(label))
.on_hover_cursor(CursorIcon::PointingHand)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Add a kittest harness for the new add_sized button-sizing contract

add_primary_button, add_primary_button_enabled, add_secondary_button, and add_danger_button now route every callsite through ui.add_sized(DIALOG_BUTTON_MIN_SIZE, ...) instead of Button::min_size(...). add_sized wraps the widget in a centered_and_justified inner layout — that is exactly what fixes the text-centering bug, but it is not a drop-in replacement for min_size: it imposes a fixed size from the parent rather than a floor on the widget's own desired size. The doc comments on these helpers correctly explain the new semantics, but with 17 direct Button::new(...) callsites also migrated and tests/kittest/button_sizing.rs not present at this SHA, there is nothing in the repo that fails when a future cleanup reverts to .min_size(...) or drops add_sized. A small kittest covering at least one of each helper plus a long-label case (label wider than DIALOG_BUTTON_MIN_SIZE) and a short-label case would lock in both the centering fix and the expected min footprint.

source: ['codex']

🤖 Fix this with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/ui/theme.rs`:
- [SUGGESTION] lines 848-915: Add a kittest harness for the new add_sized button-sizing contract
  `add_primary_button`, `add_primary_button_enabled`, `add_secondary_button`, and `add_danger_button` now route every callsite through `ui.add_sized(DIALOG_BUTTON_MIN_SIZE, ...)` instead of `Button::min_size(...)`. `add_sized` wraps the widget in a `centered_and_justified` inner layout — that is exactly what fixes the text-centering bug, but it is not a drop-in replacement for `min_size`: it imposes a fixed size from the parent rather than a floor on the widget's own desired size. The doc comments on these helpers correctly explain the new semantics, but with 17 direct `Button::new(...)` callsites also migrated and `tests/kittest/button_sizing.rs` not present at this SHA, there is nothing in the repo that fails when a future cleanup reverts to `.min_size(...)` or drops `add_sized`. A small kittest covering at least one of each helper plus a long-label case (label wider than `DIALOG_BUTTON_MIN_SIZE`) and a short-label case would lock in both the centering fix and the expected min footprint.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The helper migration looks coherent against the checked-out PR head, and I did not find a blocking behavioral regression in the migrated callsites from source review. The only issue worth surfacing is in the new kittest coverage: it verifies button sizing semantics, but it still does not protect the text-centering regression this PR is meant to address. That makes this a comment-level test gap, not a change blocker.

Reviewed commit: f9f24d3

🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `tests/kittest/button_sizing.rs`:
- [SUGGESTION] lines 13-110: The new kittests do not actually guard the button-centering regression
  All five tests assert only the outer button `Rect` width/height, and they do so inside `ui.horizontal(...)` layouts. That covers the new `add_sized(...)` sizing semantics, but it does not exercise the top-down/left layout that originally caused short labels to render left-shifted inside the button, and it never inspects text placement at all. A regression back to `ui.add(button.min_size(...))` could therefore reintroduce the user-visible centering bug while these tests still pass, so the core behavior this PR fixes remains effectively unguarded.

Comment on lines +13 to +110
#[test]
fn primary_button_grows_for_long_label() {
let mut harness = Harness::builder()
.with_size(egui::vec2(800.0, 200.0))
.build_ui(|ui| {
ui.horizontal(|ui| {
let _ = ComponentStyles::add_primary_button(ui, "Register Token Contract");
});
});
let rect = button_rect(&mut harness, "Register Token Contract");
eprintln!("Register Token Contract rect: {rect:?}");
assert!(
rect.width() > 120.0,
"long label must grow past the 96px floor (actual width: {})",
rect.width()
);
}

#[test]
fn primary_button_floors_short_label() {
let mut harness = Harness::builder()
.with_size(egui::vec2(800.0, 200.0))
.build_ui(|ui| {
ui.horizontal(|ui| {
let _ = ComponentStyles::add_primary_button(ui, "OK");
});
});
let rect = button_rect(&mut harness, "OK");
assert!(
rect.width() >= 90.0,
"short label must still honor ~96px min width (actual: {})",
rect.width()
);
assert!(
rect.height() >= 30.0,
"short label must honor ~36px min height (actual: {})",
rect.height()
);
}

#[test]
fn secondary_button_grows_for_long_label() {
let mut harness = Harness::builder()
.with_size(egui::vec2(800.0, 200.0))
.build_ui(|ui| {
ui.horizontal(|ui| {
let _ = ComponentStyles::add_secondary_button(
ui,
"Create Asset Lock Transaction",
false,
);
});
});
let rect = button_rect(&mut harness, "Create Asset Lock Transaction");
assert!(
rect.width() > 150.0,
"long label on secondary must grow (actual: {})",
rect.width()
);
}

#[test]
fn danger_button_grows_for_long_label() {
let mut harness = Harness::builder()
.with_size(egui::vec2(800.0, 200.0))
.build_ui(|ui| {
ui.horizontal(|ui| {
let _ = ComponentStyles::add_danger_button(ui, "Remove From Local Database");
});
});
let rect = button_rect(&mut harness, "Remove From Local Database");
assert!(
rect.width() > 150.0,
"long label on danger must grow (actual: {})",
rect.width()
);
}

#[test]
fn primary_button_enabled_grows_for_long_label() {
let mut harness = Harness::builder()
.with_size(egui::vec2(800.0, 200.0))
.build_ui(|ui| {
ui.horizontal(|ui| {
let _ = ComponentStyles::add_primary_button_enabled(
ui,
true,
"Register Token Contract",
);
});
});
let rect = button_rect(&mut harness, "Register Token Contract");
assert!(
rect.width() > 120.0,
"long label on enabled primary must grow (actual: {})",
rect.width()
);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The new kittests do not actually guard the button-centering regression

All five tests assert only the outer button Rect width/height, and they do so inside ui.horizontal(...) layouts. That covers the new add_sized(...) sizing semantics, but it does not exercise the top-down/left layout that originally caused short labels to render left-shifted inside the button, and it never inspects text placement at all. A regression back to ui.add(button.min_size(...)) could therefore reintroduce the user-visible centering bug while these tests still pass, so the core behavior this PR fixes remains effectively unguarded.

source: ['claude-general', 'codex-general']

🤖 Fix this with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `tests/kittest/button_sizing.rs`:
- [SUGGESTION] lines 13-110: The new kittests do not actually guard the button-centering regression
  All five tests assert only the outer button `Rect` width/height, and they do so inside `ui.horizontal(...)` layouts. That covers the new `add_sized(...)` sizing semantics, but it does not exercise the top-down/left layout that originally caused short labels to render left-shifted inside the button, and it never inspects text placement at all. A regression back to `ui.add(button.min_size(...))` could therefore reintroduce the user-visible centering bug while these tests still pass, so the core behavior this PR fixes remains effectively unguarded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants