commit 613126629ab21280ab6087e3c5e36a5e3788ae2e
parent 69bb2df5e35b1862672886a267e87f0fc8a2c7b4
Author: claude-cdn-bot <claude-bot@users.noreply.github.com>
Date: Tue, 13 Oct 2026 08:39:17 +0000
feat(ui): icon-only copy buttons on phones
The small 'Copy' buttons (Links rows, preview 'Copy contents') show just the universal copy icon at <=640px,
which gives the link boxes ~100px more room. They keep accessible names (aria-label) and a 42px tap target; the
main 'Copy link' button keeps its label, and desktop is unchanged. 6 new browser checks (80 total).
Diffstat:
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/app/static/app.css b/app/static/app.css
@@ -924,6 +924,11 @@ html[data-js] .preview--image.is-loading::after, html[data-js] .preview--pdf.is-
.link-row__label { grid-column: 1 / -1; }
.link-row__label small { display: inline; margin-left: 0.4rem; }
.toc ol { columns: 1; }
+ /* small copy buttons become icon-only: the copy glyph is universal, and the link box gets the room back */
+ .link-row .btn > span, [data-copy-preview] > span { display: none; }
+ .link-row .btn-sm, .preview__bar .btn-sm { width: 2.6rem; min-width: 2.6rem; height: 2.6rem; padding: 0; }
+ .preview__bar { padding-right: 0.5rem; }
+ .sk-btn { width: 2.6rem; height: 2.6rem; }
.list-item { padding-left: 0.85rem; padding-right: 0.85rem; }
.item-name { gap: 0.65rem; }
.listing-toolbar { flex-wrap: nowrap; }
diff --git a/app/static/app.js b/app/static/app.js
@@ -42,6 +42,7 @@
alert: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',
file: '<svg class="file-icon-list" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>',
folder: '<svg class="folder-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>',
+ copy: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>',
download: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></svg>',
};
@@ -804,7 +805,7 @@
pre.appendChild(code);
const bar = document.createElement('div');
bar.className = 'preview__bar';
- bar.innerHTML = '<span></span><button type="button" class="btn btn-sm" data-copy-preview><span>Copy contents</span></button>';
+ bar.innerHTML = '<span></span><button type="button" class="btn btn-sm" data-copy-preview aria-label="Copy file contents" title="Copy file contents">' + ICON.copy + '<span>Copy contents</span></button>';
bar.firstChild.textContent = lines.length + ' line' + (lines.length !== 1 ? 's' : '') + (truncated ? ' · preview truncated' : '');
// everything is built off-screen above, then swapped in at once (replacing the skeleton)
box.replaceChildren(bar, pre);