Spaces:
Running
Running
File size: 3,882 Bytes
330b65e 66f3a37 330b65e 66f3a37 330b65e 66f3a37 330b65e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | from __future__ import annotations
from backend.models.issue import Category, Issue, Severity
def analyze(parsed_page: dict, thresholds: dict) -> list[Issue]:
issues: list[Issue] = []
t = thresholds["tables"]
tables = parsed_page.get("tables", [])
for i, table in enumerate(tables):
label = f"Table #{i + 1}"
# TBL1 — no header row
if not table.get("has_header", True):
issues.append(Issue(
rule_id="TBL1_missing_header",
category=Category.COMPONENT_QUALITY,
severity=Severity.HIGH,
confidence=0.95,
message=f"{label} has no header row (<thead>/<th>).",
recommendation=(
"Add a <thead> with <th> elements. Use scope='col' for accessibility. "
"Style headers to visually distinguish them from data rows."
),
evidence="No <th> or <thead> detected.",
estimated_time="10 minutes",
why=(
"Screen readers announce column context from <th> elements — without "
"them, table data is read as an unstructured list and is impossible to "
"navigate. WCAG 1.3.1 requires programmatic relationships in tabular data. "
"Visually, headers also give users an instant map of what each column means."
),
references=["WCAG 2.1 SC 1.3.1", "GOV.UK Design System", "WebAIM"],
))
# TBL2 — no zebra striping
if not table.get("has_zebra_striping", False):
issues.append(Issue(
rule_id="TBL2_no_zebra",
category=Category.COMPONENT_QUALITY,
severity=Severity.LOW,
confidence=0.7,
message=f"{label} has no alternating row colours — dense tables are hard to scan.",
recommendation="Apply a subtle background to odd/even rows (e.g. tr:nth-child(even) { background: #f9f9f9; }).",
evidence="No alternating row background detected.",
estimated_time="10 minutes",
why=(
"In data-dense tables, alternating row backgrounds reduce horizontal "
"scanning errors by helping users track a row across wide tables. "
"Leading analytics products consistently use zebra striping for tables "
"with more than 5 columns or 10 rows."
),
references=["Stripe", "Notion", "Google Sheets"],
))
# TBL3 — insufficient cell padding
cell_pad = table.get("cell_padding_px", 0)
if cell_pad < t["min_cell_padding_px"]:
issues.append(Issue(
rule_id="TBL3_cell_padding",
category=Category.COMPONENT_QUALITY,
severity=Severity.MEDIUM,
confidence=0.9,
message=(
f"{label} cell padding ({cell_pad}px) is below the "
f"recommended {t['min_cell_padding_px']}px."
),
recommendation=f"Set td, th {{ padding: {t['min_cell_padding_px']}px 12px; }} for comfortable reading.",
evidence=f"td padding: {cell_pad}px",
estimated_time="5 minutes",
why=(
"Cramped table cells compress data to the point where users struggle to "
"identify individual values without physically pointing at the screen. "
"Adequate cell padding (8px+) gives each datum visual breathing room "
"and dramatically improves scan speed in data-heavy views."
),
references=["Material Design", "Stripe", "GitHub"],
))
return issues
|