Skip to content

Commit

Permalink
fix(text-field): Show clear button in TextField only when it is fille…
Browse files Browse the repository at this point in the history
…d and hovered/focused (channel-io#1713)

<!--
  How to write a good PR title:
- Follow [the Conventional Commits
specification](https://www.conventionalcommits.org/en/v1.0.0/).
  - Give as much context as necessary and as little as possible
  - Prefix it with [WIP] while it’s a work in progress
-->

## Self Checklist

- [x] I wrote a PR title in **English** and added an appropriate
**label** to the PR.
- [x] I wrote the commit message in **English** and to follow [**the
Conventional Commits
specification**](https://www.conventionalcommits.org/en/v1.0.0/).
- [x] I [added the
**changeset**](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md)
about the changes that needed to be released. (or didn't have to)
- [x] I wrote or updated **documentation** related to the changes. (or
didn't have to)
- [x] I wrote or updated **tests** related to the changes. (or didn't
have to)
- [x] I tested the changes in various browsers. (or didn't have to)
  - Windows: Chrome, Edge, (Optional) Firefox
  - macOS: Chrome, Edge, Safari, (Optional) Firefox

## Related Issue
<!-- Please link to issue if one exists -->

Fixes channel-io#502 

## Summary
<!-- Please brief explanation of the changes made -->

input에 값이 채워져있고, focus되거나 hover되었을 때만 내용 삭제 버튼이 나오도록 변경합니다.

## Details
<!-- Please elaborate description of the changes -->

```tsx
// TextField.tsx

// before
const activeClear = activeInput && allowClear

// after
const activeClear = activeInput && allowClear && !!normalizedValue

return (
  ...
    { activeClear && ClearComponent }
  ...
)
```

기존에 `ClearComponent` 의 렌더링 조건에는 `value`에 대한 것이 없었습니다. 그래서
`!!normalizedValue`를 통해 input 태그에 값이 있어야지만 내용 삭제 버튼이 렌더링되도록 하였습니다.

### Breaking change? (Yes/No)
<!-- If Yes, please describe the impact and migration path for users -->

No
  • Loading branch information
jintak0401 authored Nov 10, 2023
1 parent 8c7ce90 commit 79e1a51
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-bikes-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@channel.io/bezier-react": patch
---

Show clear button in TextField only when its value is not empty and focused/hovered.
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import React from 'react'

import { fireEvent } from '@testing-library/dom'
import { act } from '@testing-library/react'
import {
act,
within,
} from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { LightFoundation } from '~/src/foundation'

import { render } from '~/src/utils/testUtils'

import { COMMON_IME_CONTROL_KEYS } from '~/src/components/Forms/Inputs/constants/CommonImeControlKeys'

import TextField, { TEXT_INPUT_TEST_ID } from './TextField'
import TextField, {
TEXT_INPUT_CLEAR_ICON_TEST_ID,
TEXT_INPUT_TEST_ID,
} from './TextField'
import {
type TextFieldProps,
TextFieldVariant,
} from './TextField.types'
import { getProperTextFieldBgColor } from './TextFieldUtils'

describe('TextField', () => {
const user = userEvent.setup()
let props: TextFieldProps

beforeEach(() => {
Expand Down Expand Up @@ -285,4 +293,54 @@ describe('TextField', () => {
})
})
})

describe('show remove button only when it is filled and focused/hovered', () => {
it('disappear when empty & focused/hovered', async () => {
const { getByTestId } = renderComponent({ value: '', allowClear: true })
const rendered = getByTestId(TEXT_INPUT_TEST_ID)
const input = rendered.getElementsByTagName('input')[0]

await act(async () => {
await user.hover(input)
input.focus()
})

const clearButton = within(rendered).queryByTestId(TEXT_INPUT_CLEAR_ICON_TEST_ID)
expect(clearButton).toBeNull()
})

it('disappear when filled & not focused/hovered', () => {
const { getByTestId } = renderComponent({ value: 'test', allowClear: true })
const rendered = getByTestId(TEXT_INPUT_TEST_ID)

const clearButton = within(rendered).queryByTestId(TEXT_INPUT_CLEAR_ICON_TEST_ID)
expect(clearButton).toBeNull()
})

it('appear when filled & hovered', async () => {
const { getByTestId } = renderComponent({ value: 'test', allowClear: true })
const rendered = getByTestId(TEXT_INPUT_TEST_ID)
const input = rendered.getElementsByTagName('input')[0]

await act(async () => {
await user.hover(input)
})

const clearButton = within(rendered).getByTestId(TEXT_INPUT_CLEAR_ICON_TEST_ID)
expect(clearButton).toBeInTheDocument()
})

it('appear when filled & focused', () => {
const { getByTestId } = renderComponent({ value: 'test', allowClear: true })
const rendered = getByTestId(TEXT_INPUT_TEST_ID)
const input = rendered.getElementsByTagName('input')[0]

act(() => {
input.focus()
})

const clearButton = within(rendered).getByTestId(TEXT_INPUT_CLEAR_ICON_TEST_ID)
expect(clearButton).toBeInTheDocument()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
import Styled from './TextField.styled'

export const TEXT_INPUT_TEST_ID = 'bezier-react-text-input'
export const TEXT_INPUT_CLEAR_ICON_TEST_ID = 'bezier-react-text-input-clear-icon'

function TextFieldComponent({
name,
Expand Down Expand Up @@ -117,7 +118,7 @@ forwardedRef: Ref<TextFieldRef>,
), [value])

const activeInput = !disabled && !readOnly
const activeClear = activeInput && allowClear
const activeClear = activeInput && allowClear && !isEmpty(normalizedValue)

const inputRef = useRef<HTMLInputElement | null>(null)

Expand Down Expand Up @@ -363,8 +364,9 @@ forwardedRef: Ref<TextFieldRef>,
onClick={handleClear}
>
{
normalizedValue && normalizedValue.length > 0 && (focused || hovered) && (
(focused || hovered) && (
<Icon
testId={TEXT_INPUT_CLEAR_ICON_TEST_ID}
source={CancelCircleFilledIcon}
size={IconSize.XS}
/>
Expand All @@ -375,7 +377,6 @@ forwardedRef: Ref<TextFieldRef>,
focused,
handleClear,
hovered,
normalizedValue,
])

return (
Expand Down

0 comments on commit 79e1a51

Please sign in to comment.