[1252] 일본의 전각 숫자, 반각 함수변경

This commit is contained in:
ysCha 2025-08-22 11:18:49 +09:00
parent 848f75bafa
commit 736328ef0f

View File

@ -23,79 +23,82 @@ export const onlyNumberWithDotInputChange = (e, callback) => {
// ============================= // =============================
// Number normalization utilities // Number normalization utilities
// ============================= // =============================
// 1) Normalize any string to NFKC and keep only ASCII digits 0-9. // 마지막으로 유효했던 값 추적
// 1) Normalize any string to keep only ASCII digits 0-9 let lastValidDigits = '';
// IME composition state tracking let lastValidDecimal = '';
let isComposingDigits = false;
let lastDigitsValue = '';
let isComposingDecimal = false;
let lastDecimalValue = '';
/** /**
* 숫자만 포함된 문자열로 정규화 (0-9) * 숫자만 포함된 문자열로 정규화 (0-9)
* - 전각 숫자반각으로 변환 * - 전각 숫자 -> 반각
* - 숫자아닌 문자 제거 * - 숫자 제거
* - IME 입력 대응 * - 결과가 유효하면 길이/증가폭과 무관하게 허용
*/ */
export function normalizeDigits(value) { export function normalizeDigits(value) {
if (value == null) return ''; if (value == null || value === '') {
if (isComposingDigits) return value; lastValidDigits = '';
return '';
// 전각 숫자를 반각으로 변환
const normalized = String(value).replace(/[-]/g, s =>
String.fromCharCode(s.charCodeAt(0) - 0xFEE0)
);
// IME 조합 중인지 확인
if (lastDigitsValue && normalized.startsWith(lastDigitsValue) &&
normalized.length > lastDigitsValue.length + 1) {
isComposingDigits = true;
setTimeout(() => { isComposingDigits = false; }, 0);
return value;
} }
// 숫자만 남기기 const converted = String(value).replace(/[-]/g, s =>
const result = normalized.replace(/\D/g, ''); String.fromCharCode(s.charCodeAt(0) - 0xFEE0)
lastDigitsValue = result; );
return result; const normalized = converted.replace(/\D/g, '');
if (normalized === '') {
lastValidDigits = '';
return '';
}
if (/^\d+$/.test(normalized)) {
lastValidDigits = normalized;
return normalized;
}
return lastValidDigits || '';
} }
/** /**
* 소수점이 포함된 숫자 문자열로 정규화 * 소수점이 포함된 숫자 문자열로 정규화
* - 전각 숫자와 소수점을 반각으로 변환 * - 전각 숫자/ -> 반각
* - 소수점은 개만 유지 * - 숫자/ 제거
* - IME 입력 대응 * - 점은 번째만 허용
*/ */
export function normalizeDecimal(value) { export function normalizeDecimal(value) {
if (value == null) return ''; if (value == null || value === '') {
if (isComposingDecimal) return value; lastValidDecimal = '';
return '';
}
// 전각 숫자와 소수점을 반각으로 변환 let converted = String(value).replace(/[-]/g, s =>
const normalized = String(value).replace(/[-]/g, s =>
s === '' ? '.' : String.fromCharCode(s.charCodeAt(0) - 0xFEE0) s === '' ? '.' : String.fromCharCode(s.charCodeAt(0) - 0xFEE0)
); );
converted = converted.replace(/[^0-9.]/g, '');
// IME 조합 중인지 확인 const firstDot = converted.indexOf('.');
if (lastDecimalValue && normalized.startsWith(lastDecimalValue) && let normalized;
normalized.length > lastDecimalValue.length + 1) {
isComposingDecimal = true;
setTimeout(() => { isComposingDecimal = false; }, 0);
return value;
}
// 소수점 처리 if (firstDot !== -1) {
const parts = normalized.split('.'); const integerPart = converted.slice(0, firstDot).replace(/\D/g, '');
let result; const fractionPart = converted.slice(firstDot + 1).replace(/\D/g, '');
if (parts.length > 1) { normalized = integerPart + '.' + fractionPart;
result = parts[0].replace(/\D/g, '') + '.' + parts[1].replace(/\D/g, '');
} else { } else {
result = normalized.replace(/\D/g, ''); normalized = converted.replace(/\D/g, '');
} }
lastDecimalValue = result; if (normalized === '') {
return result; lastValidDecimal = '';
return '';
} }
if (/^\d+(\.\d*)?$/.test(normalized) || /^\d+$/.test(normalized)) {
lastValidDecimal = normalized;
return normalized;
}
return lastValidDecimal || '';
}
// 2-1) Limit fractional digits for decimal numbers. Default to 2 digits. // 2-1) Limit fractional digits for decimal numbers. Default to 2 digits.
export function normalizeDecimalLimit(value, maxFractionDigits = 2) { export function normalizeDecimalLimit(value, maxFractionDigits = 2) {
const s = normalizeDecimal(value) const s = normalizeDecimal(value)