71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import type { HTMLAttributes } from 'react';
|
|
import { useMemo } from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface InputErrorProps extends HTMLAttributes<HTMLParagraphElement> {
|
|
message?: string;
|
|
label?: string;
|
|
}
|
|
|
|
export default function InputError({
|
|
message,
|
|
label,
|
|
className = '',
|
|
...props
|
|
}: InputErrorProps) {
|
|
const formattedError = useMemo(() => {
|
|
if (!message) {
|
|
return null;
|
|
}
|
|
|
|
if (!label) {
|
|
return message;
|
|
}
|
|
|
|
// Preserve all-caps labels (like NIK), otherwise capitalize first letter and lowercase the rest
|
|
const isAllOptionsCaps = label === label.toUpperCase() && label.length > 1;
|
|
const formattedLabel = isAllOptionsCaps
|
|
? label
|
|
: label.charAt(0).toUpperCase() + label.slice(1).toLowerCase();
|
|
|
|
const words = message.split(' ');
|
|
|
|
// List of common Indonesian and English validation verbs/connectors that follow the attribute
|
|
const verbs = [
|
|
'wajib', 'harus', 'berupa', 'adalah', 'minimal', 'maksimal', 'tidak', 'kurang', 'lebih', 'antara', 'sudah',
|
|
'is', 'must', 'field', 'has', 'was', 'should', 'cannot', 'required', 'invalid'
|
|
];
|
|
|
|
// Find the first occurrence of a verb
|
|
let verbIndex = -1;
|
|
|
|
for (let i = 0; i < words.length; i++) {
|
|
if (verbs.includes(words[i].toLowerCase())) {
|
|
verbIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (verbIndex !== -1) {
|
|
// Replace everything before the verb with the label
|
|
return `${formattedLabel} ${words.slice(verbIndex).join(' ')}`;
|
|
}
|
|
|
|
// Fallback to replacing only the first word if no verb found
|
|
if (words.length > 0) {
|
|
return `${formattedLabel} ${words.slice(1).join(' ')}`;
|
|
}
|
|
|
|
return message;
|
|
}, [message, label]);
|
|
|
|
return formattedError ? (
|
|
<p
|
|
{...props}
|
|
className={cn('text-sm text-red-600 dark:text-red-400', className)}
|
|
>
|
|
{formattedError}
|
|
</p>
|
|
) : null;
|
|
}
|