Skip to content

Commit

Permalink
feat!: Expose ComboBox component ref with a clearSelection method (#1236
Browse files Browse the repository at this point in the history
)

* Changes ComboBox to use forwardRef, adds clearSelection method to ref

* Changes dispatched action to new type, which doesn't effect focus

* Clear focused option when clearing ComboBox selected value
  • Loading branch information
Kyle Hill authored Jun 3, 2021
1 parent f632744 commit e90e4df
Show file tree
Hide file tree
Showing 4 changed files with 435 additions and 327 deletions.
32 changes: 30 additions & 2 deletions src/components/forms/ComboBox/ComboBox.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react'
import React, { useRef } from 'react'

import { ComboBox } from './ComboBox'
import { ComboBox, ComboBoxRef } from './ComboBox'
import { Form } from '../Form/Form'
import { Label } from '../Label/Label'
import { TextInput } from '../TextInput/TextInput'
import { Button } from '../../Button/Button'
import { fruits } from './fruits'

export default {
Expand Down Expand Up @@ -118,3 +119,30 @@ export const withOtherFields = (): React.ReactElement => {
</Form>
)
}

export const externalClearSelection = (): React.ReactElement => {
const ref = useRef<ComboBoxRef>()

const fruitList = Object.entries(fruits).map(([value, key]) => ({
value: value,
label: key,
}))

const handleClearSelection = (): void => ref.current.clearSelection()

return (
<Form onSubmit={noop}>
<Label htmlFor="fruit">Select a Fruit</Label>
<ComboBox
id="fruit"
name="fruit"
options={fruitList}
onChange={noop}
ref={ref}
/>
<Button type="reset" onClick={handleClearSelection}>
Clear Selected Value
</Button>
</Form>
)
}
40 changes: 39 additions & 1 deletion src/components/forms/ComboBox/ComboBox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { ComboBox } from './ComboBox'
import { ComboBox, ComboBoxRef } from './ComboBox'
import { TextInput } from '../TextInput/TextInput'
import { fruits } from './fruits'

Expand Down Expand Up @@ -1427,4 +1427,42 @@ describe('ComboBox component', () => {
expect(firstItem).toHaveTextContent('NOTHING')
})
})

describe('exposed ref', () => {
it('can be used to clear the selected value', () => {
const comboRef = React.createRef<ComboBoxRef>()
const onChange = jest.fn()
const handleClearSelection = (): void =>
comboRef.current?.clearSelection()

const { getByTestId } = render(
<>
<ComboBox
id="favorite-fruit"
name="favorite-fruit"
options={fruitOptions}
onChange={onChange}
ref={comboRef}
/>
<button data-testid="clear-button" onClick={handleClearSelection}>
Clear
</button>
</>
)

const input = getByTestId('combo-box-input')
fireEvent.click(getByTestId('combo-box-toggle'))
fireEvent.click(getByTestId('combo-box-option-apple'))

expect(onChange).toHaveBeenLastCalledWith('apple')
expect(input).toHaveDisplayValue('Apple')
expect(input).toHaveValue('Apple')

fireEvent.click(getByTestId('clear-button'))

expect(onChange).toHaveBeenLastCalledWith(undefined)
expect(input).toHaveDisplayValue('')
expect(input).toHaveValue('')
})
})
})
Loading

0 comments on commit e90e4df

Please sign in to comment.