Files
bible/assets/templates/toast.njk
T
2026-09-09 09:08:19 -04:00

43 lines
2.3 KiB
Plaintext

{# One confirmation: something the reader just did, said once and then gone.
Bootstrap's custom-content shape -- a flex row of body and close button,
with no toast-header above it. The header carries a title, an icon and a
timestamp, which is what a notification arriving from elsewhere needs; this
is the answer to a button pressed a second ago, and the sentence is the
whole of it.
Context: text, bad (it did not happen), oob.
Two ways in, the same element either way. api/toast renders it alone and
htmx appends it to the container; the bookmark write renders it with oob
set and it rides along on the answer that updates the navbar slot -- one
response, both halves of the page, the way the modal's status line used to.
The wrapper is how an out-of-band element with no id of its own says where
it goes: htmx appends the wrapper's children to the named container and
drops the wrapper itself.
It shows itself on arrival and removes itself once it has gone. hx-on::load
is htmx's own event, fired on content it has just inserted and processed,
so it covers both ways in -- and it is the same move base.njk makes to open
the dialog: the arrival of the content is the signal to show it. Bootstrap
owns the timer, the fade, the close button and Escape from there. Removing
the element on hidden.bs.toast is what keeps the container from filling up
with dead markup: a toast that has been read is not history, and nothing
here ever looks at it again. #}
{% if oob %}<div hx-swap-oob="beforeend:#toasts">{% endif %}
<div class="toast align-items-center{% if bad %} text-bg-danger{% endif %}"
role="alert" aria-live="assertive" aria-atomic="true"
hx-on::load="bootstrap.Toast.getOrCreateInstance(this).show();"
hx-on:hidden.bs.toast="this.remove();">
<div class="d-flex">
<div class="toast-body">{{ text }}</div>
{# me-2 m-auto, not ms-auto: the row is body then button, and the body is
what grows -- the button only has to sit centred against however many
lines it turns out to be. #}
<button type="button"
class="btn-close{% if bad %} btn-close-white{% endif %} me-2 m-auto"
data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
{% if oob %}</div>{% endif %}