feat(modals): FormModal gains submitDisabled + subtitle props

submitDisabled greys out the primary (so callers can gate it on validity
instead of a clickable-but-inert button); subtitle renders a muted line under
the title in the header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-06 14:53:28 +02:00
parent 7f156cc721
commit 55fa4045ad
2 changed files with 25 additions and 4 deletions

View File

@@ -255,12 +255,23 @@
gap: 12px; gap: 12px;
} }
.admin-modal-heading {
min-width: 0;
}
.admin-modal-title { .admin-modal-title {
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
color: var(--text-primary); color: var(--text-primary);
} }
.admin-modal-subtitle {
margin: 2px 0 0;
font-size: 12.5px;
font-weight: 500;
color: var(--text-secondary);
}
.admin-modal-close { .admin-modal-close {
flex-shrink: 0; flex-shrink: 0;
display: inline-flex; display: inline-flex;

View File

@@ -15,10 +15,15 @@ export interface FormModalProps {
onClose: () => void; onClose: () => void;
onSubmit?: () => void; // called when user clicks primary button (only if provided) onSubmit?: () => void; // called when user clicks primary button (only if provided)
title: string; title: string;
/** Optional muted line shown under the title in the header. */
subtitle?: ReactNode;
children: ReactNode; // modal body (form fields) children: ReactNode; // modal body (form fields)
submitLabel?: string; // primary button text submitLabel?: string; // primary button text
cancelLabel?: string; // cancel button text cancelLabel?: string; // cancel button text
loading?: boolean; loading?: boolean;
/** Disable the primary (submit) button — e.g. until the form is valid.
* Keeps the button visibly greyed out instead of clickable-but-inert. */
submitDisabled?: boolean;
hideFooter?: boolean; // for "view-only" modals hideFooter?: boolean; // for "view-only" modals
size?: "sm" | "md" | "lg"; // optional size?: "sm" | "md" | "lg"; // optional
closeOnBackdrop?: boolean; // default true closeOnBackdrop?: boolean; // default true
@@ -35,10 +40,12 @@ export default function FormModal({
onClose, onClose,
onSubmit, onSubmit,
title, title,
subtitle,
children, children,
submitLabel = "Uložit", submitLabel = "Uložit",
cancelLabel = "Zrušit", cancelLabel = "Zrušit",
loading = false, loading = false,
submitDisabled = false,
hideFooter = false, hideFooter = false,
size = "md", size = "md",
closeOnBackdrop = true, closeOnBackdrop = true,
@@ -107,9 +114,12 @@ export default function FormModal({
transition={{ duration, ease }} transition={{ duration, ease }}
> >
<div className="admin-modal-header"> <div className="admin-modal-header">
<h2 id={titleId} className="admin-modal-title"> <div className="admin-modal-heading">
{title} <h2 id={titleId} className="admin-modal-title">
</h2> {title}
</h2>
{subtitle && <p className="admin-modal-subtitle">{subtitle}</p>}
</div>
{!hideCloseButton && ( {!hideCloseButton && (
<button <button
type="button" type="button"
@@ -175,7 +185,7 @@ export default function FormModal({
type="button" type="button"
onClick={handlePrimaryClick} onClick={handlePrimaryClick}
className="admin-btn admin-btn-primary" className="admin-btn admin-btn-primary"
disabled={loading} disabled={loading || submitDisabled}
> >
{loading ? "Zpracování..." : submitLabel} {loading ? "Zpracování..." : submitLabel}
</button> </button>