diff --git a/.jules/palette.md b/.jules/palette.md index 9bd1949388..7978f1fd73 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -22,3 +22,6 @@ ## 2024-05-24 - Confirm Destructive Actions **Learning:** Destructive actions that result in data loss or immediate page reloads (like resetting settings) must have a confirmation prompt to prevent accidental activation and poor UX. **Action:** Always add a confirmation step (e.g., using `confirm()`) or a custom confirmation modal before executing destructive actions or operations that force a full page reload. +## 2024-11-20 - Added keyboard shortcuts to primary prompt inputs +**Learning:** Added visual keyboard hints using `` tags tied directly to `aria-keyshortcuts` on the input field rather than the visual hints to ensure screen reader accessibility, alongside `aria-hidden="true"` on the hints. +**Action:** Always map explicit DOM keyboard events along with accessible key hints for form-based interactions. diff --git a/examples/wasm/browser/index.html b/examples/wasm/browser/index.html index e0717f1b91..345f61f418 100644 --- a/examples/wasm/browser/index.html +++ b/examples/wasm/browser/index.html @@ -261,6 +261,20 @@ .tab-content.active { display: block; } + + .kbd-hint { + display: inline-block; + padding: 2px 6px; + font-size: 11px; + line-height: 1.2; + color: #6c757d; + background-color: #f8f9fa; + border: 1px solid #dee2e6; + border-radius: 4px; + box-shadow: inset 0 -1px 0 #dee2e6; + margin-left: 8px; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + } @@ -298,8 +312,8 @@

Basic Text Generation

- - + +
@@ -343,8 +357,8 @@

Basic Text Generation

Streaming Text Generation

- - + +
@@ -392,8 +406,8 @@

Web Workers Integration

- - + +
diff --git a/examples/wasm/browser/main.js b/examples/wasm/browser/main.js index b15b93970c..5519ff246f 100644 --- a/examples/wasm/browser/main.js +++ b/examples/wasm/browser/main.js @@ -44,6 +44,9 @@ async function initApp() { loadSettings(); updateProgress(90); + // Setup keyboard shortcuts + setupKeyboardShortcuts(); + updateStatus('WebAssembly module initialized successfully!', 'success'); updateProgress(100); @@ -688,6 +691,42 @@ document.getElementById('top-p').addEventListener('input', function() { document.getElementById('top-p-value').textContent = this.value; }); +// Setup keyboard shortcuts for textareas +function setupKeyboardShortcuts() { + const handleShortcut = (e, buttonId) => { + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { + e.preventDefault(); + const btn = document.getElementById(buttonId); + if (btn && !btn.disabled) { + btn.click(); + } + } + }; + + const promptTextarea = document.getElementById('prompt'); + if (promptTextarea) { + promptTextarea.addEventListener('keydown', (e) => handleShortcut(e, 'generate')); + } + + const streamingPromptTextarea = document.getElementById('streaming-prompt'); + if (streamingPromptTextarea) { + streamingPromptTextarea.addEventListener('keydown', (e) => { + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { + e.preventDefault(); + const startBtn = document.getElementById('start-streaming'); + if (startBtn && !startBtn.disabled) { + startBtn.click(); + } + } + }); + } + + const workerPromptTextarea = document.getElementById('worker-prompt'); + if (workerPromptTextarea) { + workerPromptTextarea.addEventListener('keydown', (e) => handleShortcut(e, 'worker-generate')); + } +} + // Setup keyboard navigation for tabs function setupTabNavigation() { const tabsContainer = document.querySelector('.tabs');