Skip to content

Commit

Permalink
feat(useCombobox): remove selectedItemChanged (#1583)
Browse files Browse the repository at this point in the history
* feat(useCombobox): remove selectedItemChanged

* doctoc
  • Loading branch information
silviuaavram authored Mar 13, 2024
1 parent 9bb08ba commit fd1ede6
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 148 deletions.
12 changes: 12 additions & 0 deletions src/hooks/MIGRATION_V9.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ hooks and are detailed below.
- [getA11ySelectionMessage](#geta11yselectionmessage)
- [getA11yRemovalMessage](#geta11yremovalmessage)
- [getA11yStatusMessage](#geta11ystatusmessage)
- [selectedItemChanged](#selecteditemchanged)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand All @@ -22,11 +23,13 @@ The handlers below have their types improved to reflect that they will always
get called with their corresponding state prop:

- useCombobox

- onSelectedItemChange: selectedItem is non optional
- onIsOpenChange: isOpen is non optional
- onHighlightedIndexChange: highlightedIndex is non optional

- useSelect

- onSelectedItemChange: selectedItem is non optional
- onIsOpenChange: isOpen is non optional
- onHighlightedIndexChange: highlightedIndex is non optional
Expand Down Expand Up @@ -80,3 +83,12 @@ References:
- [useCombobox docs](https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#geta11ystatusmessage)
- [useSelect docs](https://github.com/downshift-js/downshift/blob/master/src/hooks/useSelect/README.md#geta11ystatusmessage)
- [useMultipleSelection docs](https://github.com/downshift-js/downshift/blob/master/src/hooks/useMultipleSelection/README.md#geta11ystatusmessage)

## selectedItemChanged

This prop has been removed from `useCombobox`. You should use `itemToKey`
instead.

Reference:

[itemToKey docs](https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#itemtokey)
15 changes: 2 additions & 13 deletions src/hooks/useCombobox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ and update if necessary.
- [defaultHighlightedIndex](#defaulthighlightedindex)
- [defaultInputValue](#defaultinputvalue)
- [itemToKey](#itemtokey)
- [selectedItemChanged](#selecteditemchanged)
- [getA11yStatusMessage](#geta11ystatusmessage)
- [onHighlightedIndexChange](#onhighlightedindexchange)
- [onIsOpenChange](#onisopenchange)
Expand Down Expand Up @@ -411,8 +410,8 @@ function itemToKey(item) {
```

> This deprecates the "selectedItemChanged" prop. If you are using the prop
> already, make sure you change to "itemToKey" as the former will be removed in
> the next Breaking Change update. A migration example:
> already, make sure you change to "itemToKey" as the former is removed in v9. A
> migration example:
```js
// initial items.
Expand All @@ -438,16 +437,6 @@ function itemToKey(item) {
}
```

### selectedItemChanged

> DEPRECATED. Please use "itemToKey".
> `function(prevItem: any, item: any)` | defaults to:
> `(prevItem, item) => (prevItem !== item)`
Used to determine if the new `selectedItem` has changed compared to the previous
`selectedItem` and properly update Downshift's internal state.

### getA11yStatusMessage

> `function({/* see below */})` | default messages provided in English
Expand Down
117 changes: 0 additions & 117 deletions src/hooks/useCombobox/__tests__/props.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,123 +71,6 @@ describe('props', () => {
})
})

describe('selectedItemChanged', () => {
test('props update of selectedItem will update inputValue state with default selectedItemChanged referential equality check', () => {
const initialSelectedItem = {id: 3, value: 'init'}
const selectedItem = {id: 1, value: 'wow'}
const newSelectedItem = {id: 1, value: 'not wow'}
function itemToString(item) {
return item.value
}
const stateReducer = jest
.fn()
.mockImplementation((_state, {changes}) => changes)

const {rerender} = renderCombobox({
stateReducer,
itemToString,
selectedItem: initialSelectedItem,
})

expect(stateReducer).not.toHaveBeenCalled() // won't get called on first render

rerender({
stateReducer,
itemToString,
selectedItem,
})

expect(stateReducer).toHaveBeenCalledTimes(1)
expect(stateReducer).toHaveBeenCalledWith(
{
inputValue: itemToString(initialSelectedItem),
selectedItem,
highlightedIndex: -1,
isOpen: false,
},
expect.objectContaining({
type: useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem,
changes: {
inputValue: itemToString(selectedItem),
selectedItem,
highlightedIndex: -1,
isOpen: false,
},
}),
)

stateReducer.mockClear()
rerender({
stateReducer,
selectedItem: newSelectedItem,
itemToString,
})

expect(stateReducer).toHaveBeenCalledTimes(1)
expect(stateReducer).toHaveBeenCalledWith(
{
inputValue: itemToString(selectedItem),
selectedItem: newSelectedItem,
highlightedIndex: -1,
isOpen: false,
},
expect.objectContaining({
changes: {
inputValue: itemToString(newSelectedItem),
selectedItem: newSelectedItem,
highlightedIndex: -1,
isOpen: false,
},
type: useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem,
}),
)
expect(getInput()).toHaveValue(itemToString(newSelectedItem))
})

test('props update of selectedItem will not update inputValue state if selectedItemChanged returns false', () => {
const consoleWarnSpy = jest
.spyOn(console, 'warn')
.mockImplementation(() => {})
const initialSelectedItem = {id: 1, value: 'hmm'}
const selectedItem = {id: 1, value: 'wow'}
function itemToString(item) {
return item.value
}
const selectedItemChanged = jest
.fn()
.mockImplementation((prev, next) => prev.id !== next.id)
const stateReducer = jest
.fn()
.mockImplementation((_state, {changes}) => changes)

const {rerender} = renderCombobox({
selectedItemChanged,
stateReducer,
selectedItem: initialSelectedItem,
itemToString,
})

rerender({
selectedItemChanged,
stateReducer,
selectedItem,
itemToString,
})

expect(getInput()).toHaveValue(itemToString(initialSelectedItem))
expect(selectedItemChanged).toHaveBeenCalledTimes(1)
expect(selectedItemChanged).toHaveBeenCalledWith(
initialSelectedItem,
selectedItem,
)
expect(consoleWarnSpy).toHaveBeenCalledTimes(1)
expect(consoleWarnSpy).toHaveBeenCalledWith(
`The "selectedItemChanged" is deprecated. Please use "itemToKey instead". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged`,
)
consoleWarnSpy.mockRestore()
})
})

describe('itemToKey', () => {
test('props update of selectedItem will update inputValue state with default itemToKey referential equality check', () => {
const initialSelectedItem = {id: 3, value: 'init'}
Expand Down
20 changes: 3 additions & 17 deletions src/hooks/useCombobox/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const propTypes = {
...commonDropdownPropTypes,
items: PropTypes.array.isRequired,
isItemDisabled: PropTypes.func,
selectedItemChanged: PropTypes.func,
inputValue: PropTypes.string,
defaultInputValue: PropTypes.string,
initialInputValue: PropTypes.string,
Expand Down Expand Up @@ -79,22 +78,9 @@ export function useControlledReducer(
if (
!isInitialMount // on first mount we already have the proper inputValue for a initial selected item.
) {
let shouldCallDispatch

if (props.selectedItemChanged === undefined) {
shouldCallDispatch =
props.itemToKey(props.selectedItem) !==
props.itemToKey(previousSelectedItemRef.current)
} else {
console.warn(
`The "selectedItemChanged" is deprecated. Please use "itemToKey instead". https://github.com/downshift-js/downshift/blob/master/src/hooks/useCombobox/README.md#selecteditemchanged`,
)

shouldCallDispatch = props.selectedItemChanged(
previousSelectedItemRef.current,
props.selectedItem,
)
}
const shouldCallDispatch =
props.itemToKey(props.selectedItem) !==
props.itemToKey(previousSelectedItemRef.current)

if (shouldCallDispatch) {
dispatch({
Expand Down
1 change: 0 additions & 1 deletion typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,6 @@ export interface UseComboboxProps<Item> {
isItemDisabled?(item: Item, index: number): boolean
itemToString?: (item: Item | null) => string
itemToKey?: (item: Item | null) => any
selectedItemChanged?: (prevItem: Item, item: Item) => boolean
getA11yStatusMessage?: (options: UseComboboxState<Item>) => string
highlightedIndex?: number
initialHighlightedIndex?: number
Expand Down

0 comments on commit fd1ede6

Please sign in to comment.