{% load i18n brickwork_icons %} {% comment %} Full-width banner alert (STA-008/009). role="alert" so it is announced. The status icon is decorative (the variant + text carry the meaning; the icon is reinforcement, not the sole signal). This is the loud surface for page-level errors and status, distinct from a field's inline error (forms/_field.html). Dismissible (04-interfaces 4b Dismissible section, 0.9.0, CMP-010): with the tag's dismissible=True the root gains x-data="bwDismissible()" (semver-public, BR-BW-JS-004; no props, state { visible }, method dismiss(), emits bw:dismiss { id }) and an icon-only close button ships WITH the hidden attribute; bwDismissible removes hidden at init, so the no-JS floor shows no dead control. Dismissal removes the element from the DOM only; persistence stays host-owned (CMP-012). Exit at --bw-duration-fast/--bw-ease-in (MOT-007's clear-quickly tier); reduced motion removes instantly (BR-BW-TOK-009). REGRESSION NOTE: with dismissible=False (the default) the rendered output is byte-identical to the 0.8.0 template; the conditional blocks below are laid out so the False path adds not even whitespace. DIRECT INCLUDE (2.0.0): {% bw_alert %} derives `icon` from `variant` before rendering, but a plain {% include %} with only variant/title/message (the copy-paste example shape this package now documents, ADR-056) supplies no `icon` at all, and passing that undefined value to {% bw_icon %} raised IconNotFoundError for the empty name. The variant-to-icon mapping is therefore resolved HERE as a fallback, so both call shapes work. The tag path is unaffected: it still passes an explicit `icon`, which {% firstof %} takes ahead of the fallback, so its output is byte-identical to 1.x. The chain sits at the template's top level on purpose: an `{% ... as %}` assignment made inside an `{% if %}` body would fall out of scope before the icon line. Named blocks (semver-public, BR-BW-TPL-001): body: the concise successor to the deprecated alert_body block below (ADR-077 SS4), present SINCE 3.4.0. Empty by default; a filled block adds extra content under the title/message lines. alert_body: present since before 3.4.0 (unchanged back to at least 3.2.1). DEPRECATED, removed at 4.0 (ADR-077 SS4, BR-BW-TPL-001/BR-BW-VER-001). Kept as an additional empty extension point for backwards compatibility: a shipped block name cannot be renamed silently. Both body and alert_body render when both are filled; a caller migrating to the concise name fills body only. A block name this file does not define is SILENTLY DISCARDED by Django: no error, no warning, DEBUG=True does not catch it. If you extend this template using a name read from a newer checkout than the version you have pinned, check that name against your pinned version's own header before relying on it, or the region renders nothing. States: dismissed/not-dismissed when dismissible=True (x-data="bwDismissible()", state { visible }); the no-JS floor renders the close button with the hidden attribute, removed at Alpine init, so a JS-disabled page shows no dead control. Four variant states (info/success/warning/danger, default info), each pairing a fixed icon with its own tint and border colour. Accessibility: role="alert" so the whole banner is announced on render; the status icon is decorative (bw_icon decorative=True), the variant colour and text carry the meaning, never the icon alone. The dismiss control is an icon-only button with an aria-label (translated "Dismiss"). Covered by axe.spec.mjs indirectly via app/confirm.html and app/detail.html (both compose it) and via sections-*.html (content/callout.html); the dismiss markup and its bwDismissible() wiring are asserted at the Python/string level (tests/test_components.py, tests/test_integration.py), not by a browser-driven dismiss interaction in the a11y suites. Responsive: no breakpoint switch; no width-dependent CSS on any .bw-alert* selector. The banner is full-width within its container at every viewport size. {% endcomment %} {% if variant == "success" %}{% firstof icon "success" as bw_alert_icon %}{% elif variant == "warning" %}{% firstof icon "alert-triangle" as bw_alert_icon %}{% elif variant == "danger" %}{% firstof icon "alert-circle" as bw_alert_icon %}{% else %}{% firstof icon "info" as bw_alert_icon %}{% endif %}