@gravityforms/components
Version:
UI components for use in Gravity Forms development. Both React and vanilla js flavors.
123 lines (111 loc) • 3.75 kB
JavaScript
import { parse, format, templateParser, parseDigit, templateFormatter } from 'input-format';
import { AsYouType } from 'libphonenumber-js';
/**
* @function edit
* @description Edits text based on the operation.
* Copied from the original function `edit` from `input-format` package.
* The original function is not exported, so it was copied here.
*
* @param {string} value The value to edit.
* @param {number} caret The caret position.
* @param {string} operation The operation to perform, one of `Backspace` or `Delete`.
*
* @return {object} The edited value and the caret position.
*/
export const edit = ( value, caret, operation ) => {
// Edits text `value` (if `operation` is passed) and repositions the `caret` if needed.
//
// Example:
//
// value - '88005553535'
// caret - 2 // starting from 0; is positioned before the first zero
// operation - 'Backspace'
//
// Returns
// {
// value: '8005553535'
// caret: 1
// }
//
// Currently supports just 'Delete' and 'Backspace' operations
//
switch ( operation ) {
case 'Backspace':
// If there exists the previous character,
// then erase it and reposition the caret.
if ( caret > 0 ) {
// Remove the previous character
value = value.slice( 0, caret - 1 ) + value.slice( caret );
// Position the caret where the previous (erased) character was
caret--;
}
break;
case 'Delete':
// Remove current digit (if any)
value = value.slice( 0, caret ) + value.slice( caret + 1 );
break;
}
return { value, caret };
};
/**
* @function parseDigitWithPlus
* @description Parses a digit with a plus sign.
*
* @since 5.5.0
*
* @param {boolean} international Whether the phone number is in international format.
*
* @return {Function} The function to parse a digit with a plus sign.
*/
export const parseDigitWithPlus = ( international ) => ( character, value ) => {
// Leading plus is allowed
if ( international && character === '+' && ! value ) {
return character;
}
// Digits are allowed
return parseDigit( character );
};
/**
* @function getFormattedInputText
* @description Gets the formatted input text.
* Modified from the original function `formatInputText` from `input-format` package.
*
* @since 5.5.0
*
* @param {string} inputValue The input value.
* @param {number} caretPosition The caret position.
* @param {string} country The country code.
* @param {boolean} international Whether the phone number is in international format.
* @param {string|undefined} operation The operation to perform, one of `Backspace` or `Delete`.
*
* @return {object} The formatted input text, caret position, and the AsYouType instance.
*/
export const getFormattedInputText = (
inputValue,
caretPosition,
country,
international,
operation,
) => {
const asYouType = new AsYouType( country );
asYouType.input( inputValue );
const parser = templateParser( asYouType.getTemplate(), parseDigitWithPlus( international ) );
// Parse input value.
// Get the `value` and `caret` position.
let { value, caret } = parse( inputValue, caretPosition, parser );
// If a user performed an operation ("Backspace", "Delete")
// then apply that operation and get the new `value` and `caret` position.
if ( operation ) {
const newValueAndCaret = edit( value, caret, operation );
value = newValueAndCaret.value;
caret = newValueAndCaret.caret;
}
asYouType.reset();
asYouType.input( value );
const formatter = templateFormatter( asYouType.getTemplate(), 'x', true );
// Format the `value` and reposition the caret accordingly.
return {
asYouType,
formatted: format( value, caret, formatter ),
};
};