입력값 제어 라이브러리 개관
프론트엔드 개발 시 사용자의 입력 데이터를 일정한 형식으로 강제하고 유효성을 검사하는 작업은 필수적입니다. imask.js 는 이러한 요구를 충족시키기 위해 설계된 경량화된 자바스크립트 유틸리티로, 별도의 의존성 없이 다양한 환경에서 안정적으로 구동됩니다. 텍스트 정규화, 날짜 변환, 통화 포맷팅 등 복잡한 로직을 간결한 설정으로 해결할 수 있습니다.
설치 및 기본 실행
프로젝트에 라이브러리를 적용하려면 패키지 관리자를 통해 설치합니다.
npm install imask
설치 후 임의의 DOM 요소를 선택하여 인스턴스를 생성하고 간단한 패턴을 지정하면 작동합니다.
import IMask from 'imask';
// 대상 요소 선택
const targetField = document.querySelector('#user-phone');
// 초기화 옵션 정의
const settings = {
mask: '+82-(00)-0000-0000',
lazy: false
};
// 인스턴스 생성 및 바인딩
const inputController = IMask(targetField, settings);
주요 속성 커스터마이징
기본 제공 옵션 외에도 상황별 요구사항에 맞도록 세부 파라미터를 조정할 수 있습니다.
1. 문자열 패턴 처리
고정된 형식의 데이터, 예를 들어 카드 번호나 주민등록번호 등을 처리할 때 사용합니다. 특수 기호를 정의하고 자동补全 여부를 제어합니다.
const patternConfig = {
mask: 'XXXX-YYYY-ZZZZ',
definitions: {
X: /[a-z]/,
Y: /[A-Z]/,
Z: /[0-9]/
},
overwrite: true, // 기존 글자 덮어쓰기
eager: 'remove' // 삭제 동작 모드
};
IMask(document.getElementById('pattern-target'), patternConfig);
2. 수치형 데이터 핸들링
숫자 입력 시 소수점 자리수 제한과 천 단위 구분 기호 추가가 가능합니다.
const numericSetup = {
mask: Number,
scale: 2, // 소수점 둘째 자리까지
thousandsSeparator: '.', // 천 단위 마침표
padFractionalZeros: true, // 자리수 채우기 활성화
radix: ',', // 소수점 쉼표
mapToRadix: ['.', ','], // 허용되는 소수점 입력값
min: 0,
max: 9999.99
};
IMask(document.getElementById('price-input'), numericSetup);
3. 시간 및 날짜 포맷팅
연월일 형태의 데이터를 일관되게 저장하기 위한 파서와 포맷터 함수를 구현합니다.
const dateConfig = {
mask: Date,
pattern: 'yyyy-mm-dd',
units: ['년', '월', '일'],
min: new Date('2000-01-01'),
max: new Date(),
// 값이 표시될 때 가공됨
format(dateObj) {
return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')}`;
}
};
IMask(document.getElementById('birth-date'), dateConfig);
복합 논리 처리 전략
상황에 따른 동적 전환
사용자가 입력하는 접두사에 따라 사용하는 마스크를 실시간으로 변경해야 하는 경우 배열 형태로 규칙을 정의할 수 있습니다.
const dynamicRules = [
{ mask: '+1 (000) 000-0000', startsWith: '1' },
{ mask: '+82 (00) 0000-0000', startsWith: '82' },
{ mask: '+44 000 000 0000', startsWith: '44' }
];
const smartMask = IMask(fieldElement, {
mask: dynamicRules
});
// 수동 분배 로직 필요 시
smartMask.on('insert', function () {
const val = this.value;
if (val.startsWith('82')) {
this.update({ mask: '+82 (00) 0000-0000' });
}
});
블록별 범위 제약
하나의 입력창 내에서 특정 구간만 숫자 범위를 제한하고자 할 때 블록 구성을 활용합니다.
const ipValidator = {
mask: '000.000.000.000',
blocks: {
'000': {
mask: IMask.MaskedRange,
from: 0,
to: 255
}
}
};
IMask(document.getElementById('server-ip'), ipValidator);
프레임워크 연동 방법
라이브러리 자체는 프레임워크 독립적이지만, 생태계 각 플러그인을 사용하여 리액티브하게 연결할 수 있습니다.
React 환경
import { useIMask } from 'react-imask';
const PhoneInputComponent = () => {
const { ref, value, maskRef } = useIMask({
mask: '+1 000-000-0000',
lazy: true
});
return (
<div>
<label>전화번호:</label>
<input ref={ref} />
<span>{value}</span>
</div>
);
};
Vue 3 환경
// main.js 에서 등록 권장
app.directive('imask', {
mounted(el, binding) {
const instance = IMask(el, binding.value);
el.imask = instance;
// 라이프사이클 관리용 핸들링 필요 시 여기서 작성
}
});
Angular 모듈
// app.module.ts
import { IMaskModule } from 'angular-imask';
@NgModule({
imports: [
CommonModule,
IMaskModule
]
})
export class AppModule {}
이벤트 리스닝 및 디버깅
데이터 변경 상태에 반응하여 부수 작업을 수행하거나, 문제 발생 시 내부 상태를 확인하는 것이 중요합니다.
생각 가능한 이벤트
const maskInstance = IMask(document.getElementById('debug-field'), {
mask: '000-000',
debug: true // 개발 중 추적 활성화
});
maskInstance.on('accept', () => {
console.log('유효한 문자 수신:', maskInstance.unmaskedValue);
});
maskInstance.on('complete', () => {
console.log('전체 패턴 입력 완료');
});
maskInstance.on('invalid', () => {
console.log('규칙 위반 문자 감지');
});
상태 업데이트 및 제거
런타임 중에 설정을 수정하거나 메모리 누수를 방지하기 위해 인스턴스를 해제하는 메소드를 제공합니다.
// 설정 변경
maskInstance.updateOptions({
mask: 'AAA-000',
skipInvalid: false
});
// 요소에서 분리
function cleanup() {
if (maskInstance) {
maskInstance.remove();
}
}
구현 시 고려 사항
- 너무 많은 옵션 조합보다는 핵심 기능에 집중하여 가독성을 유지하세요.
- 사용자 입력 경험을 위해
lazy속성을 적극적으로 활용하여 불필요한 플레이스홀더 노출을 줄입니다. - 비즈니스 로직이 복잡할 경우
validate콜백을 사용하여 최종 제출 전 검증을 추가하세요. - 모바일 키보드 최적화를 위해 입력 타입 속성을 올바르게 매핑해야 합니다.