Files
lti-web-client/src/components/input/PatternInput.tsx
T

90 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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<TextInputProps, 'type'> {
/**
* 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<HTMLInputElement> | undefined;
if (newEvent) {
newEvent.target.value = values.value.toUpperCase();
onChange?.(newEvent);
}
};
if (inputVehicleNumber) {
return (
<NumberFormatBase
{...restProps}
type={type}
customInput={TextInput}
format={(value) => {
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 (
<PatternFormat
{...restProps}
type={type}
format={format}
mask={mask}
allowEmptyFormatting={allowEmptyFormatting}
patternChar={patternChar}
customInput={TextInput}
onValueChange={handleValueChange}
/>
);
};
export default PatternInput;