Modals
Modal patterns for confirmations, destructive actions, and form dialogs. Modals are full-screen on mobile and centered dialogs on desktop.
Destructive confirmation
Red icon with a Danger confirm button. Used for cancel, delete, and disable actions.
Cancel this quote?
This action cannot be undone. The quote will be marked as cancelled and the client will be notified.
Positive confirmation
Green icon with a Primary confirm button. Used for enable, activate, and approve actions.
Enable this partner?
This partner will be able to log in and create quotes. Their team members will also regain access.
Modal markup pattern
The full pattern for a confirmation modal with mobile-first responsive design.
<div x-data="{ confirmOpen: false }">
<!-- Trigger -->
<button type="button"
x-on:click="confirmOpen = true"
koala-btn="Danger" koala-btn-variant="Outlined">
Cancel quote
</button>
<!-- Backdrop -->
<div x-show="confirmOpen" x-cloak
class="fixed inset-0 z-40 bg-gray-900/50 dark:bg-gray-900/75">
</div>
<!-- Panel container -->
<div x-show="confirmOpen" x-cloak
class="fixed inset-0 z-50 flex items-center justify-center sm:p-4">
<!-- Content container -->
<div class="relative bg-white dark:bg-gray-800
sm:border border-gray-200 dark:border-gray-700
rounded-none sm:rounded-lg
w-full h-full sm:h-auto sm:max-w-md
p-6 pt-14 sm:pt-6 overflow-y-auto">
<!-- Close button (absolutely positioned) -->
<button type="button"
x-on:click="confirmOpen = false"
class="absolute top-4 right-4 text-gray-400
hover:text-gray-500 dark:text-gray-500
dark:hover:text-gray-400">
<koala-icon name="X" />
</button>
<!-- Icon (centered) -->
<div class="flex items-center justify-center w-12 h-12
mx-auto rounded-full bg-red-100
dark:bg-red-900/50">
<koala-icon name="AlertTriangle" size="Large"
class="text-red-600 dark:text-red-400" />
</div>
<!-- Title (left-aligned) -->
<h3 class="text-lg font-semibold text-gray-900
dark:text-white text-left mt-4">
Confirm action?
</h3>
<!-- Description (left-aligned) -->
<p class="text-gray-500 dark:text-gray-400
text-left mt-2 mb-6">
Description of what will happen.
</p>
<!-- Buttons (right-aligned) -->
<div class="flex justify-end gap-3">
<button type="button" koala-btn="Neutral"
x-on:click="confirmOpen = false">
Cancel
</button>
<button type="submit" koala-btn="Danger">
Confirm
</button>
</div>
</div>
</div>
</div>
Key CSS classes
These class combinations ensure full-screen on mobile and centered dialog on desktop.
| Element | Classes | Purpose |
|---|---|---|
| Backdrop | fixed inset-0 z-40 bg-gray-900/50 dark:bg-gray-900/75 |
Semi-transparent overlay behind modal |
| Panel container | fixed inset-0 z-50 flex items-center justify-center sm:p-4 |
No padding on mobile so content fills viewport |
| Content container | relative bg-white sm:border rounded-none sm:rounded-lg w-full h-full sm:h-auto sm:max-w-md p-6 pt-14 sm:pt-6 overflow-y-auto |
Full viewport on mobile, constrained dialog on desktop |
| Icon badge | flex items-center justify-center w-12 h-12 mx-auto rounded-full |
Centered icon in colored circle |
| Title | text-lg font-semibold text-left mt-4 |
Left-aligned heading below icon |
| Buttons | flex justify-end gap-3 |
Right-aligned Cancel + Confirm |
| Close button | absolute top-4 right-4 |
Absolutely positioned, always accessible |
Switcher modals
For switcher modals (partner/organisation selector) that use items-start pt-[15vh] on desktop,
use this pattern instead to maintain center alignment on mobile:
<!-- Panel container for switcher modals -->
<div class="fixed inset-0 z-50 flex items-center justify-center
sm:items-start sm:pt-[15vh] sm:p-4">
<!-- Content centered on mobile, offset from top on desktop -->
</div>
Action button pattern
On detail pages, action buttons (enable/disable, cancel/accept) show inline on desktop and in a three-dot dropdown menu on mobile. This follows the ViewQuote pattern.
<!-- Desktop: inline buttons -->
<div class="hidden sm:flex gap-3">
<button type="button"
x-on:click="confirmOpen = true"
koala-btn="Danger" koala-btn-variant="Outlined"
class="hidden sm:inline-flex shrink-0">
Cancel quote
</button>
<a href="/accept" koala-btn="Primary"
class="hidden sm:inline-flex shrink-0">
Accept
</a>
</div>
<!-- Mobile: 3-dot dropdown -->
<div class="sm:hidden" x-data="{ menuOpen: false }">
<button type="button" x-on:click="menuOpen = !menuOpen"
class="p-2 text-gray-500">
<!-- 3-dot icon -->
</button>
<div x-show="menuOpen" x-on:click.outside="menuOpen = false"
class="absolute right-0 mt-1 w-48 bg-white dark:bg-gray-800
border border-gray-200 dark:border-gray-700
rounded-xl shadow-lg py-1 z-10">
<button type="button"
x-on:click="confirmOpen = true; menuOpen = false"
class="block w-full px-4 py-2 text-left text-red-600">
Cancel quote
</button>
<a href="/accept"
class="block px-4 py-2 text-gray-700">
Accept
</a>
</div>
</div>
Form modals
Form modals use sm:max-w-2xl for wider content. The content container must use
overflow-y-auto sm:overflow-visible so dropdowns are not clipped on desktop.
<!-- Content container for form modals -->
<div class="relative bg-white dark:bg-gray-800
sm:border border-gray-200 dark:border-gray-700
rounded-none sm:rounded-lg
w-full h-full sm:h-auto sm:max-w-2xl
p-6 pt-14 sm:pt-6
overflow-y-auto sm:overflow-visible">
<!-- Form content -->
</div>
Key rules
- All modals must be full-screen on mobile (<640px) and centered dialogs on desktop
- Icon: centered in a colored circular badge (
mx-auto rounded-full) - Title: left-aligned (
text-left),text-lg font-semibold, withmt-4 - Description: left-aligned,
text-gray-500 dark:text-gray-400 - Buttons: right-aligned (
flex justify-end gap-3), Cancel (Neutral) then Confirm (Danger or Primary) - Confirmation modals use
relativeon the content container withpt-14 sm:pt-6 - The close (X) button must be absolutely positioned at
top-4 right-4 - Form modals use
overflow-y-auto sm:overflow-visibleto avoid clipping dropdowns on desktop - Use
x-cloakon both the backdrop and modal to prevent flash of content on page load - Use
<koala-icon>for all SVG icons (close X, warning triangle, checkmark)