experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: card button visibility, search interactions, remove-from-group positioning

- Fix card action button contrast in dark mode: use --base04 across all extensions
- Fix search checkbox toggle: refresh tags from datastore before re-render
- Add Delete/Backspace shortcut to delete items in search view
- Position remove-from-group button left of delete in group detail view

+61 -16
+1 -1
features/entities/home.css
··· 265 265 border: none; 266 266 border-radius: 4px; 267 267 cursor: pointer; 268 - color: var(--base03); 268 + color: var(--base04); 269 269 flex-shrink: 0; 270 270 transition: all 0.15s; 271 271 }
+2 -7
features/groups/home.css
··· 186 186 border: none; 187 187 border-radius: 4px; 188 188 cursor: pointer; 189 - color: var(--base03); 189 + color: var(--base04); 190 190 flex-shrink: 0; 191 191 transition: all 0.15s; 192 192 padding: 0; ··· 208 208 border: none; 209 209 border-radius: 4px; 210 210 cursor: pointer; 211 - color: var(--base03); 211 + color: var(--base04); 212 212 flex-shrink: 0; 213 213 transition: all 0.15s; 214 214 padding: 0; 215 - opacity: 0; 216 - } 217 - 218 - peek-card:hover .card-remove-group-btn { 219 - opacity: 1; 220 215 } 221 216 222 217 .card-remove-group-btn:hover {
+7 -1
features/groups/home.js
··· 961 961 console.error('[groups] Failed to remove item from group:', err); 962 962 } 963 963 }); 964 - btnGroup.appendChild(removeBtn); 964 + // Insert before the delete button so remove-from-group is to the LEFT of delete 965 + const deleteBtn = btnGroup.querySelector('.card-delete-btn'); 966 + if (deleteBtn) { 967 + btnGroup.insertBefore(removeBtn, deleteBtn); 968 + } else { 969 + btnGroup.appendChild(removeBtn); 970 + } 965 971 } 966 972 } 967 973
+1 -1
features/lists/home.css
··· 182 182 border: none; 183 183 border-radius: 4px; 184 184 cursor: pointer; 185 - color: var(--base03); 185 + color: var(--base04); 186 186 flex-shrink: 0; 187 187 transition: all 0.15s; 188 188 padding: 0;
+1 -1
features/pagestream/home.css
··· 213 213 border: none; 214 214 border-radius: 4px; 215 215 cursor: pointer; 216 - color: var(--base03); 216 + color: var(--base04); 217 217 flex-shrink: 0; 218 218 transition: all 0.15s; 219 219 padding: 0;
+1 -1
features/search/home.css
··· 162 162 border: none; 163 163 border-radius: 4px; 164 164 cursor: pointer; 165 - color: var(--base03); 165 + color: var(--base04); 166 166 flex-shrink: 0; 167 167 transition: all 0.15s; 168 168 padding: 0;
+47 -3
features/search/home.js
··· 11 11 updateSelection as _updateSelection, 12 12 createKeydownHandler, 13 13 setupToolbar as _setupToolbar, 14 - createViewPrefs 14 + createViewPrefs, 15 + getCards, 16 + toggleSelectedCheckbox 15 17 } from 'peek://app/lib/grid-nav.js'; 16 18 import { getItemDisplayInfo } from 'peek://app/lib/card-helpers.js'; 17 19 import { createActionRulesCache } from 'peek://app/lib/tag-action-affordances.js'; ··· 310 312 affordances: rules.length > 0 ? { 311 313 rules, 312 314 api, 313 - onToggle: () => { render(); } 315 + onToggle: async () => { 316 + // Refresh tags for the toggled item so re-render shows the new state 317 + const tagsResult = await api.datastore.getItemTags(item.id); 318 + if (tagsResult.success) { 319 + state.itemTags.set(item.id, tagsResult.data); 320 + } 321 + render(); 322 + } 314 323 } : null, 315 324 onClick: async (item) => { 316 325 if (itemUrl && isWebUrl(itemUrl)) { ··· 333 342 334 343 const updateSelection = () => _updateSelection(state); 335 344 336 - const handleKeydown = createKeydownHandler(state, { 345 + /** 346 + * Delete the currently selected search result item. 347 + * Matches the onDelete callback used by card delete buttons. 348 + */ 349 + const deleteSelectedItem = async () => { 350 + const cards = getCards(); 351 + const selected = cards[state.selectedIndex]; 352 + if (!selected) return; 353 + 354 + const itemId = selected.dataset.itemId; 355 + const item = state.results.find(r => r.id === itemId); 356 + if (!item) return; 357 + 358 + if (!confirm(`Delete "${item.title || item.content || 'this item'}"?`)) return; 359 + 360 + await api.datastore.deleteItem(item.id); 361 + api.publish('item:deleted', { id: item.id }, api.scopes.GLOBAL); 362 + state.results = state.results.filter(r => r.id !== item.id); 363 + state.itemTags.delete(item.id); 364 + render(); 365 + }; 366 + 367 + const _baseKeydownHandler = createKeydownHandler(state, { 337 368 onEscape: () => window.close() 338 369 }); 370 + 371 + /** 372 + * Extended keydown handler: delegates to shared grid-nav handler, 373 + * plus adds Delete key for deleting items. 374 + */ 375 + const handleKeydown = (e) => { 376 + if (e.key === 'Delete' || e.key === 'Backspace') { 377 + e.preventDefault(); 378 + deleteSelectedItem(); 379 + return; 380 + } 381 + _baseKeydownHandler(e); 382 + }; 339 383 340 384 // ── Toolbar ──────────────────────────────────────────────────────────── 341 385
+1 -1
features/tags/home.css
··· 585 585 border: none; 586 586 border-radius: 4px; 587 587 cursor: pointer; 588 - color: var(--base03); 588 + color: var(--base04); 589 589 flex-shrink: 0; 590 590 transition: all 0.15s; 591 591 padding: 0;