diff --git a/projects/core/src/lib/types/maskito-element.ts b/projects/core/src/lib/types/maskito-element.ts index df37daeb0..225e8c245 100644 --- a/projects/core/src/lib/types/maskito-element.ts +++ b/projects/core/src/lib/types/maskito-element.ts @@ -1,5 +1,10 @@ export type TextfieldLike = Pick< HTMLInputElement, - 'maxLength' | 'selectionEnd' | 'selectionStart' | 'setSelectionRange' | 'value' + | 'maxLength' + | 'select' + | 'selectionEnd' + | 'selectionStart' + | 'setSelectionRange' + | 'value' >; export type MaskitoElement = HTMLElement & TextfieldLike; diff --git a/projects/core/src/lib/utils/content-editable.ts b/projects/core/src/lib/utils/content-editable.ts index f42e99880..ba709c037 100644 --- a/projects/core/src/lib/utils/content-editable.ts +++ b/projects/core/src/lib/utils/content-editable.ts @@ -27,6 +27,10 @@ class ContentEditableAdapter implements TextfieldLike { public setSelectionRange(from: number | null, to: number | null): void { setContentEditableSelection(this.element, [from || 0, to || 0]); } + + public select(): void { + this.setSelectionRange(0, this.value.length); + } } export function maskitoAdaptContentEditable(element: HTMLElement): MaskitoElement { diff --git a/projects/demo-integrations/src/tests/component-testing/native-select-method/native-select-method.cy.ts b/projects/demo-integrations/src/tests/component-testing/native-select-method/native-select-method.cy.ts new file mode 100644 index 000000000..178f2086d --- /dev/null +++ b/projects/demo-integrations/src/tests/component-testing/native-select-method/native-select-method.cy.ts @@ -0,0 +1,58 @@ +import {Component} from '@angular/core'; +import {MaskitoDirective} from '@maskito/angular'; +import type {MaskitoOptions} from '@maskito/core'; +import {maskitoEventHandler} from '@maskito/kit'; + +@Component({ + standalone: true, + imports: [MaskitoDirective], + template: ` + + +
+ `, +}) +export class TestComponent { + protected readonly maskitoOptions: MaskitoOptions = { + mask: /^\d+$/, + plugins: [ + maskitoEventHandler('focus', element => element.select(), {once: true}), + ], + }; +} + +describe('Native method `.select()` works', () => { + ['input', 'textarea'].forEach(selector => { + it(`for <${selector} />`, () => { + cy.mount(TestComponent); + cy.get(selector) + .should('have.value', '123') + .should('have.prop', 'selectionStart', 0) + .should('have.prop', 'selectionEnd', 0) + .should('not.be.focused') + .focus() + .should('have.prop', 'selectionStart', 0) + .should('have.prop', 'selectionEnd', 3); + }); + }); + + it('for [contenteditable]', () => { + cy.mount(TestComponent); + cy.get('[contenteditable]') + .should('have.text', '123') + .should('not.be.focused') + .focus() + .type('0') // all selected value will be overwritten + .should('have.text', '0') + .focus() + .type('2') // no selection (plugin works only for the first focus), just append value + .should('have.text', '02'); + }); +});