import { isFocusable , isTextField , getActiveElement } from "reakit-utils" ; import { warning } from "reakit-warning" ; import { DirtiableElement , TextField } from "./__utils/types" ; import { fireEvent } from "./fireEvent" ; import { focus } from "./focus" ; import { getSelectionRange , setSelectionRange } from "./__utils/selectionRange" ; import "./mockClientRects" ; export function type ( text , element ? , options = { } ) { if ( element == null ) { element = document . activeElement as HTMLInputElement ; } if ( ! element || ! isFocusable ( element ) ) return ; focus ( element ) ; element . dirty = true ; for ( const char of text ) { const key = char === "\b" ? "Backspace" : char ; let value = "" ; let inputType = "insertText" ; let defaultAllowed = fireEvent . keyDown ( element , { key , ... options } ) ; element = ( getActiveElement ( element ) || element ) as HTMLElement ; if ( ! isTextField ( element ) ) { warning ( true , "[reakit-test-utils/type]" , "You're trying to type on an element that is not able of being typed on a keyboard." ) ; return ; } const input = element as TextField ; const [ start , end ] = getSelectionRange ( input ) ; if ( char === "\b" ) { const startAfterBackspace = start === end ? Math . max ( start - 1 , 0 ) : start ; const firstPart = input . value . slice ( 0 , startAfterBackspace ) ; const lastPart = input . value . slice ( end , input . value . length ) ; setSelectionRange ( input , startAfterBackspace ) ; value = `${ firstPart }${ lastPart }` ; inputType = "deleteContentBackward" ; } else { const firstPart = input . value . slice ( 0 , start ) ; const lastPart = input . value . slice ( end , input . value . length ) ; setSelectionRange ( input , start + 1 ) ; value = `${ firstPart }${ char }${ lastPart }` ; } if ( defaultAllowed && ! input . readOnly ) { if ( inputType === "insertText" ) { defaultAllowed = fireEvent . keyPress ( input , { key , charCode : key . charCodeAt ( 0 ) , ... options , } ) ; } if ( defaultAllowed ) { fireEvent . input ( input , { data : char , target : { value } , inputType , ... options , } ) ; } } fireEvent . keyUp ( input , { key , ... options } ) ; } }