Skip to content

Commit fc0c3a1

Browse files
committed
feat: migrate from docz to docusaurus
1 parent 4804ffc commit fc0c3a1

32 files changed

+3195
-2447
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
.docz
2-
.cache
1+
.docusaurus
2+
build
33
node_modules

.npmrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
registry=http://registry.npmjs.org/
21
package-lock=false

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
16.14.0

README.md

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
1-
# Downshift Docs
1+
# Website
22

3-
Repository that hosts the Downshift Docsite. All Downshift examples should be hosted here, along with links to their Codesandbox equivalents, which should be hosted on the [examples repository](https://github.com/downshift-js/downshift-examples).
3+
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
44

5-
## Develop
5+
### Installation
66

7-
```sh
8-
npm install
7+
```
8+
$ yarn
9+
```
10+
11+
### Local Development
12+
13+
```
14+
$ yarn start
15+
```
16+
17+
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18+
19+
### Build
920

10-
npm run dev
1121
```
22+
$ yarn build
23+
```
24+
25+
This command generates static content into the `build` directory and can be served using any static contents hosting service.
26+
27+
### Deployment
28+
29+
Using SSH:
1230

13-
This will start the `docz` app in development mode.
31+
```
32+
$ USE_SSH=true yarn deploy
33+
```
1434

35+
Not using SSH:
1536

16-
## Contribute
37+
```
38+
$ GIT_USER=<Your GitHub username> yarn deploy
39+
```
1740

18-
A great opportunity is to have all the sandboxes of the examples from this docsite in the examples repository. Also to have all examples from the examples repository hosted on the docsite as well.
41+
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

babel.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3+
};

docs/downshift.mdx

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
---
2+
title: Downshift
3+
description: Downshift Component Documentation
4+
slug: /downshift
5+
sidebar_position: 3
6+
---
7+
8+
# Downshift
9+
10+
## Introduction
11+
12+
The **Downshift** component has been developed in order to provide accessibility
13+
and functionality to a **combobox** or **autocomplete** input, described by its
14+
corresponding [ARIA accessibility pattern][combobox-aria].
15+
16+
This is a component that controls user interactions and state for you so you can
17+
create _autocomplete/combobox_ or _select_ components. It uses a [render
18+
prop][use-a-render-prop] which gives you maximum flexibility with a minimal API
19+
because you are responsible for the rendering of everything and you simply apply
20+
props to what you're rendering.
21+
22+
This differs from other solutions which render things for their use case and
23+
then expose many options to allow for extensibility resulting in a bigger API
24+
that is less flexible as well as making the implementation more complicated and
25+
harder to contribute to.
26+
27+
## Props used in examples
28+
29+
In the examples below, we use the **Downshift** component and destructure from
30+
its result the getter props and state variables. The props returned by
31+
_Downshift_ are used as follows:
32+
33+
| Returned prop | Element | Comments |
34+
| ---------------------- | ---------- | -------------------------------------------------------------------------------------------- |
35+
| `getLabelProps` | `<label>` | Call and destructure its returned object on the label element. |
36+
| `getToggleButtonProps` | `<button>` | Call and destructure its returned object on the toggle button (if any). |
37+
| `getRootProps` | `<div>` | Call and destructure its returned object on the input and toggle button parent. |
38+
| `getInputProps` | `<input>` | Call and destructure its returned object on the input element. |
39+
| `getMenuProps` | `<ul>` | Call and destructure its returned object on the menu element. |
40+
| `getItemProps` | `<li>` | Call with `index` or `item` and destructure its returned object on each menu item element. |
41+
| `isOpen` | | State value with the open state of the menu. Used below for conditionally showing the items. |
42+
| `highlightedIndex` | | State value with the index of thehighlighted menu item. Used below for styling. |
43+
| `selectedItem` | | State value with the item that is selected. Used below for styling. |
44+
| `inputValue` | | State value with the search query. Used below for filtering the items. |
45+
46+
For a complete documentation on all the returned props, component props and more
47+
information check out the [Github Page][github-page].
48+
49+
## Important
50+
51+
If you are new to _Downshift_ then maybe you should first check
52+
[useCombobox](/use-combobox) which should provide the same functionality but as
53+
a hook. Also, if you need just a _select_ dropdown without a text input, then
54+
check [useSelect](/use-select). Finally, for multiple selection support, you can
55+
check the [useMultipleSelection](/use-multiple-selection) hook.
56+
57+
As far as the Downshift component is concerned, you can use it in two ways, both
58+
of them illustrated below.
59+
60+
There is a (straightforward* way, which allows you to wrap your whole
61+
\_combobox* HTML in _Downshift_. The drawback of this way is that the _combobox_
62+
HTML structure suggested by ARIA is not achieved, and screen readers will not
63+
widely support it.
64+
65+
There is also the _not-so-straightforward-way_ which allows you to follow the
66+
_combobox_ HTML structure and you should aim to implement this one. Here you
67+
will use _getRootProps_ on the element that wraps your _input_ and then you will
68+
add the _ul_ element as a sibling to the wrapper element. See the examples
69+
below.
70+
71+
A _combobox_ element can be created with HTML elements such as a: **label**,
72+
**ul**, **li**, **button**, **input** and a **div** or something similar to
73+
contain the input and the toggle button. It is absolutely important to follow
74+
the HTML structure below, as it will allow all screen readers to properly work
75+
with the widget. Most importantly, the **input** needs to be contained by the
76+
combobox **div** and the **ul** needs to be at the same level with the combobox
77+
**div**.
78+
79+
## Usage with `getRootProps`
80+
81+
It is possible to achieve the correct HTML structure only if you use
82+
**getRootProps** getter prop from _Downshift_. You apply _getRootProps_ on the
83+
wrapper element that contains the _input_ and optionally the trigger button.
84+
85+
[CodeSandbox for usage with getRootProps.][code-sandbox-no-get-root-props]
86+
87+
```jsx live
88+
function ComboBox() {
89+
const items = [
90+
{author: 'Harper Lee', title: 'To Kill a Mockingbird'},
91+
{author: 'Lev Tolstoy', title: 'War and Peace'},
92+
{author: 'Fyodor Dostoyevsy', title: 'The Idiot'},
93+
{author: 'Oscar Wilde', title: 'A Picture of Dorian Gray'},
94+
{author: 'George Orwell', title: '1984'},
95+
{author: 'Jane Austen', title: 'Pride and Prejudice'},
96+
{author: 'Marcus Aurelius', title: 'Meditations'},
97+
{author: 'Fyodor Dostoevsky', title: 'The Brothers Karamazov'},
98+
{author: 'Lev Tolstoy', title: 'Anna Karenina'},
99+
{author: 'Fyodor Dostoevsky', title: 'Crime and Punishment'},
100+
]
101+
102+
return (
103+
<Downshift
104+
onChange={selection =>
105+
alert(
106+
selection
107+
? `You selected "${selection.title}" by ${selection.author}. Great Choice!`
108+
: 'Selection Cleared',
109+
)
110+
}
111+
itemToString={item => (item ? item.title : '')}
112+
>
113+
{({
114+
getInputProps,
115+
getItemProps,
116+
getLabelProps,
117+
getMenuProps,
118+
getToggleButtonProps,
119+
isOpen,
120+
inputValue,
121+
highlightedIndex,
122+
selectedItem,
123+
getRootProps,
124+
}) => (
125+
<div>
126+
<div className="w-72 flex flex-col gap-1">
127+
<label {...getLabelProps()}>Favorite Book:</label>
128+
<div
129+
className="flex shadow-sm bg-white gap-0.5"
130+
{...getRootProps({}, {suppressRefError: true})}
131+
>
132+
<input className="w-full p-1.5" {...getInputProps()} />
133+
<button
134+
aria-label={'toggle menu'}
135+
className="px-2"
136+
type="button"
137+
{...getToggleButtonProps()}
138+
>
139+
{isOpen ? <>&#8593;</> : <>&#8595;</>}
140+
</button>
141+
</div>
142+
</div>
143+
<ul
144+
className="absolute w-72 bg-white mt-1 shadow-md max-h-80 overflow-scroll"
145+
{...getMenuProps()}
146+
>
147+
{isOpen
148+
? items
149+
.filter(
150+
item =>
151+
!inputValue ||
152+
item.title.toLowerCase().includes(inputValue) ||
153+
item.author.toLowerCase().includes(inputValue),
154+
)
155+
.map((item, index) => (
156+
<li
157+
className={cx(
158+
highlightedIndex === index && 'bg-blue-300',
159+
selectedItem === item && 'font-bold',
160+
'py-2 px-3 shadow-sm flex flex-col',
161+
)}
162+
{...getItemProps({
163+
key: item.title,
164+
index,
165+
item,
166+
})}
167+
>
168+
<span>{item.title}</span>
169+
<span className="text-sm text-gray-700">
170+
{item.author}
171+
</span>
172+
</li>
173+
))
174+
: null}
175+
</ul>
176+
</div>
177+
)}
178+
</Downshift>
179+
)
180+
}
181+
```
182+
183+
## Usage without `getRootProps`
184+
185+
Using _Downshift_ without the _getRootProps_ will add the _combobox_ role to the
186+
child element rendered. This way forces your widget into having all elements
187+
(menu, input, button, label) as children of the _combobox_, which is not
188+
compatible with the ARIA combobox HTML structure. It will still work but this
189+
structure is not supported by all screen readers. Since this is how the usage
190+
was advertised in the past, we are still supporting it, but we strongly suggest
191+
to move either to the structure with the _getRootProps_ or even better to use
192+
the _useCombobox_ hook.
193+
194+
[CodeSandbox for usage without getRootProps.][code-sandbox-get-root-props]
195+
196+
```jsx live
197+
function ComboBox() {
198+
const items = [
199+
{author: 'Harper Lee', title: 'To Kill a Mockingbird'},
200+
{author: 'Lev Tolstoy', title: 'War and Peace'},
201+
{author: 'Fyodor Dostoyevsy', title: 'The Idiot'},
202+
{author: 'Oscar Wilde', title: 'A Picture of Dorian Gray'},
203+
{author: 'George Orwell', title: '1984'},
204+
{author: 'Jane Austen', title: 'Pride and Prejudice'},
205+
{author: 'Marcus Aurelius', title: 'Meditations'},
206+
{author: 'Fyodor Dostoevsky', title: 'The Brothers Karamazov'},
207+
{author: 'Lev Tolstoy', title: 'Anna Karenina'},
208+
{author: 'Fyodor Dostoevsky', title: 'Crime and Punishment'},
209+
]
210+
211+
return (
212+
<Downshift
213+
onChange={selection =>
214+
alert(
215+
selection
216+
? `You selected "${selection.title}" by ${selection.author}. Great Choice!`
217+
: 'Selection Cleared',
218+
)
219+
}
220+
itemToString={item => (item ? item.title : '')}
221+
>
222+
{({
223+
getInputProps,
224+
getItemProps,
225+
getMenuProps,
226+
getLabelProps,
227+
getToggleButtonProps,
228+
inputValue,
229+
highlightedIndex,
230+
selectedItem,
231+
isOpen,
232+
}) => (
233+
<div>
234+
<div className="w-72 flex flex-col gap-1">
235+
<label {...getLabelProps()}>Favorite book</label>
236+
<div className="flex shadow-sm bg-white gap-0.5">
237+
<input className="w-full p-1.5" {...getInputProps()} />
238+
<button
239+
aria-label={'toggle menu'}
240+
className="px-2"
241+
{...getToggleButtonProps()}
242+
>
243+
{isOpen ? <>&#8593;</> : <>&#8595;</>}
244+
</button>
245+
</div>
246+
</div>
247+
<ul
248+
className="absolute w-72 bg-white mt-1 shadow-md max-h-80 overflow-scroll"
249+
{...getMenuProps()}
250+
>
251+
{isOpen
252+
? items
253+
.filter(
254+
item =>
255+
!inputValue ||
256+
item.title.toLowerCase().includes(inputValue) ||
257+
item.author.toLowerCase().includes(inputValue),
258+
)
259+
.map((item, index) => (
260+
<li
261+
className={cx(
262+
highlightedIndex === index && 'bg-blue-300',
263+
selectedItem === item && 'font-bold',
264+
'py-2 px-3 shadow-sm flex flex-col',
265+
)}
266+
key={`${item.value}${index}`}
267+
{...getItemProps({
268+
item,
269+
index,
270+
})}
271+
>
272+
<span>{item.title}</span>
273+
<span className="text-sm text-gray-700">
274+
{item.author}
275+
</span>
276+
</li>
277+
))
278+
: null}
279+
</ul>
280+
</div>
281+
)}
282+
</Downshift>
283+
)
284+
}
285+
```
286+
287+
## Other usage examples
288+
289+
To see more cool stuff you can build with _Downshift_, explore the [examples
290+
repository][examples-code-sandbox].
291+
292+
[combobox-aria]:
293+
https://w3c.github.io/aria-practices/examples/combobox/combobox-autocomplete-list.html
294+
[use-a-render-prop]:
295+
https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce
296+
[github-page]: https://github.com/downshift-js/downshift
297+
[code-sandbox-get-root-props]:
298+
https://codesandbox.io/s/github/kentcdodds/downshift-examples?file=/src/downshift/ordered-examples/01-basic-autocomplete.js
299+
[code-sandbox-no-get-root-props]:
300+
https://codesandbox.io/s/github/kentcdodds/downshift-examples?file=/src/downshift/ordered-examples/00-get-root-props-example.js
301+
[examples-code-sandbox]:
302+
https://codesandbox.io/s/github/kentcdodds/downshift-examples

docs/hooks/index.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: Hooks
3+
description: Downshift Hooks
4+
slug: /hooks
5+
sidebar_position: 2
6+
---
7+
8+
# Downshift Hooks
9+
10+
Every React hook offers custom logic to build the kind of dropdown you need. If
11+
you need to build a **combobox** then use [useCombobox](/use-combobox).
12+
13+
However, if you don't need to type a search query and just have a dropdown that
14+
is actioned by a button (a **select**, basically), then use
15+
[useSelect](/use-select).
16+
17+
If you need to add multiple selection for any of them and have the selected
18+
items act as a Tag List next to the _select_ or _combobox_, then
19+
[useMultipleSelection](/use-multiple-selection) is the right tool for that.

0 commit comments

Comments
 (0)