55 lines
3.0 KiB
HTML
55 lines
3.0 KiB
HTML
{#
|
|
Blocking modal dialog — Penguin UI's "modal" component
|
|
(https://www.penguinui.com/components/modal, modern style), with the dark
|
|
variants dropped because the app has no dark theme.
|
|
|
|
It is Tailwind + Alpine markup, so a page that calls this macro must load
|
|
both in its `head` block; `pages/add_table/add_table.html` shows the set.
|
|
The `@theme` block there maps Penguin UI's semantic colour names onto the
|
|
palette in `static/app.css`.
|
|
|
|
Rendered already open (`modalIsOpen: true`): the server only sends the
|
|
dialog when there is something the user has to be told, so there is no
|
|
trigger button — the response itself is the trigger.
|
|
|
|
{% import "ui/dialog.html" as dialog %}
|
|
{% call dialog::error("Could not add the column", message) %}{% endcall %}
|
|
#}
|
|
{% macro error(title, message) %}
|
|
<div x-data="{ modalIsOpen: true }">
|
|
<div x-cloak x-show="modalIsOpen" x-transition.opacity.duration.200ms
|
|
x-trap.inert.noscroll="modalIsOpen"
|
|
x-on:keydown.esc.window="modalIsOpen = false" x-on:click.self="modalIsOpen = false"
|
|
class="fixed inset-0 z-30 flex items-end justify-center bg-surfaceDark/20 p-4 pb-8 backdrop-blur-xs sm:items-center lg:p-8"
|
|
role="dialog" aria-modal="true" aria-labelledby="dialogTitle">
|
|
<!-- Modal Dialog -->
|
|
<div x-show="modalIsOpen"
|
|
x-transition:enter="transition delay-100 duration-200 ease-out motion-reduce:transition-opacity"
|
|
x-transition:enter-start="scale-50 opacity-0" x-transition:enter-end="scale-100 opacity-100"
|
|
class="flex max-w-lg flex-col gap-4 overflow-hidden rounded-lg border border-outline bg-surface text-onSurface">
|
|
<!-- Dialog Header -->
|
|
<div class="flex items-center justify-between border-b border-outline bg-surfaceAlt/60 p-4">
|
|
<h3 id="dialogTitle" class="font-semibold tracking-wide text-danger">{{ title }}</h3>
|
|
<button type="button" x-on:click="modalIsOpen = false" class="cursor-pointer text-onSurface" aria-label="close dialog">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" stroke="currentColor"
|
|
fill="none" stroke-width="1.4" class="h-5 w-5">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<!-- Dialog Body -->
|
|
<div class="px-4 py-4">
|
|
<p class="text-pretty whitespace-pre-wrap">{{ message }}</p>
|
|
</div>
|
|
<!-- Dialog Footer -->
|
|
<div class="flex flex-col-reverse justify-between gap-2 border-t border-outline bg-surfaceAlt/60 p-4 sm:flex-row sm:items-center md:justify-end">
|
|
<button type="button" x-on:click="modalIsOpen = false"
|
|
class="cursor-pointer rounded-md whitespace-nowrap bg-primary px-4 py-2 text-center text-sm font-medium tracking-wide text-onPrimary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary active:opacity-100 active:outline-offset-0">
|
|
Back to the form
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|