-
-
Save whoisryosuke/e6ba1404d2a58fa5d9b47598f7ed2a7d 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
/* eslint-disable jsx-a11y/accessible-emoji */ | |
import React, { Suspense, useState } from "react"; | |
import { unstable_scheduleCallback } from "scheduler"; | |
import { unstable_createResource as createResource } from "react-cache"; | |
import { | |
Combobox, | |
ComboboxInput, | |
ComboboxList, | |
ComboboxOption, | |
ComboboxOptionText | |
} from "./Combobox.js"; | |
function App({ tabIndex, navigate }) { | |
let [searchTerm, setSearchTerm] = useState(null); | |
let [selection, setSelection] = useState(null); | |
let [searchTerm2, setSearchTerm2] = useState(null); | |
return ( | |
<div style={{ maxWidth: 600, margin: "auto" }}> | |
<h1 style={{ textAlign: "center" }}>Combobox</h1> | |
<h2>Async Search</h2> | |
<p> | |
last selection: <i>{selection}</i> | |
</p> | |
<form | |
onSubmit={event => { | |
event.preventDefault(); | |
setSearchTerm(null); | |
}} | |
> | |
<Combobox onSelect={setSelection}> | |
<ComboboxInput | |
selectOnClick | |
onChange={event => { | |
let value = event.target.value; | |
unstable_scheduleCallback(() => { | |
setSearchTerm(value); | |
}); | |
}} | |
/> | |
<Suspense maxDuration={2000} fallback={<div>Loading...</div>}> | |
<AsyncList searchTerm={searchTerm} /> | |
</Suspense> | |
</Combobox> | |
</form> | |
<div style={{ height: 50 }} /> | |
<h2>Client side search</h2> | |
<Combobox> | |
<ComboboxInput onChange={event => setSearchTerm2(event.target.value)} /> | |
<ComboboxList ariaText={`10 Results for ${searchTerm2}`}> | |
{searchTerm2 && searchTerm2.trim() !== "" | |
? Array.from({ length: 10 }).map((_, index) => ( | |
<ComboboxOption | |
key={index} | |
value={`${searchTerm2} ${rando()}`} | |
/> | |
)) | |
: null} | |
</ComboboxList> | |
</Combobox> | |
<div style={{ height: 50 }} /> | |
<h2>Custom rendering</h2> | |
<p>(options intentionally static)</p> | |
<Combobox> | |
<ComboboxInput /> | |
<ComboboxList ariaText="10 Results"> | |
<ComboboxOption value="Apple"> | |
π <ComboboxOptionText /> | |
</ComboboxOption> | |
<ComboboxOption value="Banana"> | |
π <ComboboxOptionText /> | |
</ComboboxOption> | |
<ComboboxOption value="Orange"> | |
π <ComboboxOptionText /> | |
</ComboboxOption> | |
<ComboboxOption value="Pineapple"> | |
π <ComboboxOptionText /> | |
</ComboboxOption> | |
<ComboboxOption value="Kiwi"> | |
π₯ <ComboboxOptionText /> | |
</ComboboxOption> | |
</ComboboxList> | |
</Combobox> | |
<div style={{ height: 400 }} /> | |
</div> | |
); | |
} | |
function AsyncList({ searchTerm }) { | |
let options = SearchResource.read(searchTerm); | |
return options ? ( | |
<ComboboxList ariaText={`${options.length} results`}> | |
{options.map(option => ( | |
<ComboboxOption key={option} value={option} /> | |
))} | |
</ComboboxList> | |
) : null; | |
} | |
let rando = () => | |
Math.random() | |
.toString(16) | |
.substr(2, 6); | |
let SearchResource = createResource(value => { | |
return new Promise(resolve => { | |
if (!value) { | |
resolve(null); | |
} | |
setTimeout(() => { | |
resolve([ | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${rando()} ${value} ${rando()}`, | |
`${value}${rando()}`, | |
`${rando()} ${value} ${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}`, | |
`${value}${rando()}` | |
]); | |
}, Math.random() * 500); | |
}); | |
}); | |
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