Skip to content

Commit fced1d9

Browse files
authored
Merge pull request #14 from Sisyphean-a/palette/scratchpad-smart-copy-5734841487803236292
🎨 Palette: Smart Copy for Scratchpad
2 parents 2661fe1 + e44f7ec commit fced1d9

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

.Jules/palette.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@
1313
## 2025-10-26 - Scratchpad Focus Management
1414
**Learning:** In VS Code Webviews, automatically returning focus to the main input (e.g. textarea) after a button click (like "Copy" or "Remove Empty Lines") can be disorienting for screen reader users and keyboard navigators. It interrupts the natural tab order and prevents users from hearing status updates on the button they just clicked.
1515
**Action:** Avoid calling `.focus()` on the input element immediately after secondary actions unless the primary purpose of the action is to prepare for immediate typing. For status updates (like "Copied!"), keep focus on the trigger element.
16+
17+
## 2025-01-21 - Smart Copy Actions in Webviews
18+
**Learning:** Users often expect "Copy" buttons to respect their active text selection, even if the button click moves focus away from the input. Fortunately, `textarea.selectionStart/End` properties persist even when the element loses focus.
19+
**Action:** When implementing "Copy" actions in Webviews, check for selection first. If present, copy only the selection and update the button feedback (e.g. "Copied Selection!") to confirm the specific action.

src/features/scratchpad/scratchpad.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,23 @@
216216

217217
// Copy Button Logic
218218
btnCopy.addEventListener('click', () => {
219-
const content = textarea.value;
219+
const start = textarea.selectionStart;
220+
const end = textarea.selectionEnd;
221+
const hasSelection = start !== end;
222+
const content = hasSelection ? textarea.value.substring(start, end) : textarea.value;
223+
220224
if (!content) return;
221225

222226
vscode.postMessage({
223227
type: 'copyToClipboard',
224228
content: content
225229
});
226230

227-
btnCopy.textContent = 'Copied!';
228-
btnCopy.setAttribute('aria-label', 'Copied to Clipboard');
231+
const feedbackText = hasSelection ? 'Copied Selection!' : 'Copied!';
232+
const ariaLabel = hasSelection ? 'Copied Selection to Clipboard' : 'Copied to Clipboard';
233+
234+
btnCopy.textContent = feedbackText;
235+
btnCopy.setAttribute('aria-label', ariaLabel);
229236

230237
if (copyTimeoutId) clearTimeout(copyTimeoutId);
231238
copyTimeoutId = setTimeout(resetCopyButton, 2000);

0 commit comments

Comments
 (0)