Skip to content

fix(board): match the tile board's outer gutters to the gaps between tiles - #749

Open
wyne wants to merge 1 commit into
mainfrom
fix/board-gutters
Open

fix(board): match the tile board's outer gutters to the gaps between tiles#749
wyne wants to merge 1 commit into
mainfrom
fix/board-gutters

Conversation

@wyne

@wyne wyne commented Sep 9, 2026

Copy link
Copy Markdown
Owner

The problem

The gaps between tiles aren't margins. Each tile draws borderWidth: 3 in the board's background colour, so what you see between two adjacent tiles is two borders — 6pt. At the board's edge only one tile contributes, so the outer gutters were half that.

Before After
Between tiles 6 6
Top (header) 3 6
Left / right 3 6
Bottom (sheet) 5 6

The bottom was 5 rather than 3 because of a hand-added + 2 on paddingBottom, which is why the top gap looked visibly tighter than the bottom one.

The fix

The board pads its own edges by one border width, supplying the border a tile can't. Every gutter then reads as TILE_BORDER_WIDTH * 2, and if that 3 ever changes, all four edges and the inter-tile gaps move together.

Why the constant moved

It started as an export from PlayerTile, and TileBoard.test.tsx immediately failed with padding: undefined and paddingBottom: NaN — that suite mocks ./PlayerTile wholesale, so the named export vanished.

That was worth listening to rather than working around: a gutter metric shared by the board and the tile isn't a PlayerTile implementation detail. It lives in Boards/layout.ts now and both import it.

Not addressed here

calculateTileDimensions divides the measured height by rows, and onLayout reports the border box — which already includes the ~82pt of bottom padding reserved for the sheet. So the maxWidth/maxHeight hints passed to AdditionTile for font sizing have always overstated the real tile height, and this adds 6pt to that. Correcting it would visibly shrink the score fonts, so it wants its own change.

ListBoard (the dial layout) is untouched — it uses explicit 10pt padding and doesn't share the border trick, so its gutters won't match the tile board's.

Testing

npm run lint clean, 444 tests pass. The TileBoard padding assertion now expresses itself in terms of the constant rather than a literal. JS-only — no rebuild needed.

🤖 Generated with Claude Code

…tiles

Tiles have no margins — each draws a 3pt border in the board's background
colour, so the gap between two of them is 6. At the board's edge only one tile
contributes, leaving 3 against the header and the screen sides, and 5 against
the sheet where an extra 2 had been added by hand.

Padding the board by one border width makes every gutter the same, whether it
falls between two tiles or between a tile and the header, sheet or screen edge.

The constant moves to a layout module rather than being exported from
PlayerTile: TileBoard's test mocks that component wholesale, so importing from
it resolved to undefined and produced padding: NaN. A metric both components
share is not a PlayerTile implementation detail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Coverage after merging fix/board-gutters into main will be

65.14%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
redux
   GamesSlice.ts59.90%35.42%63.33%69.30%104–105, 105, 105, 107, 115–116, 116, 116, 118, 126, 148, 173–175, 190, 220, 227, 229, 232–234, 298, 311, 320–321, 321, 321, 327, 327, 327–328, 330, 332–333, 336, 336, 336, 336, 336–337, 340–341, 343, 345, 345, 345, 345, 345–346, 348, 348, 348, 350–351, 354, 354, 354, 356, 58, 69, 86, 91–92, 92, 92
   PlayersSlice.ts88.04%95%85.71%86.27%105, 107, 115, 35, 52–53, 70–71
   SettingsSlice.ts61.54%66.67%55%65.38%103, 106, 111, 117, 61, 64, 70, 73, 76, 88, 97
   backup.ts78.19%75.19%88.89%80.21%105, 105, 128–130, 138, 174–175, 177, 191–195, 197, 197, 197–198, 203, 206, 217, 227–228, 244, 58–63, 65, 68, 68–70, 70, 70–71, 71, 71, 73–74, 76–78, 80–81, 81–82, 88–89
   hooks.ts100%100%100%100%
   scoreUtils.ts93.33%87.50%100%100%5
   selectors.ts100%100%100%100%
   store.ts0%0%0%0%10, 12, 12, 12–13, 13, 13–15, 18, 21–23, 23, 23, 23, 23–24, 29, 33, 60, 67, 74, 81, 99
   testStore.ts0%100%0%0%11–15, 20–23, 25, 42–44, 5
