feat(desktop): add compact modal size

This commit is contained in:
leokun
2026-09-05 00:12:20 +08:00
parent 2cb15b541b
commit c379c315e6
4 changed files with 21 additions and 8 deletions
@@ -162,6 +162,12 @@
}
}
.actionBody {
display: flex;
flex-direction: column;
gap: 12px;
}
.actionDescription {
color: var(--vscode-descriptionForeground);
font-size: type.$font-size-xs;
@@ -420,12 +420,13 @@ function ResourceActionModal({ action, cardAction, result, busy, error, onClose,
const cardActions = cardAction ? [cardAction] : [];
return <>
<Modal open title={title} busy={busy} onClose={onClose} submitLabel={t("关闭")} onSubmit={onClose}>
{result?.description && <span className={styles.actionDescription}>{pluginText(result.description, locale)}</span>}
{busy && <span className={styles.empty}>{t("正在加载…")}</span>}
{error && <span className={styles.error} role="alert">{error}</span>}
{!busy && !error && result && result.cards.length === 0 && <span className={styles.empty}>{t("没有可用的重置卡。")}</span>}
{!busy && !error && result && <div className={styles.actionCardList}>
<Modal compact open title={title} busy={busy} onClose={onClose} submitLabel={t("关闭")} onSubmit={onClose}>
<div className={styles.actionBody}>
{result?.description && <span className={styles.actionDescription}>{pluginText(result.description, locale)}</span>}
{busy && <span className={styles.empty}>{t("正在加载…")}</span>}
{error && <span className={styles.error} role="alert">{error}</span>}
{!busy && !error && result && result.cards.length === 0 && <span className={styles.empty}>{t("没有可用的重置卡。")}</span>}
{!busy && !error && result && <div className={styles.actionCardList}>
{result.cards.map((card) => <Card key={card.id} className={styles.actionCard}>
<div className={styles.actionCardMain}>
<strong>{pluginText(card.title, locale)}</strong>
@@ -444,6 +445,7 @@ function ResourceActionModal({ action, cardAction, result, busy, error, onClose,
</div>}
</Card>)}
</div>}
</div>
</Modal>
{pendingCard && cardAction && <ConfirmDialog
open
@@ -54,6 +54,10 @@
width: min(1080px, calc(100vw - 48px));
}
.compact {
width: min(560px, calc(100vw - 48px));
}
.fullHeight {
height: calc(100vh - var(--window-header-height) - 24px);
}
+3 -2
View File
@@ -12,6 +12,7 @@ type ModalProps = {
banner?: ReactNode;
busy?: boolean;
wide?: boolean;
compact?: boolean;
fullHeight?: boolean;
role?: "dialog" | "alertdialog";
ariaDescribedBy?: string;
@@ -38,7 +39,7 @@ function focusableElements(root: HTMLElement) {
.filter((element) => element.getClientRects().length > 0);
}
export function Modal({ id, open, title, children, banner, busy, wide, fullHeight, role = "dialog", ariaDescribedBy, initialFocus = "first", onClose, onSubmit, secondaryAction, closeLabel = t("取消"), submitLabel = t("保存"), submitDisabled = false }: ModalProps) {
export function Modal({ id, open, title, children, banner, busy, wide, compact, fullHeight, role = "dialog", ariaDescribedBy, initialFocus = "first", onClose, onSubmit, secondaryAction, closeLabel = t("取消"), submitLabel = t("保存"), submitDisabled = false }: ModalProps) {
const dialog = useRef<HTMLDivElement>(null);
const submitButton = useRef<HTMLButtonElement>(null);
const closeRef = useRef(onClose);
@@ -89,7 +90,7 @@ export function Modal({ id, open, title, children, banner, busy, wide, fullHeigh
if (!open) return null;
return createPortal(<div className={styles.mask}>
<div className={styles.dragLayer} data-tauri-drag-region aria-hidden="true" />
<div id={id} ref={dialog} className={[styles.dialog, wide && styles.wide, fullHeight && styles.fullHeight].filter(Boolean).join(" ")} role={role} aria-modal="true" aria-labelledby={titleId} aria-describedby={ariaDescribedBy} tabIndex={-1}>
<div id={id} ref={dialog} className={[styles.dialog, wide && styles.wide, compact && styles.compact, fullHeight && styles.fullHeight].filter(Boolean).join(" ")} role={role} aria-modal="true" aria-labelledby={titleId} aria-describedby={ariaDescribedBy} tabIndex={-1}>
<header id={titleId}>{title}</header>
{banner && <div className={styles.banner}>{banner}</div>}
<ScrollableContent alwaysShowVertical className={styles.body} contentClassName={styles.bodyContent}>{children}</ScrollableContent>