postiz-app/libraries/react-shared-libraries/src/form/input.tsx
2025-07-27 02:31:52 +02:00

88 lines
2.3 KiB
TypeScript

'use client';
import {
DetailedHTMLProps,
forwardRef,
InputHTMLAttributes,
ReactNode,
useEffect,
useMemo,
} from 'react';
import { clsx } from 'clsx';
import { useFormContext, useWatch } from 'react-hook-form';
import interClass from '../helpers/inter.font';
import { TranslatedLabel } from '../translation/translated-label';
export const Input = forwardRef<
HTMLInputElement,
DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> & {
removeError?: boolean;
error?: any;
disableForm?: boolean;
customUpdate?: () => void;
label: string;
name: string;
icon?: ReactNode;
translationKey?: string;
translationParams?: Record<string, string | number>;
}
>((props, ref) => {
const {
label,
icon,
removeError,
customUpdate,
className,
disableForm,
error,
translationKey,
translationParams,
...rest
} = props;
const form = useFormContext();
const err = useMemo(() => {
if (error) return error;
if (!form || !form.formState.errors[props?.name!]) return;
return form?.formState?.errors?.[props?.name!]?.message! as string;
}, [form?.formState?.errors?.[props?.name!]?.message, error]);
const watch = customUpdate ? form?.watch(props.name) : null;
useEffect(() => {
if (customUpdate) {
customUpdate();
}
}, [watch]);
return (
<div className="flex flex-col gap-[6px]">
{!!label && (
<div className={`${interClass} text-[14px]`}>
<TranslatedLabel
label={label}
translationKey={translationKey}
translationParams={translationParams}
/>
</div>
)}
<div
className={clsx(
'bg-newBgColorInner h-[42px] border-newTableBorder border rounded-[8px] text-textColor placeholder-textColor flex items-center justify-center',
className
)}
>
{icon && <div className="ps-[16px]">{icon}</div>}
<input
ref={ref}
className={clsx(
'h-full bg-transparent outline-none flex-1 text-[14px] text-textColor',
icon ? 'pl-[8px] pe-[16px]' : 'px-[16px]'
)}
{...rest}
/>
</div>
{!removeError && (
<div className="text-red-400 text-[12px]">{err || <>&nbsp;</>}</div>
)}
</div>
);
});
Input.displayName = 'Input';