Created
November 7, 2018 17:55
-
-
Save ryanflorence/669e04f4ee833555a16aae649cb8d2ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Suspense, useState } from "react"; | |
import { unstable_createResource as createResource } from "react-cache"; | |
import { | |
Autocomplete as Combobox, | |
Input as ComboboxInput, | |
List as ComboboxList, | |
Option as ComboboxOption | |
} from "./Combobox"; | |
function App({ tabIndex, navigate }) { | |
let [searchTerm, setSearchTerm] = useState(null); | |
function handleSelect(value) { | |
console.log("SELECTED!", value); | |
} | |
return ( | |
<div> | |
<h1 style={{ textAlign: "center" }}>Combobox</h1> | |
<p> | |
<b>Features / Keyboard events</b> | |
</p> | |
<ul style={{ lineHeight: 1.5 }}> | |
<li>Autocompletes first suggestion</li> | |
<li>ArrowDown/Up navigate the list</li> | |
<li> | |
When navigating with arrow keys | |
<ul> | |
<li>The input's value changes to the item</li> | |
<li> | |
Enter | |
<ul> | |
<li>Selects an item (calls onSelect prop)</li> | |
<li>List closes</li> | |
<li>Text is selected</li> | |
</ul> | |
</li> | |
<li> | |
Escape | |
<ul> | |
<li>Puts the value back to what it was before</li> | |
<li>Including autocompleted portion</li> | |
</ul> | |
</li> | |
</ul> | |
</li> | |
<li> | |
Escape while typing (not navigating) | |
<ul> | |
<li>Closes the list</li> | |
<li>Selects the text</li> | |
</ul> | |
</li> | |
</ul> | |
<Combobox onSelect={handleSelect}> | |
<ComboboxInput | |
onChange={async event => { | |
let value = event.target.value; | |
await Promise.resolve(); | |
setSearchTerm(value); | |
}} | |
/> | |
<Suspense maxDuration={2000} fallback={<div>Loading...</div>}> | |
<AsyncList searchTerm={searchTerm} /> | |
</Suspense> | |
</Combobox> | |
<div style={{ height: 400 }} /> | |
</div> | |
); | |
} | |
function AsyncList({ searchTerm }) { | |
let options = SearchResource.read(searchTerm); | |
return options ? ( | |
<ComboboxList> | |
{options.map(option => ( | |
<ComboboxOption key={option} value={option}> | |
{option} | |
</ComboboxOption> | |
))} | |
</ComboboxList> | |
) : null; | |
} | |
let rando = () => | |
Math.random() | |
.toString(16) | |
.substr(2, 8); | |
let SearchResource = createResource(value => { | |
return new Promise(resolve => { | |
setTimeout(() => { | |
resolve( | |
value | |
? [ | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}` | |
] | |
: null | |
); | |
}, Math.random() * 1000); | |
}); | |
}); | |
export default () => ( | |
<Suspense maxDuration={5000} fallback={<div>Loading...</div>}> | |
<App /> | |
</Suspense> | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment