'use client'; import { ChangeEvent } from 'react'; import { PatternFormat, NumberFormatBase, OnValueChange, } from 'react-number-format'; import TextInput, { TextInputProps } from '@/components/input/TextInput'; interface PatternInputProps extends Omit { /** * Format pattern, contoh: "##/##/####", "(###) ###-####", "####-####-####" */ format: string; /** Mask karakter kosong, misal "_" */ mask?: string; /** Menampilkan mask walau value kosong */ allowEmptyFormatting?: boolean; /** Placeholder karakter format, default: "#" */ patternChar?: string; /** Jika true, izinkan huruf (A-Z) selain angka */ inputVehicleNumber?: boolean; type?: 'text' | 'password' | 'tel'; } /** * PatternInput – tetap backward-compatible dengan Storybook * tapi bisa menerima huruf jika `allowCharacters={true}` */ const PatternInput = ({ type = 'text', format, mask = '_', allowEmptyFormatting = false, patternChar = '#', inputVehicleNumber = false, onChange, ...restProps }: PatternInputProps) => { const handleValueChange: OnValueChange = (values, { event }) => { const newEvent = event as ChangeEvent | undefined; if (newEvent) { newEvent.target.value = values.value.toUpperCase(); onChange?.(newEvent); } }; if (inputVehicleNumber) { return ( { const clean = value.replace(/[^a-z0-9]/gi, '').toUpperCase(); const match = clean.match(/^([A-Z]{0,2})(\d{0,4})([A-Z]{0,3})$/); if (!match) return clean; const [, prefix, number, suffix] = match; return [prefix, number, suffix].filter(Boolean).join(' '); }} removeFormatting={(val) => val.replace(/\s+/g, '')} isValidInputCharacter={(char) => /^[a-z0-9]$/i.test(char)} getCaretBoundary={(val) => Array(val.length + 1) .fill(true) .map(Boolean) } onValueChange={handleValueChange} /> ); } return ( ); }; export default PatternInput;