shoc-frontend-new/src/components/ui/form-field.tsx
2026-07-24 11:32:58 -03:00

70 lines
1.9 KiB
TypeScript

import type { ReactNode } from "react";
import { FormControl, FormHelperText, FormLabel, type FormControlProps } from "@mui/material";
import { cn } from "@/lib/utils";
type FormFieldAppearance = "default" | "auth";
type FormFieldProps = FormControlProps & {
label: string;
htmlFor?: string;
helperText?: string;
error?: boolean;
required?: boolean;
children: ReactNode;
className?: string;
appearance?: FormFieldAppearance;
};
const appearanceClassName: Record<FormFieldAppearance, string> = {
default: "gap-1",
auth: "gap-1.5 [&_.MuiFormLabel-root]:mb-0 [&_.MuiFormLabel-root]:!font-sans [&_.MuiFormLabel-root]:![font-size:var(--text-base-sm)] [&_.MuiFormLabel-root]:!font-medium [&_.MuiFormLabel-root]:!leading-[1.5] [&_.MuiFormLabel-root]:!normal-case [&_.MuiFormLabel-root]:!tracking-normal",
};
const appearanceLabelClassName: Record<FormFieldAppearance, string> = {
default: "text-label static mb-1 text-foreground normal-case",
auth: "static text-foreground normal-case",
};
const appearanceLabelSx: Record<FormFieldAppearance, object | undefined> = {
default: {
fontSize: "0.8125rem",
fontWeight: 600,
letterSpacing: "normal",
textTransform: "none",
lineHeight: 1.5,
},
auth: undefined,
};
export function FormField({
label,
htmlFor,
helperText,
error,
required,
children,
className,
appearance = "default",
...props
}: FormFieldProps) {
return (
<FormControl
error={error}
required={required}
fullWidth
className={cn(appearanceClassName[appearance], className)}
{...props}
>
<FormLabel
htmlFor={htmlFor}
className={appearanceLabelClassName[appearance]}
sx={appearanceLabelSx[appearance]}
>
{label}
</FormLabel>
{children}
{Boolean(helperText) && <FormHelperText>{helperText}</FormHelperText>}
</FormControl>
);
}