Skip to content

Commit

Permalink
fix: use button tag and native tabindex for clear button (#63)
Browse files Browse the repository at this point in the history
Co-authored-by: afc163 <[email protected]>
  • Loading branch information
vtx-anton-chashchin and afc163 authored Nov 29, 2024
1 parent c0dd6ed commit 220a5e3
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 44 deletions.
4 changes: 3 additions & 1 deletion assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
}

&-clear-icon {
padding: 0;
font-size: 12px;
cursor: pointer;
background: none;
border: none;

&-hidden {
display: none;
Expand Down
6 changes: 2 additions & 4 deletions src/BaseInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const BaseInput = React.forwardRef<HolderRef, BaseInputProps>((props, ref) => {
: '✖';

clearIcon = (
<span
<button
onClick={(event) => {
handleReset?.(event);
onClear?.();
Expand All @@ -92,11 +92,9 @@ const BaseInput = React.forwardRef<HolderRef, BaseInputProps>((props, ref) => {
[`${clearIconCls}-hidden`]: !needClear,
[`${clearIconCls}-has-suffix`]: !!suffix,
})}
role="button"
tabIndex={-1}
>
{iconNode}
</span>
</button>
);
}

Expand Down
63 changes: 48 additions & 15 deletions tests/BaseInput.test.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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<string>('');

Expand All @@ -74,23 +77,53 @@ describe('BaseInput', () => {
);
};

const { container } = render(<Demo />);
it('By click', () => {
const { container } = render(<Demo />);

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(<Demo />);

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(<Demo />);

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', () => {
Expand Down
36 changes: 12 additions & 24 deletions tests/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,11 @@ exports[`Input allowClear should change type when click 1`] = `
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand All @@ -140,13 +138,11 @@ exports[`Input allowClear should change type when click 2`] = `
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon rc-input-clear-icon-hidden"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand All @@ -165,13 +161,11 @@ exports[`Input allowClear should not show icon if defaultValue is undefined or e
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon rc-input-clear-icon-hidden"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand All @@ -190,13 +184,11 @@ exports[`Input allowClear should not show icon if defaultValue is undefined or e
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon rc-input-clear-icon-hidden"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand All @@ -215,13 +207,11 @@ exports[`Input allowClear should not show icon if value is undefined or empty st
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon rc-input-clear-icon-hidden"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand All @@ -240,13 +230,11 @@ exports[`Input allowClear should not show icon if value is undefined or empty st
<span
class="rc-input-suffix"
>
<span
<button
class="rc-input-clear-icon rc-input-clear-icon-hidden"
role="button"
tabindex="-1"
>
</span>
</button>
</span>
</span>
</div>
Expand Down

0 comments on commit 220a5e3

Please sign in to comment.