Ajoute icône/largeur/arrondi/gras/majuscules à l'étiquette (badge)

Nouveaux attributs par élément (svg_markup/width/border_radius/bold/
uppercase, tous vides ou False par défaut = comportement historique
inchangé), réglables depuis le panneau Propriétés — même esprit que
bold/align/color déjà présents sur titre/paragraphe. Fixer une largeur
implique toujours de sortir de l'étirement pleine largeur par défaut
(align-self:flex-start posé automatiquement avec elle).

Le kicker "Module obligatoire" du thème Sécurité Incendie s'en sert
maintenant (icône flamme, largeur au contenu, arrondi complet, gras,
majuscules) pour être conforme à la maquette d'origine — la puce
décorative CSS générique qui la remplaçait disparaît du thème.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-24 11:36:30 +02:00
co-authored by Claude Sonnet 5
parent 1296edc2f8
commit e03bea39c5
9 changed files with 194 additions and 26 deletions
+58 -1
View File
@@ -232,7 +232,14 @@ def test_badge_default_attributes_and_render(tmp_support_slug_cleanup: Any) -> N
element_id = doc_engine.add_document_element(slug, "badge", page_id=page_id)
element = doc_engine.get_document_element(slug, element_id)
assert element is not None
assert element["attributes"] == {"content": "Étiquette"}
assert element["attributes"] == {
"content": "Étiquette",
"svg_markup": "",
"width": "",
"border_radius": "",
"bold": False,
"uppercase": False,
}
html = doc_engine.render_document(doc_engine.list_document_elements(slug, page_id))
assert html == f'<div class="docBadge" data-element-id="{element_id}" data-kind="badge">Étiquette</div>'
@@ -248,6 +255,56 @@ def test_badge_escapes_content(tmp_support_slug_cleanup: Any) -> None:
assert "&lt;script&gt;" in html
def test_badge_with_svg_markup_renders_a_sanitized_icon(tmp_support_slug_cleanup: Any) -> None:
slug, page_id = _new_support(tmp_support_slug_cleanup)
element_id = doc_engine.add_document_element(slug, "badge", page_id=page_id)
doc_engine.update_document_element_attributes(
slug,
element_id,
{
"content": "Module obligatoire",
"svg_markup": '<svg onload="alert(1)"><circle cx="1" cy="1" r="1"/><script>alert(2)</script></svg>',
},
)
html = doc_engine.render_document(doc_engine.list_document_elements(slug, page_id))
assert '<span class="docBadgeIcon">' in html
assert "<circle" in html
assert "onload" not in html
assert "<script>" not in html
def test_badge_without_svg_markup_renders_no_icon_span(tmp_support_slug_cleanup: Any) -> None:
slug, page_id = _new_support(tmp_support_slug_cleanup)
doc_engine.add_document_element(slug, "badge", page_id=page_id)
html = doc_engine.render_document(doc_engine.list_document_elements(slug, page_id))
assert "docBadgeIcon" not in html
def test_badge_with_width_also_sets_align_self(tmp_support_slug_cleanup: Any) -> None:
"""Fixer une largeur doit TOUJOURS sortir du comportement par défaut
(pleine largeur, étirement flex) — les deux vont toujours ensemble,
voir render_document_element._render_badge."""
slug, page_id = _new_support(tmp_support_slug_cleanup)
element_id = doc_engine.add_document_element(slug, "badge", page_id=page_id)
doc_engine.update_document_element_attributes(slug, element_id, {"content": "X", "width": "fit-content"})
html = doc_engine.render_document(doc_engine.list_document_elements(slug, page_id))
assert "align-self:flex-start;" in html
assert "width:fit-content;" in html
def test_badge_border_radius_bold_and_uppercase_render_inline_style(tmp_support_slug_cleanup: Any) -> None:
slug, page_id = _new_support(tmp_support_slug_cleanup)
element_id = doc_engine.add_document_element(slug, "badge", page_id=page_id)
doc_engine.update_document_element_attributes(
slug, element_id, {"content": "X", "border_radius": "999px", "bold": True, "uppercase": True}
)
html = doc_engine.render_document(doc_engine.list_document_elements(slug, page_id))
assert "border-radius:999px;" in html
assert "font-weight:800;" in html
assert "text-transform:uppercase;" in html
def test_carte_default_attributes_and_render(tmp_support_slug_cleanup: Any) -> None:
slug, page_id = _new_support(tmp_support_slug_cleanup)
element_id = doc_engine.add_document_element(slug, "carte", page_id=page_id)
+16
View File
@@ -32,6 +32,22 @@ def test_securite_incendie_title_page_is_vertically_centered() -> None:
assert entry["seed_pages"][1].get("vertical_align", "top") == "top"
def test_securite_incendie_kicker_badge_uses_the_new_badge_properties() -> None:
"""Retour utilisateur du 24/09/2026 : l'étiquette "Module obligatoire"
doit avoir une icône, une largeur au contenu, un arrondi complet et
du gras/majuscules, comme dans la maquette d'origine."""
entry = doc_engine.get_document_theme_entry("securite-incendie")
assert entry is not None
kicker = entry["seed_pages"][0]["blocks"][0]
assert kicker["kind"] == "badge"
attrs = kicker["attributes"]
assert attrs["svg_markup"]
assert attrs["width"] == "fit-content"
assert attrs["border_radius"] == "999px"
assert attrs["bold"] is True
assert attrs["uppercase"] is True
def test_securite_incendie_intro_paragraph_has_a_max_width() -> None:
"""Retour utilisateur du 24/09/2026 : le sous-titre de la page de
garde doit rester aussi étroit que dans la maquette, pas étiré sur