Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,13 @@
"avatar_url": "https://avatars.githubusercontent.com/u/25305144?v=4",
"profile": "https://github.com/zmdavis",
"contributions": ["code", "bug"]
},
{
"login": "naveedsajjdawan",
"name": "Naveed Sajjad",
"avatar_url": "https://avatars.githubusercontent.com/u/88137903?v=4",
"profile": "https://github.com/naveedsajjdawan",
"contributions": ["doc"]
}
],
"repoHost": "https://github.com",
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ autocomplete, combobox or select dropdown components.</p>
[![downloads][downloads-badge]][npmcharts] [![version][version-badge]][package]
[![MIT License][license-badge]][license]

[![All Contributors](https://img.shields.io/badge/all_contributors-113-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-145-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs] [![Chat][chat-badge]][chat]
[![Code of Conduct][coc-badge]][coc]
[![Join the community on Spectrum][spectrum-badge]][spectrum]
Expand Down Expand Up @@ -1440,6 +1440,7 @@ Thanks goes to these people ([emoji key][emojis]):
<td align="center" valign="top" width="14.28%"><a href="https://tjenkinson.me"><img src="https://avatars.githubusercontent.com/u/3259993?v=4?s=100" width="100px;" alt="Tom Jenkinson"/><br /><sub><b>Tom Jenkinson</b></sub></a><br /><a href="#infra-tjenkinson" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aliceHendicott"><img src="https://avatars.githubusercontent.com/u/40346716?v=4?s=100" width="100px;" alt="Alice Hendicott"/><br /><sub><b>Alice Hendicott</b></sub></a><br /><a href="https://github.com/downshift-js/downshift/commits?author=aliceHendicott" title="Code">💻</a> <a href="https://github.com/downshift-js/downshift/issues?q=author%3AaliceHendicott" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zmdavis"><img src="https://avatars.githubusercontent.com/u/25305144?v=4?s=100" width="100px;" alt="Zach Davis"/><br /><sub><b>Zach Davis</b></sub></a><br /><a href="https://github.com/downshift-js/downshift/commits?author=zmdavis" title="Code">💻</a> <a href="https://github.com/downshift-js/downshift/issues?q=author%3Azmdavis" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/naveedsajjdawan"><img src="https://avatars.githubusercontent.com/u/88137903?v=4?s=100" width="100px;" alt="Naveed Sajjad"/><br /><sub><b>Naveed Sajjad</b></sub></a><br /><a href="https://github.com/downshift-js/downshift/commits?author=naveedsajjdawan" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
Expand Down
74 changes: 55 additions & 19 deletions src/hooks/useMultipleSelection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,41 +462,77 @@ function itemToKey(item) {

### getA11yStatusMessage

> `function({/* see below */})` | default messages provided in English
> `function({activeIndex, selectedItems})` | optional, no default

This function is passed as props to a status updating function nested within
that allows you to create your own ARIA statuses. It is called when the state
changes: `selectedItem`, `highlightedIndex`, `inputValue` or `isOpen`.
that allows you to create your own ARIA statuses. It is called after the initial
mount when `activeIndex` or `selectedItems` changes.

There is no default function provided anymore since v9, so if there's no prop
passed, no aria live status message is created. An implementation that resembles
the previous default is written below, should you want to keep pre v9 behaviour.
passed, no aria live status message is created. The example below opts into
announcements when selected books are removed.

We don't provide this as a default anymore since we consider that screen readers
have been significantly improved and they can convey information about items
count, possible actions and highlighted items only from the HTML markup, without
the need for aria-live regions.

```js
function getA11yStatusMessage(state) {
const {selectedItems} = state
```jsx
import * as React from 'react'
import {useMultipleSelection} from 'downshift'

if (selectedItems.length === previousSelectedItemsRef.current.length) {
return ''
}
const initialSelectedItems = [
{id: 1, title: 'To Kill a Mockingbird'},
{id: 2, title: 'War and Peace'},
]

const removedSelectedItem = previousSelectedItemsRef.current.find(
selectedItem =>
selectedItems.findIndex(
item => props.itemToKey(item) === props.itemToKey(selectedItem),
) < 0,
)
function SelectedBooks() {
const previousSelectedItemsRef = React.useRef(initialSelectedItems)
const {selectedItems, getSelectedItemProps, getDropdownProps} =
useMultipleSelection({
initialSelectedItems,
itemToKey: item => item.id,
getA11yStatusMessage({selectedItems: currentSelectedItems}) {
const previousSelectedItems = previousSelectedItemsRef.current
previousSelectedItemsRef.current = currentSelectedItems

const currentIds = new Set(currentSelectedItems.map(item => item.id))
return previousSelectedItems
.filter(item => !currentIds.has(item.id))
.map(item => `${item.title} has been removed.`)
.join(' ')
},
})

// where itemToString is a function that returns the string equivalent for an item.
return `${itemToString(removedSelectedItem)} has been removed.`
return (
<div>
<p id="selected-books-help">
Focus a selected book and press Delete or Backspace to remove it.
</p>
{selectedItems.map((selectedItem, index) => (
<span
key={selectedItem.id}
{...getSelectedItemProps({selectedItem, index})}
aria-describedby="selected-books-help"
>
{selectedItem.title}
</span>
))}
<label htmlFor="selected-books-input">Books</label>
<input id="selected-books-input" {...getDropdownProps()} />
</div>
)
}
```

Keep the previous selection in a ref initialized to the same selection as the
hook. Update it on every callback, including replacements with the same number
of items. Compare stable IDs so new object references do not count as removals.
This example returns an empty message for additions or focus changes and
announces each removed book when multiple books are removed at once. For a
controlled selection, initialize the ref from your initial `selectedItems` prop
instead.

### onActiveIndexChange

> `function(changes: object)` | optional, no useful default
Expand Down