fix(frontend): unify modal close button and title styling#747
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📸 Snapshot Test ReportWarning Snapshot comparison step crashed (timeout, OOM, or runner error) — diff results below may be incomplete or absent. ✅ 13 snapshots changed — acknowledged via the
🔴 Changed snapshots (13)
|
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-cloud-advanced-open
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-cloud-no-key-disabled
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-form-partially-filled
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-local-ready
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-two-column-layout
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-add-whitespace-host-disabled
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-edit-prefilled
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-manage-two-listed
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backends — 2 snapshots
backend-add-modal
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
backend-manage-modal
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
mcp-page
mcp-slack-install-2-modal
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
settings-page
add-backend-modal
| Expected (main) | Actual (PR) | Diff |
|---|---|---|
![]() |
![]() |
![]() |
✅ Unchanged snapshots (60)
archived-conversation
- conversation-panel-with-archived-badges
- conversation-view-archived
- conversation-view-sandbox-error
automations
- automations-delete-modal
- automations-list-active-inactive
- automations-no-automations
- automations-search-no-results
backends-extended
- backend-add-cloud-with-key-enabled
- backend-add-invalid-url-disabled
- backend-add-name-only-disabled
- backend-after-switch
- backend-cancel-nothing-saved
- backend-dropdown-two-backends
- backend-manage-after-removal
- backend-remove-cancelled
- backend-remove-confirmation
- backend-switch-overlay
backends
- backend-selector-open
changes-tab
- changes-deleted-file
- changes-diff-viewer
- changes-empty
collapsible-thinking
- reasoning-content-collapsed
- reasoning-content-expanded
- think-action-collapsed
- think-action-expanded
mcp-page
- mcp-custom-server-1-editor-open
- mcp-custom-server-2-url-filled
- mcp-custom-server-3-all-filled
- mcp-custom-server-4-installed
- mcp-custom-server-editor
- mcp-empty-installed
- mcp-search-filtered
- mcp-slack-install-1-marketplace
- mcp-slack-install-3-filled
- mcp-slack-install-4-installed
onboarding
- onboarding-step-0-choose-agent
- onboarding-step-1-check-backend
- onboarding-step-2-setup-llm
- onboarding-step-3-say-hello
projects-workspace-browser
- projects-workspace-browser
settings-page
- analytics-consent-modal
- home-screen
- settings-app-page
- settings-page
settings-secrets
- secrets-add-form-filled
- secrets-add-form
- secrets-after-save
- secrets-delete-confirm
- secrets-list
settings-verification
- condenser-settings
- verification-settings-off
- verification-settings-on
sidebar
- sidebar-collapsed
- sidebar-conversation-panel
- sidebar-filter-menu
skills-page
- skills-empty
- skills-loaded
- skills-no-match
- skills-search-filtered
- skills-type-filter
Generated by the Snapshot Tests workflow. This comment was created by an AI agent (OpenHands) on behalf of the repo maintainers.
|
PR Review by OpenHands / pr-review (pull_request) is failing. I will merge this pull request for now. If any issues are found, I will address them in follow-up pull requests. Thank you! 🙏 |







































Why
Problem
After
ac86d3ec, two close-button conventions coexisted in the app:InstallServerModal, etc.) used the inline white LucideX+text-whitetitle pattern.SettingsModal, the confirmation modals, the various*ModalHeadercomponents, etc.) used different patterns or no close icon at all.The designer asked us to:
ac86d3ec's visual direction entirely.ModalCloseButton(grayModalCloseIcon, absolute top-right) and a plain<h2>title that sits on its own row (not on the close button's row).Expected behavior
All modals in the app render:
<ModalCloseButton />(usesModalCloseIconSVG,text-tertiary-altdefault, hovers to white) positioned absolutely at top-right of the modal container.<h2>title —text-lg font-semibold, notext-whiteoverride, no<BaseModalTitle>.flex justify-betweenrow sharing space with the close icon). Title getspr-6(or wider on padded sections) to leave room for the absolute close button.Affected modals
ac86d3ectouched (CustomServerEditor,AddSkillModal,SkillDetailModal,AddAutomationModal,InstallServerModal) — revert to pre-ac86d3ecstate.<BaseModalTitle>and weren't part ofac86d3ec— bring them onto the same gray-icon / plain-<h2>pattern:BackendFormModal(add + edit),ManageBackendsModal,OpenRepositoryModal,OpenWorkspaceDialog,OpenRepositoryDialog,PluginLaunchModal, and the four*ModalHeadercomponents (SkillsModalHeader,HooksModalHeader,SystemMessageHeader,MetricsModalHeader).InstallServerModal's legacy inline whiteXbutton (a duplicate alongsideModalCloseButton) — removed so only the gray button remains.Out of scope
SettingsModal,FolderBrowserModal, confirmation modals). No change.SkillsModalHeader/HooksModalHeader, row-action buttons, etc.). Stay as-is.Acceptance criteria
<ModalCloseButton />for its close affordance.lucide-react'sXorreact-icons/io5'sIoClosefor a modal close button.ICON_BUTTON_CLASSsolely for a modal close button (Skills/Hooks headers may keep theirs since the refresh button still uses it).BaseModalTitleis no longer used inBackendFormModalorManageBackendsModal; both render<h2 className="text-lg font-semibold">instead.InstallServerModalshows exactly one close button.npm run typecheckandnpm run lintpass.Issue Number
Resolves #746
How to Test
agent-server-guirepository.Demo Video
app-1913.mov
Type
Notes
Risk
Medium. Pure UI/layout refactor — no behavior change in any of the affected modals. The biggest risk is positioning: absolute
ModalCloseButtonrequiresposition: relativeon its containing element, which this PR adds in every necessary spot. Thepr-6/pr-10/pr-12clearances on titles and header rows have been chosen to keep them clear of the corner button at standard modal widths; unusually long translated titles may visually approach the close icon but won't be physically clipped.🐳 Docker images for this PR
• GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas
ghcr.io/openhands/agent-canvasghcr.io/openhands/agent-server:1.23.0-pythonopenhands-automation==1.0.0a3f72ae98ace1b6c3be921a755d62f37fd2aacd000Pull (multi-arch manifest)
# Multi-arch manifest — Docker automatically pulls the correct architecture docker pull ghcr.io/openhands/agent-canvas:sha-f72ae98Run
All tags pushed for this build
About Multi-Architecture Support
sha-f72ae98) is a multi-arch manifest supporting both amd64 and arm64sha-f72ae98-amd64) are also available if needed