Skip to content

Commit 1c06c4e

Browse files
committed
feat(useTagGroup) add examples
1 parent f7ae0d3 commit 1c06c4e

7 files changed

Lines changed: 465 additions & 16 deletions

File tree

docs/hooks/index.mdx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@ If you need to add multiple selection for any of them and have the selected
1818
items act as a Tag List next to the _select_ or _combobox_, then
1919
[useMultipleSelection](/use-multiple-selection) is the right tool for that.
2020

21-
## Breaking Changes in v8
21+
## Migration Guides
2222

23-
Since version 8, there have been breaking changes to functionality and TS types.
24-
Check out the
25-
[migration page](https://github.com/downshift-js/downshift/blob/master/src/hooks/MIGRATION_V8.md).
26-
27-
## Breaking Changes in v7
23+
### v7
2824

2925
Since version 7, the _useSelect_ and _useCombobox_ hooks to support the ARIA 1.2
3026
pattern for the combobox, which contains some changes from the ARIA 1.1 pattern.
3127
This brings changes in the API and the behaviour of _useCombobox_, detailed in
3228
the
3329
[migration page](https://github.com/downshift-js/downshift/blob/master/src/hooks/MIGRATION_V7.md).
30+
31+
### v8 & v9
32+
33+
Since versions 8 and 9, there have been breaking changes to functionality and TS
34+
types. Check out the migration pages for
35+
[v8](https://github.com/downshift-js/downshift/blob/master/src/hooks/MIGRATION_V8.md)
36+
and
37+
[v9](https://github.com/downshift-js/downshift/blob/master/src/hooks/MIGRATION_V9.md).

docs/hooks/useCombobox.mdx

Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ implement the corresponding ARIA pattern. Every functionality needed should be
3232
provided out-of-the-box: menu toggle, item selection and up/down movement
3333
between them, screen reader support, focus management etc.
3434

35-
## Breaking Changes in v8
35+
## Breaking Changes in v8 and v9
3636

37-
_useCombobox_ has been affected by breaking changes in v8, so check out the
38-
[migration page][migration-guide-v8].
37+
_useCombobox_ has been affected by breaking changes in v8 and v9, so check out
38+
the migration pages for v8[migration-guide-v8] and v9[migration-guide-v9].
3939

4040
## Breaking Changes in v7
4141

@@ -207,7 +207,7 @@ with the resulting DOM element, we don't need to do anything specific rather
207207
than just spreading the getter props, apart from the case of the _Input_, which
208208
renders a wrapper element over the actual HTML _input_. In this case, since
209209
_Input_ provides a prop for accessing the _input_ element called _inputRef_, we
210-
will use the getter function like this: _getInputProps({refKey: 'inputRef'})_.
210+
will use the getter function like this: `getInputProps({refKey: 'inputRef'})`.
211211

212212
Another point worth mentioning is that in this case items are objects and not
213213
strings. As a result, the _itemToString_ prop is passed to _useCombobox_. It
@@ -906,6 +906,152 @@ function ComboBoxExample() {
906906
}
907907
```
908908

909+
## Multiple selection with Tag Group
910+
911+
```jsx live
912+
function TagGroupExample() {
913+
const books = [
914+
{id: 'book-1', author: 'Harper Lee', title: 'To Kill a Mockingbird'},
915+
{id: 'book-2', author: 'Lev Tolstoy', title: 'War and Peace'},
916+
{id: 'book-3', author: 'Fyodor Dostoyevsy', title: 'The Idiot'},
917+
{id: 'book-4', author: 'Oscar Wilde', title: 'A Picture of Dorian Gray'},
918+
{id: 'book-5', author: 'George Orwell', title: '1984'},
919+
{id: 'book-6', author: 'Jane Austen', title: 'Pride and Prejudice'},
920+
{id: 'book-7', author: 'Marcus Aurelius', title: 'Meditations'},
921+
{
922+
id: 'book-8',
923+
author: 'Fyodor Dostoevsky',
924+
title: 'The Brothers Karamazov',
925+
},
926+
{id: 'book-9', author: 'Lev Tolstoy', title: 'Anna Karenina'},
927+
{id: 'book-10', author: 'Fyodor Dostoevsky', title: 'Crime and Punishment'},
928+
]
929+
930+
function TagGroup() {
931+
const initialItems = books.slice(0, 2)
932+
const [inputValue, setInputValue] = React.useState('')
933+
934+
const {
935+
addItem,
936+
getTagProps,
937+
getTagRemoveProps,
938+
getTagGroupProps,
939+
items,
940+
activeIndex,
941+
} = useTagGroup({
942+
initialItems,
943+
})
944+
const itemsToAdd = books.filter(
945+
book =>
946+
!items.includes(book) &&
947+
(!inputValue ||
948+
book.title.toLowerCase().includes(inputValue.toLowerCase()) ||
949+
book.author.toLowerCase().includes(inputValue.toLowerCase())),
950+
)
951+
const {
952+
isOpen,
953+
getToggleButtonProps,
954+
getLabelProps,
955+
getMenuProps,
956+
getInputProps,
957+
highlightedIndex,
958+
getItemProps,
959+
} = useCombobox({
960+
items: itemsToAdd,
961+
inputValue,
962+
onInputValueChange: ({inputValue}) => {
963+
setInputValue(inputValue)
964+
},
965+
onSelectedItemChange({selectedItem}) {
966+
if (selectedItem) {
967+
addItem(selectedItem)
968+
}
969+
},
970+
selectedItem: null,
971+
stateReducer(_state, actionAndChanges) {
972+
const {changes} = actionAndChanges
973+
974+
if (changes.selectedItem) {
975+
return {...changes, inputValue: '', highlightedIndex: 0, isOpen: true}
976+
}
977+
978+
return changes
979+
},
980+
})
981+
982+
return (
983+
<div>
984+
<div
985+
{...getTagGroupProps({'aria-label': 'books usage example'})}
986+
className="inline-flex gap-2 items-center flex-wrap p-1.5"
987+
>
988+
{items.map((item, index) => (
989+
<span
990+
className={`${
991+
index === activeIndex ? 'italic' : ''
992+
} "border border-green-800 bg-green-600 px-1.5 mx-0.5 rounded-[10px] cursor-default hover:opacity-50 focus:bg-red-600 focus:border-red-800"`}
993+
key={item.id}
994+
{...getTagProps({index, 'aria-label': item.title})}
995+
>
996+
{item.title}
997+
<span
998+
className="p-1 cursor-pointer border-0 bg-transparent"
999+
{...getTagRemoveProps({index, 'aria-label': 'remove'})}
1000+
>
1001+
&#10005;
1002+
</span>
1003+
</span>
1004+
))}
1005+
</div>
1006+
<div className="w-72 flex flex-col gap-1">
1007+
<label className="w-fit" {...getLabelProps()}>
1008+
Choose your favorite book:
1009+
</label>
1010+
<div className="flex shadow-sm bg-white gap-0.5">
1011+
<input
1012+
placeholder="Best book ever"
1013+
className="w-full p-1.5"
1014+
{...getInputProps()}
1015+
/>
1016+
<button
1017+
aria-label="toggle menu"
1018+
className="px-2"
1019+
type="button"
1020+
{...getToggleButtonProps()}
1021+
>
1022+
{isOpen ? <>&#8593;</> : <>&#8595;</>}
1023+
</button>
1024+
</div>
1025+
</div>
1026+
<ul
1027+
className={`absolute w-72 bg-white mt-1 shadow-md max-h-80 overflow-scroll p-0 z-10 ${
1028+
!(isOpen && itemsToAdd.length) && 'hidden'
1029+
}`}
1030+
{...getMenuProps()}
1031+
>
1032+
{isOpen &&
1033+
itemsToAdd.map((item, index) => (
1034+
<li
1035+
className={cx(
1036+
highlightedIndex === index && 'bg-blue-300',
1037+
'py-2 px-3 shadow-sm flex flex-col',
1038+
)}
1039+
key={item.id}
1040+
{...getItemProps({item, index})}
1041+
>
1042+
<span>{item.title}</span>
1043+
<span className="text-sm text-gray-700">{item.author}</span>
1044+
</li>
1045+
))}
1046+
</ul>
1047+
</div>
1048+
)
1049+
}
1050+
1051+
return <TagGroup />
1052+
}
1053+
```
1054+
9091055
## Using action props
9101056

9111057
Action props are functions returned by _useCombobox_ along with the state props
@@ -1207,3 +1353,5 @@ repository][examples-code-sandbox].
12071353
https://github.com/downshift-js/downshift/tree/master/src/hooks/MIGRATION_V7.md#usecombobox
12081354
[migration-guide-v8]:
12091355
https://github.com/downshift-js/downshift/tree/master/src/hooks/MIGRATION_V8.md
1356+
[migration-guide-v9]:
1357+
https://github.com/downshift-js/downshift/tree/master/src/hooks/MIGRATION_V9.md

docs/hooks/useMultipleSelection.mdx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ slug: /use-multiple-selection
66

77
# useMultipleSelection
88

9+
## DEPRECATED
10+
11+
Please use the [useTagGroup](/use-tag-group) hook to create multiple selection
12+
dropdowns with tag groups. Check out the examples for each:
13+
14+
- [useCombobox](/use-combobox#multiple-selection-with-tag-group)
15+
- [useSelect](/use-select#multiple-selection-with-tag-group)
16+
917
## The problem
1018

1119
You have a custom **select** or a **combobox** in your applications which
@@ -33,10 +41,11 @@ arrow navigation between dropdown and items, navigation between the items
3341
themselves, removing and adding items, and also a helpful _aria-live_ message
3442
when an item has been removed from the selection.
3543

36-
## Breaking Changes in v8
44+
## Breaking Changes in v8 and v9
3745

38-
_useMultipleSelection_ has been affected by breaking changes in v8, so check out
39-
the [migration page][migration-guide-v8].
46+
_useMultipleSelection_ has been affected by breaking changes in v8 and v9, so
47+
check out the migration pages for v8[migration-guide-v8] and
48+
v9[migration-guide-v9].
4049

4150
## Props used in examples
4251

@@ -452,3 +461,5 @@ To see more cool stuff you can build with _useMultipleSelection_, explore the
452461
https://codesandbox.io/p/sandbox/github/kentcdodds/downshift-examples?file=%2Fsrc%2Findex.js%3A25%2C12&moduleview=1
453462
[migration-guide-v8]:
454463
https://github.com/downshift-js/downshift/tree/master/src/hooks/MIGRATION_V8.md
464+
[migration-guide-v9]:
465+
https://github.com/downshift-js/downshift/tree/master/src/hooks/MIGRATION_V9.md

0 commit comments

Comments
 (0)