From c101b70678054bfeca693280f61b940c1642c764 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Wed, 7 Oct 2026 03:56:38 +0200 Subject: [PATCH] refactor(tiles): each tile's zoom state is painted by _syncTileZoom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _applyTileLayout carried a loop that set every tile's zoomed class and its ⤢ button's pressed state and label. That loop is now _syncTileZoom, beside _syncTileSlots and _syncTileDividers, which _applyTileLayout calls the same way. Same order of writes, same last-English-label compare. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/web/public/tile-grid.js | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/web/public/tile-grid.js b/src/web/public/tile-grid.js index 15716545..59138143 100644 --- a/src/web/public/tile-grid.js +++ b/src/web/public/tile-grid.js @@ -1273,21 +1273,7 @@ Object.assign(CodemanApp.prototype, { } const zoomed = grid.zoomedId && grid.tiles.has(grid.zoomedId) ? grid.zoomedId : null; section.classList.toggle('tile-grid--zoomed', !!zoomed); - for (const [id, entry] of grid.tiles) { - entry.el.classList.toggle('tile--zoomed', id === zoomed); - const zoomBtn = entry.zoomBtn; - if (zoomBtn) { - const on = id === zoomed; - const label = on ? 'Restore the grid' : 'Zoom this tile'; - zoomBtn.setAttribute('aria-pressed', on ? 'true' : 'false'); - // Against the last English label, never the DOM (translated in zh-CN). - if (entry.zoomLabel !== label) { - entry.zoomLabel = label; - zoomBtn.title = label; - zoomBtn.setAttribute('aria-label', label); - } - } - } + this._syncTileZoom(zoomed); // Zoomed: one cell; the other tiles stay connected but hidden (CSS), so // they measure nothing and send no resize. Otherwise every tile is placed // explicitly in reading order, with a divider track between columns and @@ -1305,6 +1291,25 @@ Object.assign(CodemanApp.prototype, { this._persistTileGrid(); }, + // Each tile's zoom state: the zoomed one is shown alone (CSS), and every ⤢ + // button says what pressing it does next. + _syncTileZoom(zoomed) { + for (const [id, entry] of this._tileGrid.tiles) { + const on = id === zoomed; + entry.el.classList.toggle('tile--zoomed', on); + const zoomBtn = entry.zoomBtn; + if (!zoomBtn) continue; + zoomBtn.setAttribute('aria-pressed', on ? 'true' : 'false'); + const label = on ? 'Restore the grid' : 'Zoom this tile'; + // Against the last English label, never the DOM (translated in zh-CN). + if (entry.zoomLabel !== label) { + entry.zoomLabel = label; + zoomBtn.title = label; + zoomBtn.setAttribute('aria-label', label); + } + } + }, + // The empty cells of a layout that is not full (3 tiles in a 2x2, 5 in a // 3x2): drop targets for a tab, after the tiles in reading order. _syncTileSlots(count, cols) {