fix: space tile, stat and file row labels

Tiles read "BizHawkWindows, Linux", stats "168/168Coverage" and a
file row "SVI603.ROMbios/Machines/...OK": the stylesheet lays them
out as boxes, the markup had no space between them. A setup without a
logo draws its initials from the stylesheet, so its name is read once.
This commit is contained in:
Abdessamad Derraz committed 2026-11-10 14:12:06 +01:00
1 parent c916503958
commit a4d5c6149b
7 files changed
+30 -15

No files matched your search

+6 -4
View File
@@ -417,8 +417,8 @@ def _date_line() -> str:
def _stat(value: str, label: str) -> list[str]:
return [
markup.block_open("div", 'class="rb-stat"'),
f'<span class="rb-stat-value">{value}</span>',
f'<span class="rb-stat-label">{label}</span>',
# One line, a space between: the page text read "168/168Coverage".
f'<span class="rb-stat-value">{value}</span> <span class="rb-stat-label">{label}</span>',
"</div>",
"",
]
@@ -3803,8 +3803,10 @@ def _platform_file_row(f: dict, cfg_entry: dict, hash_type: str = "",
facts.append(_inline_html(_category_evidence_md(f["category_evidence"], launched)))
path = _row_path(fname, cfg_entry)
summary = (_text_html(fname) + (f"<code>{_text_html(path)}</code>" if path else "")
+ _status_chip(f))
# Spaces between name, path and status: the summary lays them out as
# columns, and the page text read "SVI603.ROMbios/Machines/...OK".
summary = " ".join([_text_html(fname), *([f"<code>{_text_html(path)}</code>"] if path else []),
_status_chip(f)])
copy = _copy_hash(shown, hashes[shown]) if shown else ""
return (f'<details class="rb-file"><summary>{summary}</summary>'
f'{"<br>".join(facts)}</details>{copy}')
+7 -6
View File
@@ -225,10 +225,11 @@ def _tile_mark(name: str, logo: str, lazy: bool = False) -> str:
loading = ' loading="lazy"' if lazy else ""
return (f'<img class="rb-card-logo" src="{html.escape(logo)}" alt="" '
f'width="40" height="40"{loading}>')
# The same square as a logo, drawn on white like the logos are.
return ('<svg class="rb-card-logo" viewBox="0 0 40 40" width="40" height="40" aria-hidden="true">'
'<text x="20" y="25" text-anchor="middle" font-size="14" font-weight="700" '
f'fill="#2b2e5c">{html.escape(initials(name))}</text></svg>')
# The same square as a logo, drawn on white like the logos are. The
# letters are the stylesheet's (::before), not text of the page: the
# tile's name follows, and a copy or a text dump read "MMMyMinUI".
return (f'<span class="rb-card-logo rb-card-initials" data-initials="{html.escape(initials(name))}" '
'aria-hidden="true"></span>')
# Tiles in the first row of a grid at its widest, two columns of 15rem in
@@ -246,8 +247,8 @@ def platform_tiles(tiles: list[tuple[str, str, str, str]], eager: int = 0) -> li
links = "".join(
f'<a class="rb-card rb-tile" href="{html.escape(target)}">'
f"{_tile_mark(name, logo, lazy=index >= eager)}"
f'<strong class="rb-tile-name">{html.escape(name)}</strong>'
f'<span class="rb-tile-runs">{inline_html(runs_on)}</span></a>'
f'<strong class="rb-tile-name">{html.escape(name)}</strong> '
f'<span class="rb-tile-runs">{inline_html(runs_on)}</span></a> '
for index, (name, target, logo, runs_on) in enumerate(tiles)
)
return [f'<div class="rb-cards rb-tiles">{links}</div>', ""]
+1 -1
View File
@@ -328,7 +328,7 @@ class TitleLogoOnAPlate(unittest.TestCase):
# written, the tile's and the title's.
import sitemarkup # noqa: PLC0415
self.assertRegex(sitemarkup._tile_mark("MyMinUI", ""), r"<svg[^>]*>.*>MM</text></svg>")
self.assertIn('data-initials="MM" aria-hidden="true"></span>', sitemarkup._tile_mark("MyMinUI", ""))
component = _read(REPO_ROOT / "website" / "src" / "components" / "PageTitle.astro")
self.assertIn("{initials(setup.name)}", component)
+1 -1
View File
@@ -160,7 +160,7 @@ class SetupTiles(unittest.TestCase):
def test_a_setup_without_a_logo_shows_its_initials(self):
self.assertEqual(sitemarkup.initials("MyMinUI"), "MM")
tile = "".join(sitemarkup.platform_tiles([("MyMinUI", "x.md", "", "Handhelds")]))
self.assertIn(">MM</text>", tile)
self.assertIn('data-initials="MM"', tile)
tile = "".join(sitemarkup.platform_tiles([("RomM", "x.md", "logo.png", "A server")]))
self.assertIn('<img class="rb-card-logo" src="logo.png"', tile)
+1 -1
View File
@@ -344,7 +344,7 @@ class APlatformPageSaysWhereEachFileGoes(unittest.TestCase):
{"nintendo-gamecube": files}, {("nintendo-gamecube", "IPL.bin"): declared}, {})
for region in regions:
# The folder: the name is before it in the row.
self.assertIn(f"<summary>IPL.bin<code>dolphin-emu/Sys/GC/{region}/</code>"
self.assertIn(f"<summary>IPL.bin <code>dolphin-emu/Sys/GC/{region}/</code> "
'<span class="rb-badge rb-badge-success">OK</span></summary>',
"\n".join(lines))
+2 -2
View File
@@ -97,7 +97,7 @@ class ARowPerFile(unittest.TestCase):
{"name": "bios_a.bin", "md5": md5, "sha1": sha1, "crc32": "0badf00d",
"destination": "bios/bios_a.bin"})
# The summary is the row: the name, its folder, the status.
self.assertIn('<details class="rb-file"><summary>bios&#95;a.bin<code>bios/</code>'
self.assertIn('<details class="rb-file"><summary>bios&#95;a.bin <code>bios/</code> '
'<span class="rb-badge rb-badge-success">OK</span></summary>', row)
# The hash the platform checks, short, on one button beside the
# summary (a summary is a control: no button inside it).
@@ -113,7 +113,7 @@ class ARowPerFile(unittest.TestCase):
def test_a_file_at_the_root_prints_no_path(self):
for destination in ("", "x.bin"):
row = self._row({"name": "x.bin", "status": "ok"}, {"destination": destination})
self.assertIn("<summary>x.bin<span", row)
self.assertIn("<summary>x.bin <span", row)
def test_a_list_drops_the_path_column_when_no_row_has_one(self):
files = [{"name": "a.bin", "status": "ok"}, {"name": "b.bin", "status": "ok"}]
+12
View File
@@ -277,6 +277,18 @@
vertical-align: middle;
}
/* A setup with no logo: its initials, drawn by the stylesheet so the page
text holds its name once (sitemarkup._tile_mark). */
.sl-markdown-content .rb-card-initials {
display: inline-grid;
place-items: center;
color: #2b2e5c;
font-size: 10.5px;
font-weight: 700;
line-height: 1;
}
.sl-markdown-content .rb-card-initials::before { content: attr(data-initials); }
/* Device tiles: the whole tile is the link. Logo on the left, name over
what it runs on, so a phone shows a short row per setup. */
.sl-markdown-content .rb-tiles { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0.6rem; }