Skip to content

Commit

Permalink
feat(type): Implement cursor navigation with ArrowLeft and ArrowRight
Browse files Browse the repository at this point in the history
  • Loading branch information
juanca authored and Jesu Castillo committed Oct 27, 2020
1 parent f944ed0 commit e254f1c
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/__tests__/type.js
Expand Up @@ -1022,3 +1022,77 @@ test('should not type inside a contenteditable=false div', () => {
div - click: Left (0)
`)
})

test('navigation key: {arrowleft} and {arrowright} moves the cursor', () => {
const {element, getEventSnapshot} = setup('<input />')
userEvent.type(element, 'Brea{arrowleft}k{arrowright}fast')
expect(getEventSnapshot()).toMatchInlineSnapshot(`
Events fired on: input[value="Brekafast"]
input[value=""] - pointerover
input[value=""] - pointerenter
input[value=""] - mouseover: Left (0)
input[value=""] - mouseenter: Left (0)
input[value=""] - pointermove
input[value=""] - mousemove: Left (0)
input[value=""] - pointerdown
input[value=""] - mousedown: Left (0)
input[value=""] - focus
input[value=""] - focusin
input[value=""] - pointerup
input[value=""] - mouseup: Left (0)
input[value=""] - click: Left (0)
input[value=""] - keydown: B (66)
input[value=""] - keypress: B (66)
input[value="B"] - input
"{CURSOR}" -> "B{CURSOR}"
input[value="B"] - keyup: B (66)
input[value="B"] - keydown: r (114)
input[value="B"] - keypress: r (114)
input[value="Br"] - input
"B{CURSOR}" -> "Br{CURSOR}"
input[value="Br"] - keyup: r (114)
input[value="Br"] - keydown: e (101)
input[value="Br"] - keypress: e (101)
input[value="Bre"] - input
"Br{CURSOR}" -> "Bre{CURSOR}"
input[value="Bre"] - keyup: e (101)
input[value="Bre"] - keydown: a (97)
input[value="Bre"] - keypress: a (97)
input[value="Brea"] - input
"Bre{CURSOR}" -> "Brea{CURSOR}"
input[value="Brea"] - keyup: a (97)
input[value="Brea"] - keydown: ArrowLeft (37)
input[value="Brea"] - select
input[value="Brea"] - keyup: ArrowLeft (37)
input[value="Brea"] - keydown: k (107)
input[value="Brea"] - keypress: k (107)
input[value="Breka"] - input
"Bre{CURSOR}a" -> "Breka{CURSOR}"
input[value="Breka"] - select
input[value="Breka"] - keyup: k (107)
input[value="Breka"] - keydown: ArrowRight (39)
input[value="Breka"] - select
input[value="Breka"] - keyup: ArrowRight (39)
input[value="Breka"] - keydown: f (102)
input[value="Breka"] - keypress: f (102)
input[value="Brekaf"] - input
"Breka{CURSOR}" -> "Brekaf{CURSOR}"
input[value="Brekaf"] - keyup: f (102)
input[value="Brekaf"] - keydown: a (97)
input[value="Brekaf"] - keypress: a (97)
input[value="Brekafa"] - input
"Brekaf{CURSOR}" -> "Brekafa{CURSOR}"
input[value="Brekafa"] - keyup: a (97)
input[value="Brekafa"] - keydown: s (115)
input[value="Brekafa"] - keypress: s (115)
input[value="Brekafas"] - input
"Brekafa{CURSOR}" -> "Brekafas{CURSOR}"
input[value="Brekafas"] - keyup: s (115)
input[value="Brekafas"] - keydown: t (116)
input[value="Brekafas"] - keypress: t (116)
input[value="Brekafast"] - input
"Brekafas{CURSOR}" -> "Brekafast{CURSOR}"
input[value="Brekafast"] - keyup: t (116)
`)
})
58 changes: 58 additions & 0 deletions src/keys/navigation-key.js
@@ -0,0 +1,58 @@
import {fireEvent} from '@testing-library/dom'

import {setSelectionRangeIfNecessary} from '../utils'

const keys = {
ArrowLeft: {
keyCode: 37,
},
ArrowRight: {
keyCode: 39,
},
}

function getSelectionRange(currentElement, key) {
switch (key) {
case 'ArrowLeft':
return {
selectionStart: currentElement().selectionStart - 1,
selectionEnd: currentElement().selectionEnd - 1,
}
case 'ArrowRight':
return {
selectionStart: currentElement().selectionStart + 1,
selectionEnd: currentElement().selectionEnd + 1,
}
default:
return {}
}
}

function navigationKey(key) {
const event = {
key,
keyCode: keys[key].keyCode,
which: keys[key].keyCode,
}

return ({currentElement, eventOverrides}) => {
fireEvent.keyDown(currentElement(), {
...event,
...eventOverrides,
})

const range = getSelectionRange(currentElement, key)
setSelectionRangeIfNecessary(
currentElement(),
range.selectionStart,
range.selectionEnd,
)

fireEvent.keyUp(currentElement(), {
...event,
...eventOverrides,
})
}
}

export {navigationKey}
3 changes: 3 additions & 0 deletions src/type.js
Expand Up @@ -15,6 +15,7 @@ import {
isContentEditable,
} from './utils'
import {click} from './click'
import {navigationKey} from './keys/navigation-key'

const modifierCallbackMap = {
...createModifierCallbackEntries({
Expand Down Expand Up @@ -44,6 +45,8 @@ const modifierCallbackMap = {
}

const specialCharCallbackMap = {
'{arrowleft}': navigationKey('ArrowLeft'),
'{arrowright}': navigationKey( 'ArrowRight'),
'{enter}': handleEnter,
'{esc}': handleEsc,
'{del}': handleDel,
Expand Down

0 comments on commit e254f1c

Please sign in to comment.