Fix the Quest Log header crest/shield to match the design (resubmission of PR #247) (#252)

This commit was merged in pull request #252.
This commit is contained in:
2026-09-26 09:08:59 -04:00
parent c5b313a5e3
commit 9916d83138
3 changed files with 72 additions and 4 deletions
@@ -1765,7 +1765,7 @@ const Nt = "polygon(0 0, 100% 0, 100% 62%, 50% 100%, 0 62%)", Ye = "polygon(50%
flex: none;
width: 96px;
height: 110px;
padding: 3px;
padding: 4px;
clip-path: ${v(Nt)};
background: rgba(255, 255, 255, 0.22);
}
@@ -3091,7 +3091,7 @@ class un extends A {
const e = this._childSlug(), n = t.kind === "away", i = n ? t.name : this._childName(e) ?? (e ? Y(e) : null), { due: r, completed: o } = this._childCounts(e), l = this._remaining(), a = this._partyCounts(), p = i ? `${i}'s Quest Log` : "Quest Log", u = (i?.charAt(0) || "?").toUpperCase();
return d`
<header class="header">
<span class="crest${n ? " away" : g}" aria-hidden="true">
<span class="crest${n ? " away" : ""}" aria-hidden="true">
<span class="crest-face">
<span class="initial">${u}</span>
</span>
+2 -2
View File
@@ -378,7 +378,7 @@ const logStyles = css`
flex: none;
width: 96px;
height: 110px;
padding: 3px;
padding: 4px;
clip-path: ${unsafeCSS(SHIELD_CLIP)};
background: rgba(255, 255, 255, 0.22);
}
@@ -1938,7 +1938,7 @@ export class NestQuestQuestLogCard extends LitElement {
const initial = (name?.charAt(0) || "?").toUpperCase();
return html`
<header class="header">
<span class="crest${away ? " away" : nothing}" aria-hidden="true">
<span class="crest${away ? " away" : ""}" aria-hidden="true">
<span class="crest-face">
<span class="initial">${initial}</span>
</span>
+68
View File
@@ -916,3 +916,71 @@ def test_quest_complete_screen_returns_to_the_board_after_the_countdown() -> Non
assert result["probe"]["countdown"] == "Returning to The Party in 1 seconds"
# …and at zero the card has returned to the party board.
assert result["location"] == "/nestquest"
def test_quest_log_crest_keeps_its_shield_classes() -> None:
"""PANEL-SPEC §3 header crest: a present child's crest renders as the
styled shield, not a bare span. Lit removes an attribute outright when
any interpolated part of it is ``nothing``, so a class written as
``crest${away ? " away" : nothing}`` lost ``crest`` for every present
child and the header showed an unstyled sliver. The rendered markup
must carry ``class="crest"`` (present) and ``class="crest away"``
(away), each wrapping the face and initial."""
generated = _generate_dashboard(
{}, _three_child_states(), url="http://homeassistant.local/nestquest"
)
log_config = generated["views"][1]["cards"][0]
for slug, crest_class in (("ada", "crest"), ("bo", "crest away")):
result = _render_quest_log(
log_config,
_three_child_states(),
url=f"http://homeassistant.local/nestquest/{slug}",
)
header = result["html"][result["html"].index('<header class="header">') :]
crest = re.match(
r'<header class="header">\s*(?:<!--[^>]*-->\s*)*<span ([^>]*)>\s*'
r'<span class="crest-face">\s*<span class="initial">',
header,
)
assert crest is not None, header[:600]
assert f'class="{crest_class}"' in crest.group(1), crest.group(1)
def test_quest_log_crest_matches_the_spec_geometry() -> None:
"""PANEL-SPEC §3 header crest: 96x110 shield, 4px ring of
rgba(255,255,255,.22) around the --nq-p-crest face, 44px/700 display
initial in full-opacity white; away swaps only the face gradient.
jsdom cannot lay out, so this pins the stylesheet the rendered test
above shows is applied."""
source = QUEST_LOG.read_text(encoding="utf-8")
def rule(selector: str) -> str:
found = re.search(
r"\n " + re.escape(selector) + r" \{(.*?)\n \}", source, re.DOTALL
)
assert found is not None, selector
return found.group(1)
crest = rule(".crest")
for decl in (
"width: 96px;",
"height: 110px;",
"padding: 4px;",
"clip-path: ${unsafeCSS(SHIELD_CLIP)};",
"background: rgba(255, 255, 255, 0.22);",
):
assert decl in crest, decl
face = rule(".crest-face")
assert "background: var(--nq-p-crest);" in face
assert "clip-path: ${unsafeCSS(SHIELD_CLIP)};" in face
initial = rule(".crest .initial")
for decl in (
"font-family: var(--nq-p-font-display);",
"font-size: 44px;",
"font-weight: 700;",
"color: #ffffff;",
):
assert decl in initial, decl
assert "opacity" not in initial
away = rule(".crest.away .crest-face")
assert away.strip() == "background: var(--nq-p-crest-away);"