import { useId } from "react"; import type { InputHTMLAttributes, ReactNode } from "react"; export interface InputProps extends InputHTMLAttributes { invalid?: boolean; } /** Input — radius 6px, 포커스 보더색 + ring. 좌측바 금지. §7.2 */ export function Input({ invalid, className, ...rest }: InputProps) { const cls = ["vg-input", className ?? ""].filter(Boolean).join(" "); return ( ); } export interface FieldProps { /** 라벨 텍스트 */ label?: ReactNode; /** 보조 안내 */ hint?: ReactNode; /** 에러 메시지 (있으면 input invalid) */ error?: ReactNode; /** input 에 연결할 자식. id 는 자동 연결되지 않으므로 필요 시 htmlFor 직접 사용 */ children: ReactNode; /** label htmlFor 연결용 (없으면 useId) */ htmlFor?: string; className?: string; } /** * Field — 라벨 + 입력 + 힌트/에러 묶음. * children 으로 등을 받는다(제어는 호출부). */ export function Field({ label, hint, error, children, htmlFor, className }: FieldProps) { const autoId = useId(); const fieldId = htmlFor ?? autoId; const cls = ["vg-field", className ?? ""].filter(Boolean).join(" "); return (
{label ? ( ) : null} {children} {error ? ( {error} ) : hint ? ( {hint} ) : null}
); }