feat(ui): landscape iteration — reorder left panel, enable board zoom
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m13s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 45s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m13s
Left panel order is now score / history / status / rack / controls (the history fills the middle and scrolls). Board zoom is re-enabled in landscape with the same gestures as portrait, but height-driven: the viewport is the full right pane, the board fits by height as a centred square when zoomed out, and on zoom-in it magnifies past the pane and pans within it (focus-centred scroll that rides the magnify transition), occupying the full width up to the left panel. Board.svelte gains a landscape prop; portrait stays width-driven and unchanged. landscape.spec.ts now asserts zoom works (the zoomed board overflows the pane).
This commit is contained in:
+17
-11
@@ -459,7 +459,7 @@
|
||||
hoverKey = ck;
|
||||
if (hoverTimer) clearTimeout(hoverTimer);
|
||||
hoverTimer =
|
||||
c && !zoomed && !landscape
|
||||
c && !zoomed
|
||||
? setTimeout(() => {
|
||||
// Still holding the tile over this cell: magnify into it. Only the first
|
||||
// (zoom-in) hold centres; once zoomed we never move the board on hover.
|
||||
@@ -561,7 +561,7 @@
|
||||
if (board[row]?.[col]) return;
|
||||
if (pendingMap.has(`${row},${col}`)) return;
|
||||
focus = { row, col };
|
||||
if (isCoarse() && !zoomed && !landscape) zoomed = true;
|
||||
if (isCoarse() && !zoomed) zoomed = true;
|
||||
if (placement.rack[index] === BLANK) {
|
||||
blankPrompt = { rackIndex: index, row, col };
|
||||
return;
|
||||
@@ -675,7 +675,7 @@
|
||||
// unchanged zoom state would otherwise leave it parked where the player was looking.
|
||||
recenter++;
|
||||
}
|
||||
if (isCoarse() && !landscape) zoomed = true;
|
||||
if (isCoarse()) zoomed = true;
|
||||
view = { ...view, hintsRemaining: h.hintsRemaining };
|
||||
recompute();
|
||||
}
|
||||
@@ -901,10 +901,10 @@
|
||||
{#if landscape}
|
||||
<div class="game-land">
|
||||
<div class="leftpane">
|
||||
{@render rackRow()}
|
||||
{@render statusBlock()}
|
||||
{@render scoreboardBlock()}
|
||||
<div class="history land">{@render historyBody()}</div>
|
||||
{@render statusBlock()}
|
||||
{@render rackRow()}
|
||||
<TabBar>{@render controlButtons()}</TabBar>
|
||||
</div>
|
||||
<div class="rightpane">{@render boardBlock()}</div>
|
||||
@@ -1013,6 +1013,7 @@
|
||||
flash={recentFlash}
|
||||
centre={ctr}
|
||||
{zoomed}
|
||||
{landscape}
|
||||
{variant}
|
||||
labelMode={app.boardLabels}
|
||||
lines={app.boardLines}
|
||||
@@ -1021,7 +1022,7 @@
|
||||
{recenter}
|
||||
{dropTarget}
|
||||
oncell={onCell}
|
||||
ontogglezoom={(r, c) => { focus = { row: r, col: c }; if (!gameOver && !landscape) zoomed = !zoomed; }}
|
||||
ontogglezoom={(r, c) => { focus = { row: r, col: c }; if (!gameOver) zoomed = !zoomed; }}
|
||||
onrecall={onRecall}
|
||||
onpenddown={onBoardDown}
|
||||
/>
|
||||
@@ -1502,17 +1503,21 @@
|
||||
min-height: 0;
|
||||
}
|
||||
.rightpane {
|
||||
/* A size container so the board can be the largest square that fits — by height, shrinking
|
||||
by width when the column is narrow (the board has the lowest priority, per the design). */
|
||||
/* A size container spanning the whole right area: the board (Board.svelte's .viewport.land)
|
||||
fills it and fits the square board by HEIGHT via min(100cqw,100cqh); on zoom-in the board
|
||||
grows past the pane and pans within it, occupying the full width up to the left panel. The
|
||||
board has the lowest priority, so the pane shrinks the board (by width) when narrow. */
|
||||
container-type: size;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
.rightpane .boardwrap {
|
||||
padding: 0;
|
||||
width: min(100cqw, 100cqh);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
/* The history docked open in the left panel: a normal flex child that fills the remaining
|
||||
height and scrolls, its sticky header staying pinned — no slide-down drawer, no transform. */
|
||||
@@ -1522,7 +1527,8 @@
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
box-shadow: none;
|
||||
border-bottom: none;
|
||||
/* Sits between the score plaques (above) and the status/rack/controls (below): rule it off on
|
||||
both edges (the base rule already draws the bottom border). */
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
/* The score plaques do not toggle the history in landscape (it is always open). */
|
||||
|
||||
Reference in New Issue
Block a user