src
   Analytics.ts100%100%100%100%
   AnalyticsEvents.ts100%100%100%100%
   ColorPalette.ts100%100%100%100%
   Logger.ts91.23%87.50%81.82%94.74%14–15, 22
   Navigation.tsx82.35%80%66.67%88.89%104–105, 49, 53, 95, 98
   constants.ts100%100%100%100%
   platform.ts100%100%100%100%
   theme.ts93.75%85.71%100%100%79
src/components
   EditGame.tsx79.63%75%66.67%84.85%35, 49, 62–63, 86, 86, 86–87
   FloatingActionButton.tsx95.24%100%92.31%96%47
   GameListItem.tsx66.10%47.83%100%73.33%103, 20, 23–24, 24, 24–26, 26, 26–28, 28, 28–30, 30, 30–31, 73
   GameListItemPlayerName.tsx100%100%100%100%
   MenuOpenContext.tsx87.50%100%66.67%100%
   PlayerListItem.tsx0%0%0%0%123, 123, 134, 24, 32–34, 34, 34–38, 40, 40, 40, 40, 40–41, 41, 41–42, 42, 42, 44–45, 56, 63–64, 66, 72–73, 76, 79, 82–83, 90, 93, 93, 96, 96, 96–97, 99
   ScoreLogTable.tsx90.91%80%100%96.67%51, 53, 55, 55, 64, 70
   SplashOverlay.tsx0%0%0%0%22–24, 24, 24, 26–28, 30, 32–33, 35, 37, 40, 40, 40, 43, 49, 53, 58, 74
src/components/AppInfo
   RotatingIcon.tsx0%0%0%0%18–19, 21–24, 26, 28–30, 37–38, 40, 40, 40–41, 44, 44, 44–48, 51, 53–54, 59
   SeedData.ts0%100%0%0%17, 47, 49–50, 52, 54–56, 58–60, 62, 68, 71, 82–85
src/components/BigButtons
   BigButton.tsx0%0%0%0%18, 18–20, 22–23, 23, 25, 25–26, 26, 48
src/components/Boards
   ListBoard.tsx86.81%72.73%84.21%98.57%123, 180, 206–207, 220, 223, 262, 29, 33, 59–61, 84, 84, 88, 92
   PlayerTile.tsx0%0%0%0%100, 31, 40–44, 44, 44–45, 45, 45, 45, 45–46, 46, 46–48, 48, 48, 50–52, 52, 52, 54, 57, 57, 61–62, 65–66, 68, 70, 70, 70, 70, 70–71, 71, 71, 71, 71, 73, 83, 83
   TileBoard.tsx96.43%90.32%100%100%19, 78, 99
   layout.ts100%100%100%100%
src/components/Buttons
   AppSettingsButton.tsx100%100%100%100%
   GameOptionsButton.tsx51.85%42.86%69.23%54.72%102, 122, 122, 122–123, 125–126, 130, 130, 130, 130, 130, 130, 130, 132–133, 135–136, 138–139, 141–144, 146–148, 150–152, 159, 165–166, 177, 179, 179, 185, 185, 185, 185, 40, 46, 48, 58, 65, 73, 94, 98
   HeaderButton.tsx100%100%100%100%
src/components/ColorPalettes
   ColorSelector.tsx100%100%100%100%
   PalettePreview.tsx0%0%0%0%10–12, 14, 19, 19, 25
   PaletteSelector.tsx0%0%0%0%13, 15–18, 20, 22, 22, 22, 24–25, 31, 37, 40, 45, 56
src/components/Headers
   RoundHeaderTitle.tsx0%0%0%0%12–14, 16–17, 17, 17–18, 18, 18–19, 19, 19, 21, 21, 21, 23–24, 26–27, 27, 27, 27, 27, 29–30, 30, 33–34, 43–44, 44, 44, 46–48, 56, 58, 61, 61,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant