Skip to content

Commit

Permalink
fix(NumberKeyboard): fix IOS missing the touch event when finger trig…
Browse files Browse the repository at this point in the history
…ger the scale case (#6651)

* test: adjust test case

* test: test driven

* test: update test case
  • Loading branch information
zombieJ authored Jun 25, 2024
1 parent 2203ba2 commit c106365
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
28 changes: 15 additions & 13 deletions src/components/number-keyboard/number-keyboard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useRef, useMemo } from 'react'
import type { FC, TouchEvent, MouseEvent } from 'react'
import classNames from 'classnames'
import { useMemoizedFn } from 'ahooks'
import { DownOutline, TextDeletionOutline } from 'antd-mobile-icons'
import { mergeProps } from '../../utils/with-default-props'
import classNames from 'classnames'
import type { FC, MouseEvent, TouchEvent } from 'react'
import React, { useMemo, useRef } from 'react'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import { shuffle } from '../../utils/shuffle'
import { mergeProps } from '../../utils/with-default-props'
import { useConfig } from '../config-provider'
import Popup, { PopupProps } from '../popup'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import SafeArea from '../safe-area'
import { useMemoizedFn } from 'ahooks'
import { useConfig } from '../config-provider'

const classPrefix = 'adm-number-keyboard'

Expand Down Expand Up @@ -88,13 +88,13 @@ export const NumberKeyboard: FC<NumberKeyboardProps> = p => {
props.onDelete?.()
})

const onBackspacePressStart = () => {
const startContinueClear = () => {
timeoutRef.current = window.setTimeout(() => {
onDelete()
intervalRef.current = window.setInterval(onDelete, 150)
}, 700)
}
const onBackspacePressEnd = () => {
const stopContinueClear = () => {
clearTimeout(timeoutRef.current)
clearInterval(intervalRef.current)
}
Expand Down Expand Up @@ -174,14 +174,16 @@ export const NumberKeyboard: FC<NumberKeyboardProps> = p => {
key={key}
className={className}
onTouchStart={() => {
stopContinueClear()

if (key === 'BACKSPACE') {
onBackspacePressStart()
startContinueClear()
}
}}
onTouchEnd={e => {
onKeyPress(e, key)
if (key === 'BACKSPACE') {
onBackspacePressEnd()
stopContinueClear()
}
}}
{...ariaProps}
Expand Down Expand Up @@ -226,11 +228,11 @@ export const NumberKeyboard: FC<NumberKeyboardProps> = p => {
<div
className={`${classPrefix}-key ${classPrefix}-key-extra ${classPrefix}-key-bs`}
onTouchStart={() => {
onBackspacePressStart()
startContinueClear()
}}
onTouchEnd={e => {
onKeyPress(e, 'BACKSPACE')
onBackspacePressEnd()
stopContinueClear()
}}
onContextMenu={e => {
// Long press should not trigger native context menu
Expand Down
42 changes: 41 additions & 1 deletion src/components/number-keyboard/tests/number-keyboard.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { fireEvent, render, testA11y, screen, waitFor } from 'testing'
import { fireEvent, render, screen, testA11y, waitFor } from 'testing'
import NumberKeyboard from '..'

const classPrefix = 'adm-number-keyboard'
Expand All @@ -10,7 +10,17 @@ function mockClick(el: HTMLElement) {
}

describe('NumberKeyboard', () => {
beforeEach(() => {
jest.useFakeTimers()
})

afterEach(() => {
jest.clearAllTimers()
jest.useRealTimers()
})

test('a11y', async () => {
jest.useRealTimers()
await testA11y(<NumberKeyboard visible />)
})

Expand Down Expand Up @@ -160,4 +170,34 @@ describe('NumberKeyboard', () => {
expect(right).toBeInTheDocument()
expect(screen.getByTitle('0')).not.toHaveClass(`${classPrefix}-key-mid`)
})

test('long press backspace and release', () => {
const onDelete = jest.fn()
const { container } = render(<NumberKeyboard visible onDelete={onDelete} />)

// Fire touchstart event
fireEvent.touchStart(
document.body.querySelector(
'.adm-number-keyboard-key-sign'
) as HTMLDivElement,
{ touches: [{}] }
)
onDelete.mockReset()

jest.advanceTimersByTime(10000)
expect(onDelete).toHaveBeenCalled()
onDelete.mockReset()

// We do not fire touchend event to mock ISO missing touchend event
// Press other key
fireEvent.touchStart(
document.body.querySelector(
'.adm-number-keyboard-key-number'
) as HTMLDivElement,
{ touches: [{}] }
)

jest.advanceTimersByTime(10000)
expect(onDelete).not.toHaveBeenCalled()
})
})

0 comments on commit c106365

Please sign in to comment.