Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<kbd>` 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.
26 changes: 20 additions & 6 deletions examples/wasm/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
</style>
</head>
<body>
Expand Down Expand Up @@ -298,8 +312,8 @@ <h3>Basic Text Generation</h3>
</div>

<div class="input-group">
<label for="prompt">Prompt:</label>
<textarea id="prompt" placeholder="Enter your prompt here...">Hello, I am a BitNet model running in your browser!</textarea>
<label for="prompt">Prompt: <kbd class="kbd-hint" aria-hidden="true">Ctrl+Enter</kbd></label>
<textarea id="prompt" placeholder="Enter your prompt here..." aria-keyshortcuts="Control+Enter">Hello, I am a BitNet model running in your browser!</textarea>
</div>

<div class="controls">
Expand Down Expand Up @@ -343,8 +357,8 @@ <h3>Basic Text Generation</h3>
<h3>Streaming Text Generation</h3>

<div class="input-group">
<label for="streaming-prompt">Prompt:</label>
<textarea id="streaming-prompt" placeholder="Enter your prompt for streaming...">Once upon a time, in a world where AI models run in browsers,</textarea>
<label for="streaming-prompt">Prompt: <kbd class="kbd-hint" aria-hidden="true">Ctrl+Enter</kbd></label>
<textarea id="streaming-prompt" placeholder="Enter your prompt for streaming..." aria-keyshortcuts="Control+Enter">Once upon a time, in a world where AI models run in browsers,</textarea>
</div>

<div class="controls">
Expand Down Expand Up @@ -392,8 +406,8 @@ <h3>Web Workers Integration</h3>
</div>

<div class="input-group">
<label for="worker-prompt">Prompt:</label>
<textarea id="worker-prompt" placeholder="Enter prompt for worker processing...">This text is being generated in a Web Worker to keep the main thread responsive.</textarea>
<label for="worker-prompt">Prompt: <kbd class="kbd-hint" aria-hidden="true">Ctrl+Enter</kbd></label>
<textarea id="worker-prompt" placeholder="Enter prompt for worker processing..." aria-keyshortcuts="Control+Enter">This text is being generated in a Web Worker to keep the main thread responsive.</textarea>
</div>

<div class="input-group">
Expand Down
39 changes: 39 additions & 0 deletions examples/wasm/browser/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ async function initApp() {
loadSettings();
updateProgress(90);

// Setup keyboard shortcuts
setupKeyboardShortcuts();

updateStatus('WebAssembly module initialized successfully!', 'success');
updateProgress(100);

Expand Down Expand Up @@ -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');
Expand Down
Loading