Add shared WebUI layout primitives

This commit is contained in:
2026-08-18 10:42:55 +02:00
parent dd7ad4d9c7
commit 6814a41ae4
22 changed files with 574 additions and 111 deletions
+26 -3
View File
@@ -9,12 +9,23 @@ import {
type DialogStackId
} from "./dialogStack";
import type { PlatformInterfaceIdentityProps } from "../types";
import { DialogActions, type DialogActionAlignment } from "./DialogAnatomy";
export type DialogSize = "small" | "default" | "large" | "wide" | "full";
export type DialogVariant = "default" | "administration";
export type DialogBodyPadding = "none" | "compact" | "default";
export type DialogProps = PlatformInterfaceIdentityProps & {
open: boolean;
title: ReactNode;
children: ReactNode;
footer?: ReactNode;
description?: ReactNode;
notices?: ReactNode;
size?: DialogSize;
variant?: DialogVariant;
bodyPadding?: DialogBodyPadding;
footerAlignment?: DialogActionAlignment;
role?: "dialog" | "alertdialog";
ariaDescribedBy?: string;
closeLabel?: string;
@@ -42,6 +53,12 @@ export default function Dialog({
title,
children,
footer,
description,
notices,
size = "default",
variant = "default",
bodyPadding = "default",
footerAlignment = "end",
role = "dialog",
ariaDescribedBy,
closeLabel = "i18n:govoplan-core.close.bbfa773e",
@@ -83,6 +100,8 @@ export default function Dialog({
const renderedTitle = translateReactNode(title, translateText);
const renderedChildren = translateReactNode(children, translateText);
const renderedFooter = translateReactNode(footer, translateText);
const renderedDescription = translateReactNode(description, translateText);
const renderedNotices = translateReactNode(notices, translateText);
const translatedCloseLabel = translateText(closeLabel);
useEffect(() => {
@@ -134,7 +153,7 @@ export default function Dialog({
<section
ref={panelRef}
tabIndex={-1}
className={joinClasses("dialog-panel", className)}
className={joinClasses("dialog-panel", `dialog-panel-size-${size}`, `dialog-panel-${variant}`, className)}
style={panelStyle}
role={role}
aria-modal="true"
@@ -162,8 +181,12 @@ export default function Dialog({
</button>
)}
</div>
<div className={joinClasses("dialog-body", bodyClassName)}>{renderedChildren}</div>
{footer && <div className={joinClasses("dialog-footer", footerClassName)}>{renderedFooter}</div>}
<div className={joinClasses("dialog-body", `dialog-body-padding-${bodyPadding}`, bodyClassName)}>
{description && <div className="dialog-description">{renderedDescription}</div>}
{notices && <div className="dialog-notices">{renderedNotices}</div>}
{renderedChildren}
</div>
{footer && <div className={joinClasses("dialog-footer", footerClassName)}><DialogActions align={footerAlignment}>{renderedFooter}</DialogActions></div>}
</section>
</div>
);