fix(ui): let confirm-dialog buttons grow to fit wrapped labels (#6617)

* fix(ui): let confirm-dialog buttons grow to fit wrapped labels

The global `button { height:32px }` rule also applies to styledConfirm's
buttons. A label that wraps to two lines, such as "Delete chat and images",
"Launch anyway (CPU)" or a three-button dialog's alternate action, keeps
one line's height, so its second line renders below the button. On narrow
windows the dialog makes the buttons equal width, so this hits most
multi-word labels; it also happens on desktop, where the dialog box is
narrow too.

Give .styled-confirm-box .confirm-btn height:auto with min-height:32px.
Single-line buttons keep their current 32px.

Bumps the shared stylesheet/app cache token and the service worker cache
name, since a stylesheet changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(static): leave admin.js's cache tag unchanged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cache): keep upstream's service worker cache name format

dev's editor tests require CACHE_NAME to match
odysseus-v<N>-pr40-editor-precache, so keep the version bump and use
that suffix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
John W
2026-11-03 00:27:29 +00:00
committed by GitHub
co-authored by Claude Opus 5.5
parent cad14f81b9
commit 596e1421e4
4 changed files with 67 additions and 46 deletions
+7
View File
@@ -6481,6 +6481,13 @@ body.bg-pattern-ascii-fireflies {
display:flex; justify-content:flex-end; gap:8px; padding-top:6px;
border-top:1px solid var(--border); margin-top:4px;
}
/* The global `button { height:32px }` would hold a wrapped label (e.g.
"Delete chat and images") to one line's height, so its second line
spills out below the button. Let confirm buttons grow to fit; 32px
stays the minimum, so single-line buttons look the same. */
.styled-confirm-box .confirm-btn {
height:auto; min-height:32px;
}
@media (max-width:768px) {
.styled-confirm-box {
width: 85vw;
+23 -23
View File
@@ -247,32 +247,32 @@
real request is discarded and the font fetched a second time. -->
<link rel="preload" as="font" type="font/woff2" crossorigin href="/static/fonts/FiraCode-Regular.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin href="/static/fonts/FiraCode-SemiBold.woff2">
<link rel="stylesheet" href="/static/css/00-tokens.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/01-agent-chat.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/02-compare.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/03-agent-chat.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/04-memory.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/05-documents.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/06-admin-settings.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/07-documents.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/08-skills.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/09-gallery.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/10-cookbook.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/11-tasks.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/12-gallery.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/13-image-editor.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/14-email.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/15-notes.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/16-calendar.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/17-research.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/00-tokens.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/01-agent-chat.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/02-compare.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/03-agent-chat.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/04-memory.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/05-documents.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/06-admin-settings.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/07-documents.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/08-skills.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/09-gallery.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/10-cookbook.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/11-tasks.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/12-gallery.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/13-image-editor.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/14-email.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/15-notes.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/16-calendar.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/17-research.css?v=20261008confirmwrap1">
<!-- Panel stylesheets split out of style.css for maintainability. They are
eager and their order is load-bearing: the cascade is the concatenation of
these files in this order, so they must stay in this order here and in the
PRECACHE list in sw.js. None of them is lazy-loaded. -->
<link rel="stylesheet" href="/static/css/documents-gallery-editor.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/email-calendar-notes-tasks.css?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/cookbook-research-memory-settings.css?v=20261007detailscroll1">
<link rel="modulepreload" href="/static/app.js?v=20261007detailscroll1">
<link rel="stylesheet" href="/static/css/documents-gallery-editor.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/email-calendar-notes-tasks.css?v=20261008confirmwrap1">
<link rel="stylesheet" href="/static/css/cookbook-research-memory-settings.css?v=20261008confirmwrap1">
<link rel="modulepreload" href="/static/app.js?v=20261008confirmwrap1">
<link rel="modulepreload" href="/static/js/chat.js?v=20260917toolttft1">
<link rel="modulepreload" href="/static/js/ui.js?v=20260916largetoolscroll1">
<link rel="modulepreload" href="/static/js/sessions.js">
@@ -2709,7 +2709,7 @@
<script type="module" src="/static/js/censor.js"></script>
<script type="module" src="/static/js/settings.js?v=20260912writingstyle3"></script>
<script type="module" src="/static/js/assistant.js?v=20260912firefoxjscleanup1"></script>
<script type="module" src="/static/app.js?v=20261007detailscroll1"></script> <!-- app.js must be LAST -->
<script type="module" src="/static/app.js?v=20261008confirmwrap1"></script> <!-- app.js must be LAST -->
<script type="module" src="/static/js/init.js?v=20260829chatstyle12"></script>
<script type="module" src="/static/js/a11y.js"></script>
<script nonce="{{CSP_NONCE}}">if('serviceWorker' in navigator){navigator.serviceWorker.register('/static/sw.js?v=20260916autoscroll1').catch(()=>{});}</script>
+23 -23
View File
@@ -7,7 +7,7 @@
// - Other static assets (images/fonts/libs): cache-first with bg refresh.
// - API / non-GET: never cached.
// Bump CACHE_NAME whenever the precache list or SW logic changes.
const CACHE_NAME = 'odysseus-v1135-pr40-editor-precache';
const CACHE_NAME = 'odysseus-v1136-pr40-editor-precache';
// KaTeX resolves these from its own stylesheet, so caching the CSS without them
// gives offline math fallback glyphs instead of proper typesetting.
@@ -40,28 +40,28 @@ const KATEX_FONTS = [
const PRECACHE = [
'/static/js/compare/sse.js',
'/',
'/static/css/00-tokens.css?v=20261007detailscroll1',
'/static/css/01-agent-chat.css?v=20261007detailscroll1',
'/static/css/02-compare.css?v=20261007detailscroll1',
'/static/css/03-agent-chat.css?v=20261007detailscroll1',
'/static/css/04-memory.css?v=20261007detailscroll1',
'/static/css/05-documents.css?v=20261007detailscroll1',
'/static/css/06-admin-settings.css?v=20261007detailscroll1',
'/static/css/07-documents.css?v=20261007detailscroll1',
'/static/css/08-skills.css?v=20261007detailscroll1',
'/static/css/09-gallery.css?v=20261007detailscroll1',
'/static/css/10-cookbook.css?v=20261007detailscroll1',
'/static/css/11-tasks.css?v=20261007detailscroll1',
'/static/css/12-gallery.css?v=20261007detailscroll1',
'/static/css/13-image-editor.css?v=20261007detailscroll1',
'/static/css/14-email.css?v=20261007detailscroll1',
'/static/css/15-notes.css?v=20261007detailscroll1',
'/static/css/16-calendar.css?v=20261007detailscroll1',
'/static/css/17-research.css?v=20261007detailscroll1',
'/static/css/documents-gallery-editor.css?v=20261007detailscroll1',
'/static/css/email-calendar-notes-tasks.css?v=20261007detailscroll1',
'/static/css/cookbook-research-memory-settings.css?v=20261007detailscroll1',
'/static/app.js?v=20261007detailscroll1',
'/static/css/00-tokens.css?v=20261008confirmwrap1',
'/static/css/01-agent-chat.css?v=20261008confirmwrap1',
'/static/css/02-compare.css?v=20261008confirmwrap1',
'/static/css/03-agent-chat.css?v=20261008confirmwrap1',
'/static/css/04-memory.css?v=20261008confirmwrap1',
'/static/css/05-documents.css?v=20261008confirmwrap1',
'/static/css/06-admin-settings.css?v=20261008confirmwrap1',
'/static/css/07-documents.css?v=20261008confirmwrap1',
'/static/css/08-skills.css?v=20261008confirmwrap1',
'/static/css/09-gallery.css?v=20261008confirmwrap1',
'/static/css/10-cookbook.css?v=20261008confirmwrap1',
'/static/css/11-tasks.css?v=20261008confirmwrap1',
'/static/css/12-gallery.css?v=20261008confirmwrap1',
'/static/css/13-image-editor.css?v=20261008confirmwrap1',
'/static/css/14-email.css?v=20261008confirmwrap1',
'/static/css/15-notes.css?v=20261008confirmwrap1',
'/static/css/16-calendar.css?v=20261008confirmwrap1',
'/static/css/17-research.css?v=20261008confirmwrap1',
'/static/css/documents-gallery-editor.css?v=20261008confirmwrap1',
'/static/css/email-calendar-notes-tasks.css?v=20261008confirmwrap1',
'/static/css/cookbook-research-memory-settings.css?v=20261008confirmwrap1',
'/static/app.js?v=20261008confirmwrap1',
'/static/js/storage.js',
'/static/js/appConfig.js',
'/static/js/ui.js?v=20260916largetoolscroll1',
+14
View File
@@ -58,6 +58,20 @@ def test_styled_confirm_cancel_or_close_label_is_shifted_without_moving_button()
assert "top:2px;" in rule
def test_styled_confirm_buttons_grow_to_fit_wrapped_labels():
# The global `button { height:32px }` held a two-line label (e.g.
# "Delete chat and images") to one line's height, so its second line
# rendered below the button. Confirm buttons must be allowed to grow,
# with 32px kept as the minimum.
css = app_css()
assert re.search(r"(^|\n)\s*button\s*\{\s*height:32px;", css)
rule_start = css.index(".styled-confirm-box .confirm-btn {")
rule = css[rule_start:rule_start + 120]
assert "height:auto;" in rule
assert "min-height:32px;" in rule
def test_styled_dialogs_manage_focus():
# A dialog is only really accessible if it restores focus to the trigger on
# close and traps Tab while open. Both styledConfirm and styledPrompt should