@maskito/react
Version:
The React-specific Maskito's library
67 lines (62 loc) • 2.22 kB
JavaScript
;
var core = require('@maskito/core');
var react = require('react');
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react.useLayoutEffect : react.useEffect;
function isThenable(x) {
return x && typeof x === 'object' && 'then' in x;
}
/**
* Hook for convenient use of Maskito in React
* @description For controlled inputs use `onInput` event
* @param options options used for creating Maskito
* @param elementPredicate function that can help find nested Input or TextArea
* @returns ref callback to pass it in React Element
* @example
* // To avoid unnecessary hook runs with Maskito recreation pass named variables
* // good example ✅
* useMaskito({ options: maskitoOptions, elementPredicate: maskitoPredicate })
*
* // bad example ❌
* useMaskito({ options: { mask: /^.*$/ }, elementPredicate: () => e.querySelector('input') })
*/
const useMaskito = ({
options = null,
elementPredicate = core.MASKITO_DEFAULT_ELEMENT_PREDICATE
} = {}) => {
const [hostElement, setHostElement] = react.useState(null);
const [element, setElement] = react.useState(null);
const onRefChange = react.useCallback(node => {
setHostElement(node);
}, []);
const latestPredicateRef = react.useRef(elementPredicate);
const latestOptionsRef = react.useRef(options);
latestPredicateRef.current = elementPredicate;
latestOptionsRef.current = options;
useIsomorphicLayoutEffect(() => {
if (!hostElement) {
return;
}
const elementOrPromise = elementPredicate(hostElement);
if (isThenable(elementOrPromise)) {
void elementOrPromise.then(el => {
if (latestPredicateRef.current === elementPredicate && latestOptionsRef.current === options) {
setElement(el);
}
});
} else {
setElement(elementOrPromise);
}
}, [hostElement, elementPredicate, latestPredicateRef, options, latestOptionsRef]);
useIsomorphicLayoutEffect(() => {
if (!element || !options) {
return;
}
const maskedElement = new core.Maskito(element, options);
return () => {
maskedElement.destroy();
setElement(null);
};
}, [options, element]);
return onRefChange;
};
exports.useMaskito = useMaskito;