react-imask
Version:
React input mask
121 lines (118 loc) • 3.77 kB
JavaScript
import IMask from 'imask/esm/imask';
import { useRef, useState, useCallback, useEffect } from 'react';
function useIMask(opts, _temp) {
let {
onAccept,
onComplete,
ref = useRef(null),
defaultValue,
defaultUnmaskedValue,
defaultTypedValue
} = _temp === void 0 ? {} : _temp;
const maskRef = useRef(null);
const [lastAcceptState, setLastAcceptState] = useState({});
const [value, setValue] = useState('');
const [unmaskedValue, setUnmaskedValue] = useState('');
const [typedValue, setTypedValue] = useState();
const _destroyMask = useCallback(() => {
var _maskRef$current;
(_maskRef$current = maskRef.current) == null || _maskRef$current.destroy();
maskRef.current = null;
}, []);
const storeLastAcceptedValues = useCallback(() => {
const m = maskRef.current;
if (!m) return;
setLastAcceptState({
value: m.value,
unmaskedValue: m.unmaskedValue,
typedValue: m.typedValue
});
setTypedValue(m.typedValue);
setUnmaskedValue(m.unmaskedValue);
setValue(m.value);
}, []);
const _onAccept = useCallback(event => {
const m = maskRef.current;
if (!m) return;
storeLastAcceptedValues();
onAccept == null || onAccept(m.value, m, event);
}, [onAccept]);
const _onComplete = useCallback(event => maskRef.current && (onComplete == null ? void 0 : onComplete(maskRef.current.value, maskRef.current, event)), [onComplete]);
useEffect(() => {
const {
value: lastAcceptValue,
...state
} = lastAcceptState;
const mask = maskRef.current;
if (!mask || value === undefined) return;
if (lastAcceptValue !== value) {
mask.value = value;
if (mask.value !== value) _onAccept();
}
setLastAcceptState(state);
}, [value]);
useEffect(() => {
const {
unmaskedValue: lastAcceptUnmaskedValue,
...state
} = lastAcceptState;
const mask = maskRef.current;
if (!mask || unmaskedValue === undefined) return;
if (lastAcceptUnmaskedValue !== unmaskedValue) {
mask.unmaskedValue = unmaskedValue;
if (mask.unmaskedValue !== unmaskedValue) _onAccept();
}
setLastAcceptState(state);
}, [unmaskedValue]);
useEffect(() => {
const {
typedValue: lastAcceptTypedValue,
...state
} = lastAcceptState;
const mask = maskRef.current;
if (!mask || typedValue === undefined) return;
if (lastAcceptTypedValue !== typedValue) {
mask.typedValue = typedValue;
if (!mask.masked.typedValueEquals(typedValue)) _onAccept();
}
setLastAcceptState(state);
}, [typedValue]);
useEffect(() => {
const el = ref.current;
if (!el || !(opts != null && opts.mask)) return _destroyMask();
const mask = maskRef.current;
if (!mask) {
if (el && opts != null && opts.mask) {
maskRef.current = IMask(el, opts);
storeLastAcceptedValues();
if (defaultValue !== undefined) setValue(defaultValue);
if (defaultUnmaskedValue !== undefined) setUnmaskedValue(defaultUnmaskedValue);
if (defaultTypedValue !== undefined) setTypedValue(defaultTypedValue);
}
} else {
mask == null || mask.updateOptions(opts); // TODO fix no idea
}
}, [opts, _destroyMask, _onAccept]);
useEffect(() => {
if (!maskRef.current) return;
const mask = maskRef.current;
mask.on('accept', _onAccept);
mask.on('complete', _onComplete);
return () => {
mask.off('accept', _onAccept);
mask.off('complete', _onComplete);
};
}, [_onAccept, _onComplete]);
useEffect(() => _destroyMask, [_destroyMask]);
return {
ref,
maskRef,
value,
setValue,
unmaskedValue,
setUnmaskedValue,
typedValue,
setTypedValue
};
}
export { useIMask as default };