web using penguin-ui

This commit is contained in:
Priec
2026-08-07 21:37:40 +02:00
parent 7cda7ea833
commit c47e236713
8 changed files with 183 additions and 120 deletions

View File

@@ -1,15 +1,20 @@
{#
Inline status blocks — Penguin UI's "alert" component
(https://www.penguinui.com/components/alert, modern style, with icon), minus
the dark variants because the app has no dark theme. The colours come from
the @theme block in ui/base.html.
Inline failure alert — Penguin UI's danger alert, taken from
penguinui-components/alert/alert-dismiss-functionality.html.
Failures only: a success is ui/toast.html, which says its piece and then
removes itself rather than staying in the layout. An error has to stay until
Unlike the toast, this component carries its copy in the markup, so it cannot
be `{% include %}`d from the library the way ui/toast.html's stack is: the
library file says "Invalid Email Address". This is that file's danger variant
with its two text nodes replaced by `{{ title }}` and `{{ message }}` and
nothing else touched — every class, the x-data, the leave transition and the
dismiss button are the library's. Two additions, both about this app's
content rather than the component's look: `mt-4` for the gap from the form
above, and `whitespace-pre-wrap` because the server's messages are multi-line.
Failures only. A success is ui/toast.html, which says its piece and then
removes itself rather than staying in the layout; an error has to stay until
it is read, so it is this.
Imported wherever a form reports a failure:
{% import "ui/alert.html" as alert %}
{% call alert::error("Could not create the table", message) %}{% endcall %}
@@ -17,18 +22,29 @@
the message in front of someone who has scrolled away from the top of a form.
#}
{% macro error(title, message) %}
<div class="relative mt-4 w-full overflow-hidden rounded-md border border-danger bg-surface text-onSurface" role="alert">
<div class="flex items-center gap-2 bg-danger/10 p-4">
<div class="shrink-0 rounded-full bg-danger/15 p-1 text-danger">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6" aria-hidden="true">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-8-5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 10 5Zm0 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" />
</svg>
<div x-data="{ alertIsVisible: true }" x-show="alertIsVisible"
class="relative mt-4 w-full overflow-hidden rounded-radius border border-danger bg-surface text-on-surface dark:bg-surface-dark dark:text-on-surface-dark"
role="alert" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-90">
<div class="flex w-full items-center gap-2 bg-danger/10 p-4">
<div class="bg-danger/15 text-danger rounded-full p-1" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-6"
aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM8.28 7.22a.75.75 0 0 0-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 1 0 1.06 1.06L10 11.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L11.06 10l1.72-1.72a.75.75 0 0 0-1.06-1.06L10 8.94 8.28 7.22Z"
clip-rule="evenodd" />
</svg>
</div>
<div class="ml-2">
<h3 class="text-sm font-semibold text-danger">{{ title }}</h3>
<p class="text-xs font-medium whitespace-pre-wrap sm:text-sm">{{ message }}</p>
</div>
<button type="button" @click="alertIsVisible = false" class="ml-auto" aria-label="dismiss alert">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
fill="none" stroke-width="2.5" class="w-4 h-4 shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="ml-2">
<h3 class="text-sm font-semibold text-danger">{{ title }}</h3>
<p class="text-sm font-medium whitespace-pre-wrap">{{ message }}</p>
</div>
</div>
</div>
{% endmacro %}