From 220a5e3f8e6c7454c68b4e379c0cda9522dd528a Mon Sep 17 00:00:00 2001 From: Anton Chashchin Date: Fri, 29 Nov 2024 11:49:37 +0400 Subject: [PATCH] fix: use button tag and native tabindex for clear button (#63) Co-authored-by: afc163 --- assets/index.less | 4 +- src/BaseInput.tsx | 6 +-- tests/BaseInput.test.tsx | 63 +++++++++++++++++++------ tests/__snapshots__/index.test.tsx.snap | 36 +++++--------- 4 files changed, 65 insertions(+), 44 deletions(-) diff --git a/assets/index.less b/assets/index.less index adab276..3c96198 100644 --- a/assets/index.less +++ b/assets/index.less @@ -22,8 +22,10 @@ } &-clear-icon { + padding: 0; font-size: 12px; - cursor: pointer; + background: none; + border: none; &-hidden { display: none; diff --git a/src/BaseInput.tsx b/src/BaseInput.tsx index 5d18647..125ab91 100644 --- a/src/BaseInput.tsx +++ b/src/BaseInput.tsx @@ -80,7 +80,7 @@ const BaseInput = React.forwardRef((props, ref) => { : '✖'; clearIcon = ( - { handleReset?.(event); onClear?.(); @@ -92,11 +92,9 @@ const BaseInput = React.forwardRef((props, ref) => { [`${clearIconCls}-hidden`]: !needClear, [`${clearIconCls}-has-suffix`]: !!suffix, })} - role="button" - tabIndex={-1} > {iconNode} - + ); } diff --git a/tests/BaseInput.test.tsx b/tests/BaseInput.test.tsx index 37cb282..a0c51e2 100644 --- a/tests/BaseInput.test.tsx +++ b/tests/BaseInput.test.tsx @@ -1,4 +1,5 @@ import { fireEvent, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import type { ChangeEvent, FC } from 'react'; import React, { useState } from 'react'; import BaseInput, { type HolderRef } from '../src/BaseInput'; @@ -45,11 +46,13 @@ describe('BaseInput', () => { expect(container).toMatchSnapshot(); }); - it('allowClear should work', () => { + describe('allowClear should work', () => { const onChange = jest.fn(); const onBlur = jest.fn(); const onFocus = jest.fn(); + const user = userEvent.setup(); + const Demo: FC = () => { const [value, setValue] = useState(''); @@ -74,23 +77,53 @@ describe('BaseInput', () => { ); }; - const { container } = render(); + it('By click', () => { + const { container } = render(); - const inputEl = container.querySelector('input'); - fireEvent.focus(inputEl!); - expect(onFocus).toHaveBeenCalledTimes(1); + const inputEl = container.querySelector('input'); + fireEvent.focus(inputEl!); + expect(onFocus).toHaveBeenCalledTimes(1); - fireEvent.change(inputEl!, { target: { value: 'some text' } }); - expect(onChange).toHaveBeenCalledTimes(1); - expect(inputEl!.value).toBe('some text'); + fireEvent.change(inputEl!, { target: { value: 'some text' } }); + expect(onChange).toHaveBeenCalledTimes(1); + expect(inputEl!.value).toBe('some text'); - const clearIcon = container.querySelector('.rc-input-clear-icon'); - fireEvent.mouseDown(clearIcon!); - fireEvent.click(clearIcon!); - fireEvent.mouseUp(clearIcon!); - expect(onBlur).not.toHaveBeenCalled(); - expect(onChange).toHaveBeenCalledTimes(1); - expect(inputEl!.value).toBe(''); + const clearIcon = container.querySelector('.rc-input-clear-icon'); + fireEvent.mouseDown(clearIcon!); + fireEvent.click(clearIcon!); + fireEvent.mouseUp(clearIcon!); + expect(onBlur).not.toHaveBeenCalled(); + expect(onChange).toHaveBeenCalledTimes(1); + expect(inputEl!.value).toBe(''); + }); + + it('By focus and Space', async () => { + const { container } = render(); + + const inputEl = container.querySelector('input'); + await user.click(inputEl!); + + await user.type(inputEl!, 'some text'); + expect(inputEl!.value).toBe('some text'); + + await user.tab(); + await user.keyboard('[Space]'); + expect(inputEl!.value).toBe(''); + }); + + it('By focus and Enter', async () => { + const { container } = render(); + + const inputEl = container.querySelector('input'); + await user.click(inputEl!); + + await user.type(inputEl!, 'some text'); + expect(inputEl!.value).toBe('some text'); + + await user.tab(); + await user.keyboard('[Enter]'); + expect(inputEl!.value).toBe(''); + }); }); it('should display clearIcon correctly', () => { diff --git a/tests/__snapshots__/index.test.tsx.snap b/tests/__snapshots__/index.test.tsx.snap index cb35b43..ec21db5 100644 --- a/tests/__snapshots__/index.test.tsx.snap +++ b/tests/__snapshots__/index.test.tsx.snap @@ -115,13 +115,11 @@ exports[`Input allowClear should change type when click 1`] = ` - ✖ - + @@ -140,13 +138,11 @@ exports[`Input allowClear should change type when click 2`] = ` - ✖ - + @@ -165,13 +161,11 @@ exports[`Input allowClear should not show icon if defaultValue is undefined or e - ✖ - + @@ -190,13 +184,11 @@ exports[`Input allowClear should not show icon if defaultValue is undefined or e - ✖ - + @@ -215,13 +207,11 @@ exports[`Input allowClear should not show icon if value is undefined or empty st - ✖ - + @@ -240,13 +230,11 @@ exports[`Input allowClear should not show icon if value is undefined or empty st - ✖ - +