Files
writer-work-flow/apps/web/components/ui/Field.tsx

50 lines
1.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { cloneElement, isValidElement, useId, type ReactNode } from "react";
import {
cn,
fieldErrorClass,
fieldHelpClass,
fieldLabelClass,
} from "@/lib/ui/variants";
interface FieldProps {
label: string;
children: ReactNode;
htmlFor?: string;
help?: ReactNode;
error?: ReactNode;
required?: boolean;
className?: string;
}
export function Field({
label,
children,
htmlFor,
help,
error,
required = false,
className,
}: FieldProps) {
const autoId = useId();
const id = htmlFor ?? autoId;
const labelText = required ? `${label} *` : label;
// 自动把 id 注入唯一子控件,建立 label↔控件关联仅当子控件自身未带 id
const control =
isValidElement<{ id?: string }>(children) && children.props.id == null
? cloneElement(children, { id })
: children;
return (
<div className={cn("space-y-1.5", className)}>
<label htmlFor={id} className={fieldLabelClass()}>
{labelText}
</label>
{control}
{error ? <p className={fieldErrorClass()}>{error}</p> : null}
{!error && help ? <p className={fieldHelpClass()}>{help}</p> : null}
</div>
);
}