Skip to content

fix(mcp): use ActionButton for install/update modal buttons (#10517)#10586

Merged
lucieleblanc merged 1 commit into
warpdotdev:masterfrom
maxmilian:fix/10517-mcp-button-styling
May 29, 2026
Merged

fix(mcp): use ActionButton for install/update modal buttons (#10517)#10586
lucieleblanc merged 1 commit into
warpdotdev:masterfrom
maxmilian:fix/10517-mcp-button-styling

Conversation

@maxmilian
Copy link
Copy Markdown
Contributor

@maxmilian maxmilian commented May 10, 2026

Description

The MCP install/update modal primary buttons (Install / Update) used with_custom_label so they could include a icon next to the text, and hardcoded the icon and label colors to theme.active_ui_text_color(). That helper resolves to main_text_color(surface_2()) — it picks for contrast against the surrounding modal surface, not against the accent-colored button background the label actually sits on. On themes where surface_2 and accent have similar luminance, the label became visually washed out (issue #10517).

This PR switches the icon, icon border, and label text inside both modals' accent-button labels to:

appearance.theme().main_text_color(appearance.theme().accent_button_color())

That's the same contrast-aware color the standard accent button text label uses internally — see warp_core::ui::builder::default_button_styles for ButtonVariant::Accent (crates/warp_core/src/ui/builder.rs:237). accent_button_color() returns the exact accent.blend(foreground.with_opacity(...)) background formula default_button_styles uses for the button surface, so this matches what the button itself does for its native text labels.

The Update button can also be disabled when no rows are selected. In that state the button surface flips to surface_3 per disabled_button_styles (crates/warp_core/src/ui/builder.rs:243-245), so the custom label color branches to disabled_text_color(surface_3()) to match. The Install button has no disabled state, so its label always uses the accent-button color.

The cancel buttons (rendered with ButtonVariant::Text, sitting on the modal surface) and the modal title / field labels are intentionally left alone — active_ui_text_color() is correct for them.

Linked Issue

Fixes #10517.

  • The linked issue is labeled ready-to-spec or ready-to-implement.
  • Where appropriate, screenshots or a short video of the implementation are included below (especially for user-visible or UI changes).

Testing

  • I have manually tested my changes locally with ./script/run

Built WarpOss.app from this branch, opened Settings → MCP Servers → clicked + on a gallery preset (Datadog) to trigger the install modal. The Install button now renders with the correct contrast-aware foreground (white text + icon on the accent-blue background) — matching the "what it should be" mock in the issue.

Update modal uses identical code (separate copy in update_modal.rs); the same fix is applied there. The disabled-state branch was not manually screenshotted because triggering the Update modal requires a cloud-synced MCP template with a newer published version than the locally-installed copy, which the OSS dev build cannot easily reproduce. The disabled label color is sourced directly from disabled_button_styles's standard helper (disabled_text_color(surface_3())), so it matches every other disabled accent button in the app — the regression Oz flagged was specifically that the enabled color was leaking into the disabled state, and that branch is now keyed off the same has_selection flag the existing .disabled() call uses, so the two states cannot diverge.

Screenshots / Videos

After (this PR — install modal triggered via Datadog preset):

MCP install modal — Install button with correct contrast

For comparison, the broken state ("what it is") and target state ("what it should be") are both captured in issue #10517.

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

@cla-bot cla-bot Bot added the cla-signed label May 10, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 10, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 10, 2026

@maxmilian

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 10, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR updates the custom Install and Update accent-button labels to choose the icon, border, and text color against accent_button_color(), which matches the default accent button contrast behavior. I did not find code-level correctness or security issues in the changed hunks.

Concerns

  • This is a user-visible UI styling change, but the PR description does not include an attached screenshot or recording; the Screenshots / Videos section only says one will be attached later. Manual testing is required for changes that can be manually tested. Please include screenshots or a screen recording that show it working end to end, or justify why manual testing is not possible.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@maxmilian
Copy link
Copy Markdown
Contributor Author

/oz-review
截圖 2026-05-10 中午12 16 33

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 10, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @lucieleblanc.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 10, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot dismissed their stale review May 10, 2026 04:28

Oz no longer requests changes for this pull request after the latest automated review.

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR updates the MCP installation and update modal custom accent-button labels to derive icon, border, and text colors from the accent button background instead of the surrounding modal surface.

Concerns

No correctness or security concerns found in the changed lines.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot requested a review from lucieleblanc May 10, 2026 04:28
oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 10, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR updates the custom Install/Update accent-button labels to use text color selected against the accent button background. The enabled install path is consistent with the standard accent button foreground.

Concerns

  • The update modal reuses the accent-background label color even when the Update button is disabled after all updates are deselected; because custom labels bypass the button's disabled font color, the disabled state can render with enabled/accent foreground on a disabled surface.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

// The icon and label sit on the accent-button background, so colors
// must be picked for contrast against that background rather than the
// surrounding surface — see issue #10517.
let accent_label_color = appearance
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ [IMPORTANT] This fixed accent-background foreground is also used when update_button_builder.disabled() runs below; custom labels do not inherit the button's disabled font color, so deselecting all updates can render an enabled/accent-looking label on the disabled surface. Choose the label/icon/border color from the disabled button background when has_selection is false, or use a label path that lets the button apply state colors.

maxmilian added a commit to maxmilian/warp that referenced this pull request May 10, 2026
…elected

Address oz-for-oss review on warpdotdev#10586. When the Update button is disabled
(`if !has_selection { ... .disabled() }`), the button surface flips to
`surface_3` per `disabled_button_styles` in `warp_core::ui::builder`, but
the custom label color was still being computed against the enabled
accent-button background — so the icon and text rendered with the wrong
contrast on the disabled grey surface.

Compute `has_selection` before constructing the label, and branch the
custom label color to `disabled_text_color(surface_3())` in the disabled
state. Install modal is unaffected (its accent button has no disabled
state).
@maxmilian
Copy link
Copy Markdown
Contributor Author

Addressed the disabled-state regression — when no rows are selected, the custom label now uses disabled_text_color(surface_3()) to match the disabled button surface. /oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 10, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 10, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR updates the custom labels for the MCP install/update modal accent buttons so their text, icon, and icon border use contrast-aware colors against the button background, including the disabled update-button state.

Concerns

  • This is a user-visible styling change, but the PR description does not include attached screenshots or a screen recording demonstrating the install/update modal button contrast after the change. Manual testing is required for changes that can be manually tested. Please include screenshots or a screen recording that show it working end to end, or justify why manual testing is not possible.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@maxmilian
Copy link
Copy Markdown
Contributor Author

Description has been updated with the install-modal screenshot inline (it was in a comment before) and a justification for not screenshotting the disabled-state Update button. /oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 10, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @lucieleblanc.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot dismissed stale reviews from themself May 10, 2026 04:51

Oz no longer requests changes for this pull request after the latest automated review.

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR updates the custom Install and Update modal button labels to use foreground colors selected against the actual accent or disabled button surfaces. The enabled and disabled Update button paths now share the same selection state used for .disabled().

Concerns

  • None identified.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@lucieleblanc lucieleblanc left a comment

Choose a reason for hiding this comment

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

Thank you for tackling this issue! Looking at this code, I think the best change would be to convert this modal to use the existing ActionButton component so that we don't need to manually define any theme + styling for it.

Also -- since this is theming and accessibility-related, please include screenshots that show multiple themes: dark, light, high-contrast, different colors, etc. That makes it easy to verify the changes will work for a broad range of themes.

Comment on lines +384 to +385
// Disable the update button if no updates are selected (matches the
// `accent_label_color` branch chosen above).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please restore this comment to the shorter form; the parenthetical doesn't provide useful information.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the better fix here would be to convert this modal to render an ActionButton instead of building a new button component from scratch. Ideally, we shouldn't need custom color/theming logic for this.

maxmilian added a commit to maxmilian/warp that referenced this pull request May 12, 2026
…review)

Per code-review feedback on warpdotdev#10586, the MCP installation and update modal
action rows are rewritten to use the existing `ActionButton` component
with `PrimaryTheme` + `NakedTheme` instead of hand-rolling the accent
button. This removes the manual contrast-color juggling that originally
shipped to fix warpdotdev#10517 — `PrimaryTheme` already routes the label color
through `theme.font_color(theme.accent())`, which is the same accent-aware
path other primary buttons across the app already use, so the original
bug is fixed by adopting the shared component.

Highlights:

- `InstallationModalBody` and `UpdateModalBody` now hold typed-action
  `ViewHandle<ActionButton>` for Cancel and the primary button, created
  in `new(ctx)` and rendered via `ChildView`. The previous mouse-state
  fields, manual icon/border construction, and custom Text labels are
  gone.
- The Enter keybinding hint (previously a hand-built `↩` icon stitched
  next to the label) now uses `ActionButton::with_keybinding`. This is
  visual only — the hint does not register a keystroke handler — so the
  existing dispatch paths (`handle_editor_event` on the install modal,
  the Update button's own `on_click` on the update modal) cannot
  double-fire.
- `UpdateModalBody`'s disabled-when-no-selection behavior is now driven
  by `update_button.set_disabled(...)` from a small helper
  `refresh_update_button_disabled`, called from `set_installation`,
  `clear`, and the `SelectOption` action handler. The disabled palette
  comes from `ActionButton`'s default disabled theme rather than
  `PrimaryTheme`.
- `InstallationModalBody::new()` and `UpdateModalBody::new()` now take a
  `&mut ViewContext<Self>` so the buttons can be registered as typed
  action views; their two callers in `mcp_servers_page.rs` and
  `list_page.rs` are updated accordingly. `UpdateModalBody::set_installation`
  and `clear` likewise grow a `ctx` parameter so the disabled state stays
  in sync.

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

截圖 2026-05-12 上午8 32 46 截圖 2026-05-12 上午8 33 44 截圖 2026-05-12 上午8 57 08 截圖 2026-05-12 上午8 51 14

@lucieleblanc — addressed both review points:

  1. Refactored to ActionButton in 4f92a51. Both InstallationModalBody and UpdateModalBody now
    hold typed-action ViewHandle<ActionButton> for Cancel + the primary button, with NakedTheme /
    PrimaryTheme. The Enter hint is now ActionButton::with_keybinding (visual only — actual Enter
    dispatch is unchanged). Manual color/icon construction is gone.

  2. Multi-theme manual testing below. Built locally via ./script/run (OSS channel) and verified the
    Install modal across:

    • Default Dark — accent blue on dark surface, label picks black for contrast.
    • Default Light — same blue accent, label still black, modal surface inverted.
    • Custom: yellow accent on dark surface — the original Incorrect primary buttons color on MCP update/install modal #10517 bug's worst case (dark theme + bright
      accent → hardcoded white label became invisible). PrimaryTheme correctly resolves a black label.
    • Custom: magenta accent on dark surface — different hue, same correct contrast resolution.

    The PrimaryTheme.text_color path runs theme.font_color(theme.accent()), so the label color tracks
    accent-luminance dynamically — the four screenshots cover the corners of the contrast space (high/low
    luminance accent across light/dark surfaces).

@maxmilian
Copy link
Copy Markdown
Contributor Author

/oz-review

@lucieleblanc lucieleblanc self-requested a review May 13, 2026 18:53
Copy link
Copy Markdown
Contributor

@lucieleblanc lucieleblanc left a comment

Choose a reason for hiding this comment

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

Excellent, thank you! Please rebase, clean up the comments, and I'll merge.

Comment on lines +83 to +94
// Cancel and Install both delegate to the existing typed-action
// handler so the modal-level routing (event emission, error
// surfacing) is unchanged. The Install button shows the Enter
// keybinding as a visual hint via `ActionButton`'s built-in
// keystroke rendering, replacing the prior hand-rolled `↩` icon.
// The hint does not register a keystroke handler — Enter is
// dispatched by the focused input editor through
// `handle_editor_event` below — so adding it here cannot cause a
// double-fire of `InstallationModalBodyAction::Install`. Theming
// (accent background, contrast-aware label color) is now driven
// entirely by `PrimaryTheme`, which fixes #10517 by deferring to
// the same accent-button color lookup the rest of the app uses.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please remove this comment.

Comment on lines +466 to +467
// Buttons own their own theming via `ActionButton` — see `new()` for
// construction and the rationale for this refactor (issue #10517).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean up

Comment on lines +59 to +72
// Cancel and Update both delegate to the existing typed-action
// handler so the modal-level routing (event emission, error
// surfacing) is unchanged. The Update button shows the Enter
// keybinding as a visual hint via `ActionButton`'s built-in
// keystroke rendering — the hint does not register a keystroke
// handler, so `UpdateModalBodyAction::Update` is only ever
// dispatched by the button's own `on_click` below. Theming
// (accent background, contrast-aware label color) comes from
// `PrimaryTheme`; the disabled state when nothing is selected is
// driven by `ActionButton::set_disabled` (toggled below in
// `refresh_update_button_disabled`), which uses the component's
// own disabled palette. Together this fixes #10517 by deferring
// to the same accent-button + disabled lookups the rest of the
// app uses.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove

Comment on lines +356 to +360
// Buttons own their own theming and disabled state via
// `ActionButton`. See `new()` for construction and the rationale for
// this refactor (#10517); see `refresh_update_button_disabled` for
// how the Update button's disabled state stays in sync with the
// selection.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean up

…arpdotdev#10517)

Convert the MCP install and update modal action buttons to the shared
ActionButton component instead of hand-rolled buttons with custom
theming. This fixes the accent-button label/icon contrast (warpdotdev#10517) by
deferring to the same accent-button color and disabled-state lookups the
rest of the app already uses; the Update button's disabled state is
driven by ActionButton::set_disabled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@maxmilian maxmilian force-pushed the fix/10517-mcp-button-styling branch from 4f92a51 to 4718103 Compare May 22, 2026 01:16
@maxmilian
Copy link
Copy Markdown
Contributor Author

@lucieleblanc done — rebased onto latest master and cleaned up the comments you flagged (squashed to a single commit). cargo check/clippy/fmt all pass.

One heads-up from the rebase: #10166 (by @acarl005) merged on May 11 and also closes #10517 with a minimal fix — it switches the button label/icon font_color to the accent-aware color while keeping the hand-rolled buttons. That overlapped this PR's render_action_buttons, so the rebase had a conflict there. I resolved it by keeping this PR's refactor, since converting the modals to ActionButton (per your earlier review) fully replaces the code #10166 patched — the accent-aware coloring now comes from ActionButton/PrimaryTheme rather than a manual font_color.

So #10517 is technically already fixed on master; this PR remains the deeper ActionButton refactor you asked for. Happy to proceed with the merge, but wanted to flag the overlap in case you'd rather close this as superseded — your call.

@lucieleblanc lucieleblanc changed the title fix(mcp): use accent-aware text color for install/update modal buttons (#10517) fix(mcp): use ActionButton for install/update modal buttons (#10517) May 29, 2026
Copy link
Copy Markdown
Contributor

@lucieleblanc lucieleblanc left a comment

Choose a reason for hiding this comment

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

We should be using ActionButtons anyway, so this is still good! I've changed the title of the PR to reflect the change. Thanks!

@lucieleblanc lucieleblanc merged commit 836b73c into warpdotdev:master May 29, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect primary buttons color on MCP update/install modal

2 participants