Skip to content

Commit

Permalink
fix(kit): move caret after attempt to erase fixed character in a mask…
Browse files Browse the repository at this point in the history
… with `Placeholder`
  • Loading branch information
nsbarsukov committed Jun 17, 2024
1 parent c08975d commit 9a138c9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,57 @@ describe('Placeholder | US phone', () => {
.blur()
.should('have.value', '');
});

describe('caret navigation on attempt to erase fixed character', () => {
beforeEach(() => {
cy.get('@input')
.type('2125552')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212) 555-2'.length)
.should('have.prop', 'selectionEnd', '+1 (212) 555-2'.length);
});

it('+1 (212) 555-|2___ => Backspace => +1 (212) 555|-2___', () => {
cy.get('@input')
.type('{leftArrow}{backspace}')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212) 555'.length)
.should('have.prop', 'selectionEnd', '+1 (212) 555'.length);
});

it('+1 (212) 555|-2___ => Delete => +1 (212) 555-|2___', () => {
cy.get('@input')
.type('{leftArrow}'.repeat(2))
.should('have.prop', 'selectionStart', '+1 (212) 555'.length)
.should('have.prop', 'selectionEnd', '+1 (212) 555'.length)
.type('{del}')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212) 555-'.length)
.should('have.prop', 'selectionEnd', '+1 (212) 555-'.length);
});

it('+1 (212) |555-2___ => Backspace x2 => +1 (212|) 555-2___', () => {
cy.get('@input')
.type('{leftArrow}'.repeat('555-2'.length))
.type('{backspace}')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212)'.length)
.should('have.prop', 'selectionEnd', '+1 (212)'.length)
.type('{backspace}')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212'.length)
.should('have.prop', 'selectionEnd', '+1 (212'.length);
});

it('+1 (212|) 555-2___ => Delete => +1 (212) |555-2___', () => {
cy.get('@input')
.type('{leftArrow}'.repeat(') 555-2'.length))
.should('have.prop', 'selectionStart', '+1 (212'.length)
.should('have.prop', 'selectionEnd', '+1 (212'.length)
.type('{del}')
.should('have.value', '+1 (212) 555-2___')
.should('have.prop', 'selectionStart', '+1 (212) '.length)
.should('have.prop', 'selectionEnd', '+1 (212) '.length);
});
});
});
30 changes: 22 additions & 8 deletions projects/kit/src/lib/processors/with-placeholder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {MaskitoOptions} from '@maskito/core';
import type {MaskitoOptions, MaskitoPreprocessor} from '@maskito/core';
import {maskitoUpdateElement} from '@maskito/core';

import {maskitoCaretGuard, maskitoEventHandler} from '../plugins';
Expand All @@ -10,6 +10,7 @@ export function maskitoWithPlaceholder(
removePlaceholder: (value: string) => string;
} {
let lastClearValue = '';
let action: Parameters<MaskitoPreprocessor>[1] = 'validation';
const removePlaceholder = (value: string): string => {
for (let i = value.length - 1; i >= lastClearValue.length; i--) {
if (value[i] !== placeholder[i]) {
Expand Down Expand Up @@ -52,7 +53,8 @@ export function maskitoWithPlaceholder(
plugins,
removePlaceholder,
preprocessors: [
({elementState, data}) => {
({elementState, data}, actionType) => {
action = actionType;
const {value, selection} = elementState;

return {
Expand All @@ -76,12 +78,24 @@ export function maskitoWithPlaceholder(
* For example, developer wants to remove manually placeholder (+ do something else with value) on blur.
* Without this condition, placeholder will be unexpectedly added again.
*/
return value !== initialElementState.value && (focused || !focusedOnly)
? {
value: value + placeholder.slice(value.length),
selection,
}
: {value, selection};
const newValue =
value !== initialElementState.value && (focused || !focusedOnly)
? value + placeholder.slice(value.length)
: value;

if (
newValue === initialElementState.value &&
action === 'deleteBackward'
) {
const [caretIndex] = initialElementState.selection;

return {
value: newValue,
selection: [caretIndex, caretIndex],
};
}

return {value: newValue, selection};
},
],
};
Expand Down

0 comments on commit 9a138c9

Please sign in to comment.