Files
clj-ui-framework/src/ui/dialog.css
Florian Schroedl 5449d3c0f3 feat(dialog): add overlay-based dialog pattern (dialog-overlay + dialog-panel)
For reactive frameworks (Eucalypt, etc.) where native <dialog> with
.showModal() isn't practical. dialog-overlay provides the fixed backdrop,
dialog-panel provides the content box with padding/gap/animation.

Shared inner styles (dialog-header, dialog-body, dialog-footer) work
with both native <dialog> and overlay-based patterns.
2026-03-29 13:21:19 +02:00

134 lines
3.2 KiB
CSS

/* ── Shared dialog inner styles ───────────────────────────────────── */
/* Used by both native <dialog> and overlay-based .dialog-panel */
.dialog-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--size-4);
}
.dialog-header h1,
.dialog-header h2,
.dialog-header h3,
.dialog-header h4,
.dialog-header h5,
.dialog-header h6 {
margin: 0;
}
.dialog-header p {
font-size: var(--font-sm);
color: var(--fg-2);
margin: 0;
}
.dialog-body {
display: flex;
flex-direction: column;
gap: var(--size-3);
overflow-y: auto;
}
.dialog-body > *:first-child { margin-top: 0; }
.dialog-body > *:last-child { margin-bottom: 0; }
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: var(--size-2);
}
/* ── Native <dialog> ─────────────────────────────────────────────── */
.dialog {
position: fixed;
inset: 0;
z-index: 50;
width: min(100% - 2rem, 32rem);
max-height: 85vh;
margin: auto;
padding: 0;
background: var(--bg-0);
color: var(--fg-0);
border: var(--border-0);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-3);
overflow: hidden;
}
.dialog[open] {
display: flex;
flex-direction: column;
gap: var(--size-3);
padding: var(--size-6);
}
.dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
cursor: pointer;
}
/* ── Overlay-based dialog ────────────────────────────────────────── */
.dialog-overlay {
position: fixed;
inset: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
padding: var(--size-4);
background: rgba(0, 0, 0, 0.3);
animation: dialog-overlay-in 0.15s ease;
}
@keyframes dialog-overlay-in {
from { opacity: 0; }
to { opacity: 1; }
}
.dialog-panel {
position: relative;
display: flex;
flex-direction: column;
gap: var(--size-3);
width: 100%;
max-width: 28rem;
max-height: 85vh;
padding: var(--size-6);
background: var(--bg-1);
color: var(--fg-0);
border: var(--border-0);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-3);
overflow: hidden;
animation: dialog-panel-in 0.15s ease;
}
@keyframes dialog-panel-in {
from { opacity: 0; transform: scale(0.96) translateY(var(--size-2)); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
/* ── Dark mode ───────────────────────────────────────────────────── */
[data-theme="dark"] .dialog-overlay {
background: rgba(0, 0, 0, 0.5);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) .dialog-overlay {
background: rgba(0, 0, 0, 0.5);
}
}
/* ── Mobile ──────────────────────────────────────────────────────── */
@media (max-width: 768px) {
.dialog-panel {
max-width: none;
padding: var(--size-4);
}
}