import type { InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes, } from 'react'; export type PlatformTextFieldSize = 'xs' | 'sm' | 'md' | 'lg'; export type PlatformTextFieldDensity = 'default' | 'compact' | 'roomy'; export type PlatformTextFieldTone = 'warm' | 'rose' | 'emerald' | 'sky'; export type PlatformTextFieldSurface = 'platform' | 'editorDark'; type PlatformTextFieldBaseProps = { size?: PlatformTextFieldSize; density?: PlatformTextFieldDensity; tone?: PlatformTextFieldTone; surface?: PlatformTextFieldSurface; }; type PlatformTextFieldInputProps = Omit< InputHTMLAttributes, 'size' > & PlatformTextFieldBaseProps & { variant?: 'input'; }; type PlatformTextFieldTextareaProps = TextareaHTMLAttributes & PlatformTextFieldBaseProps & { variant: 'textarea'; }; export type PlatformTextFieldProps = | PlatformTextFieldInputProps | PlatformTextFieldTextareaProps; export type PlatformSelectFieldProps = Omit< SelectHTMLAttributes, 'size' > & PlatformTextFieldBaseProps; const PLATFORM_TEXT_FIELD_SIZE_CLASS: Record = { xs: 'text-sm leading-5', sm: 'text-sm font-semibold', md: 'text-sm leading-6', lg: 'text-base font-semibold', }; const PLATFORM_TEXT_FIELD_PLATFORM_DENSITY_CLASS: Record< PlatformTextFieldDensity, string > = { default: 'rounded-[1rem] bg-white/86 px-3 py-3', compact: 'rounded-[0.85rem] bg-white/90 px-3 py-2', roomy: 'rounded-[1rem] bg-white/90 px-4 py-3', }; const PLATFORM_TEXT_FIELD_EDITOR_DARK_DENSITY_CLASS: Record< PlatformTextFieldDensity, string > = { default: 'rounded-[1rem] bg-black/30 px-3 py-3', compact: 'rounded-[0.85rem] bg-black/30 px-3 py-2', roomy: 'rounded-[1rem] bg-black/30 px-4 py-3', }; const PLATFORM_TEXT_FIELD_PLATFORM_TONE_CLASS: Record< PlatformTextFieldTone, string > = { warm: 'focus:border-[var(--platform-surface-hover-border)] focus:ring-[var(--platform-warm-border)]', rose: 'focus:border-rose-200 focus:ring-rose-100', emerald: 'focus:border-emerald-200 focus:ring-emerald-100', sky: 'focus:border-sky-200 focus:ring-sky-100', }; const PLATFORM_TEXT_FIELD_EDITOR_DARK_TONE_CLASS: Record< PlatformTextFieldTone, string > = { warm: 'focus:border-amber-300/40', rose: 'focus:border-rose-300/40', emerald: 'focus:border-emerald-400/40', sky: 'focus:border-sky-400/40', }; function buildPlatformTextFieldClassName({ surface, size, density, tone, multiline, className, }: { surface: PlatformTextFieldSurface; size: PlatformTextFieldSize; density: PlatformTextFieldDensity; tone: PlatformTextFieldTone; multiline?: boolean; className?: string; }) { const isEditorDark = surface === 'editorDark'; return [ 'w-full platform-text-field outline-none transition disabled:cursor-not-allowed disabled:opacity-60', isEditorDark ? 'platform-text-field--editor-dark border border-white/10 text-white' : 'border border-[var(--platform-subpanel-border)] text-[var(--platform-text-strong)] focus:bg-white focus:ring-2', isEditorDark ? PLATFORM_TEXT_FIELD_EDITOR_DARK_DENSITY_CLASS[density] : PLATFORM_TEXT_FIELD_PLATFORM_DENSITY_CLASS[density], PLATFORM_TEXT_FIELD_SIZE_CLASS[size], isEditorDark ? PLATFORM_TEXT_FIELD_EDITOR_DARK_TONE_CLASS[tone] : PLATFORM_TEXT_FIELD_PLATFORM_TONE_CLASS[tone], multiline ? 'resize-none' : null, className, ] .filter(Boolean) .join(' '); } /** * 平台白底表单输入框。 * 统一承接结果页 / 工作台白底圆角输入框和文本域的基础 chrome。 */ export function PlatformTextField({ variant = 'input', size = 'sm', density = 'default', tone = 'warm', surface = 'platform', className, ...fieldProps }: PlatformTextFieldProps) { const fieldClassName = buildPlatformTextFieldClassName({ surface, size, density, tone, multiline: variant === 'textarea', className, }); if (variant === 'textarea') { return (