mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-22 22:35:45 +00:00
feat(FE-166-169): Slicing UI Penjualan Form dan Client side validation
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
'use client';
|
||||
|
||||
import { ChangeEvent } from 'react';
|
||||
import {
|
||||
PatternFormat,
|
||||
NumberFormatBase,
|
||||
NumberFormatBaseProps,
|
||||
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;
|
||||
Reference in New Issue
Block a user