FormCard 字段控件摊平嵌套三元

- options/multiline/input 三态改为 if/else 生成 inputSlot
- 复用一个 fieldClassName,去掉三份重复的边框/错误态样式与嵌套三元
This commit is contained in:
2026-10-07 11:00:34 +08:00
parent 8d74fa9aba
commit e4d46609cf
@@ -1,5 +1,5 @@
import { ImagePlus, Sparkles, Trash2 } from 'lucide-react';
import { useState } from 'react';
import { type ReactNode, useState } from 'react';
import { AssetImporter } from '../../../../../components/AssetImporter';
import { SPRITE_IMPORTER_SETTINGS } from '../../../../../components/AssetImporter/settings';
@@ -104,6 +104,58 @@ export function FormCard({
fieldErrors.find((item) => item.field === meta.field)?.reason ??
null;
const value = form[meta.field];
// 字段控件按 options → multiline → input 三态摊开算好,JSX 里只留一个 {inputSlot}:
// 不再用嵌套三元,也顺手复用同一份边框/错误态样式。
const fieldClassName = `w-full rounded-xl border bg-(--platform-input-fill) px-3 py-2 text-sm text-(--platform-text-strong) outline-none focus:border-(--platform-accent) ${
error
? 'border-(--platform-accent)'
: 'border-(--platform-surface-border)'
}`;
let inputSlot: ReactNode;
if (meta.options) {
inputSlot = (
<select
aria-label={meta.label}
value={value}
className={fieldClassName}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
>
<option value="">请选择分类</option>
{meta.options.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
);
} else if (meta.multiline) {
inputSlot = (
<textarea
aria-label={meta.label}
value={value}
placeholder={meta.placeholder}
rows={3}
className={`${fieldClassName} resize-y`}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
/>
);
} else {
inputSlot = (
<input
aria-label={meta.label}
value={value}
placeholder={meta.placeholder}
className={fieldClassName}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
/>
);
}
return (
<div key={meta.field} className="grid gap-1.5">
<div className="flex items-center justify-between gap-2">
@@ -114,56 +166,7 @@ export function FormCard({
<CopyButton value={value} label={meta.label} />
) : null}
</div>
{meta.options ? (
<select
aria-label={meta.label}
value={value}
className={`w-full rounded-xl border bg-(--platform-input-fill) px-3 py-2 text-sm text-(--platform-text-strong) outline-none focus:border-(--platform-accent) ${
error
? 'border-(--platform-accent)'
: 'border-(--platform-surface-border)'
}`}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
>
<option value="">请选择分类</option>
{meta.options.map((option) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
) : meta.multiline ? (
<textarea
aria-label={meta.label}
value={value}
placeholder={meta.placeholder}
rows={3}
className={`w-full resize-y rounded-xl border bg-(--platform-input-fill) px-3 py-2 text-sm text-(--platform-text-strong) outline-none focus:border-(--platform-accent) ${
error
? 'border-(--platform-accent)'
: 'border-(--platform-surface-border)'
}`}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
/>
) : (
<input
aria-label={meta.label}
value={value}
placeholder={meta.placeholder}
className={`w-full rounded-xl border bg-(--platform-input-fill) px-3 py-2 text-sm text-(--platform-text-strong) outline-none focus:border-(--platform-accent) ${
error
? 'border-(--platform-accent)'
: 'border-(--platform-surface-border)'
}`}
onChange={(event) =>
onChange(meta.field, event.currentTarget.value)
}
/>
)}
{inputSlot}
{error ? (
<p
role="alert"