ui: uniform badge sizing across record rows + fixed-width right-aligned label column in detail meta grid
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { Badge, NeutralBadge } from '@/components/ui';
|
||||
import type { FootprintRow } from '@/lib/types';
|
||||
|
||||
// 记录徽章统一尺寸:同高 22px、最小宽 52px、居中、同字号 —— 整行排列规整
|
||||
export const ROW_BADGE_CLS = 'inline-flex h-[22px] min-w-[52px] items-center justify-center gap-1 rounded-sm border px-2 text-[11.5px] font-medium whitespace-nowrap';
|
||||
|
||||
const STATUS_MAP: Record<string, { label: string; color: string; bg: string }> = {
|
||||
draft: { label: '草稿', color: 'var(--text-3)', bg: 'var(--surface-3)' },
|
||||
ongoing: { label: '进行中', color: 'var(--brand-text)', bg: 'var(--brand-subtle)' },
|
||||
@@ -12,7 +15,7 @@ export function StatusBadge({ status }: { status: string }) {
|
||||
const s = STATUS_MAP[status] ?? STATUS_MAP.draft;
|
||||
return (
|
||||
<span
|
||||
className="inline-flex items-center rounded-sm px-1.5 py-px text-[11px] leading-[18px] font-medium whitespace-nowrap"
|
||||
className={ROW_BADGE_CLS + ' border-transparent'}
|
||||
style={{ color: s.color, backgroundColor: s.bg }}
|
||||
>
|
||||
{s.label}
|
||||
@@ -31,7 +34,7 @@ const LEVEL_COLORS: Record<string, string> = {
|
||||
|
||||
export function LevelBadge({ level }: { level?: string | null }) {
|
||||
if (!level) return null;
|
||||
return <Badge color={LEVEL_COLORS[level] ?? 'var(--text-3)'}>{level}</Badge>;
|
||||
return <Badge color={LEVEL_COLORS[level] ?? 'var(--text-3)'} className={ROW_BADGE_CLS}>{level}</Badge>;
|
||||
}
|
||||
|
||||
const GRADE_COLORS: Record<string, string> = {
|
||||
@@ -44,21 +47,21 @@ const GRADE_COLORS: Record<string, string> = {
|
||||
|
||||
export function GradeBadge({ grade }: { grade?: string | null }) {
|
||||
if (!grade) return null;
|
||||
return <Badge color={GRADE_COLORS[grade] ?? 'var(--text-3)'}>{grade}</Badge>;
|
||||
return <Badge color={GRADE_COLORS[grade] ?? 'var(--text-3)'} className={ROW_BADGE_CLS}>{grade}</Badge>;
|
||||
}
|
||||
|
||||
export function RoleBadge({ role }: { role?: string | null }) {
|
||||
if (!role) return null;
|
||||
return <NeutralBadge>{role}</NeutralBadge>;
|
||||
return <NeutralBadge className={ROW_BADGE_CLS}>{role}</NeutralBadge>;
|
||||
}
|
||||
|
||||
export function NegativeBadge() {
|
||||
return <Badge color="var(--danger)">负面</Badge>;
|
||||
return <Badge color="var(--danger)" className={ROW_BADGE_CLS}>负面</Badge>;
|
||||
}
|
||||
|
||||
export function TypeBadge({ row }: { row: FootprintRow }) {
|
||||
return (
|
||||
<Badge color={row.type_color}>
|
||||
<Badge color={row.type_color} className={ROW_BADGE_CLS}>
|
||||
{row.type_name}
|
||||
</Badge>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Pencil, Trash2, Paperclip, FileText } from 'lucide-react';
|
||||
import { attachmentRead, attachmentThumb, footprintGet, listDimensions, listTypes } from '@/lib/api';
|
||||
import type { Attachment, FormField } from '@/lib/types';
|
||||
import { Badge, Button, Confirm, Dialog, useToast } from '@/components/ui';
|
||||
import { StatusBadge, LevelBadge, GradeBadge, RoleBadge, NegativeBadge } from '@/components/common/badges';
|
||||
import { StatusBadge, LevelBadge, GradeBadge, RoleBadge, NegativeBadge, ROW_BADGE_CLS } from '@/components/common/badges';
|
||||
import { AttachmentPreview } from '@/components/common/AttachmentPreview';
|
||||
import { makeThumb } from '@/lib/img';
|
||||
import { fmtRange, fmtDateTime, fmtSize } from '@/lib/format';
|
||||
@@ -135,13 +135,13 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
|
||||
<div>
|
||||
<h2 className="text-[20px] font-bold leading-tight tracking-tight text-ink-1" style={{ textWrap: 'balance' }}>{d.title}</h2>
|
||||
<div className="mt-2.5 flex flex-wrap items-center gap-1.5">
|
||||
<Badge color={d.type_color}>{d.type_name}</Badge>
|
||||
<Badge color={d.type_color} className={ROW_BADGE_CLS}>{d.type_name}</Badge>
|
||||
<LevelBadge level={d.level} />
|
||||
<GradeBadge grade={d.award_grade} />
|
||||
<RoleBadge role={d.role} />
|
||||
<StatusBadge status={d.status} />
|
||||
{d.polarity === 'negative' && <NegativeBadge />}
|
||||
{d.rank != null && <Badge color="var(--text-3)">第 {d.rank} 名</Badge>}
|
||||
{d.rank != null && <Badge color="var(--text-3)" className={ROW_BADGE_CLS}>第 {d.rank} 名</Badge>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -272,8 +272,8 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
|
||||
|
||||
function MetaItem({ label, value }: { label: string; value: string }) {
|
||||
return (
|
||||
<div className="flex min-w-0 gap-2">
|
||||
<span className="shrink-0 text-ink-3">{label}</span>
|
||||
<div className="grid min-w-0 grid-cols-[76px_1fr] gap-x-2.5">
|
||||
<span className="shrink-0 text-right text-ink-3">{label}</span>
|
||||
<span className="min-w-0 truncate font-medium text-ink-1" title={value}>{value}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user