Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active August 17, 2019 20:08
Show Gist options
  • Select an option

  • Save ryanflorence/3042134bfe5c3121c8fc93db7a62bcbc to your computer and use it in GitHub Desktop.

Select an option

Save ryanflorence/3042134bfe5c3121c8fc93db7a62bcbc to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from "react";
import "./packages/combobox/styles.css";
import {
Combobox,
ComboboxInput,
ComboboxList,
ComboboxOption,
ComboboxOptionText,
ComboboxPopup
} from "./packages/combobox/index";
import { useThrottle } from "use-throttle";
import uniqBy from "lodash.uniqby";
const styles = {
option: {
display: "flex",
alignItems: "center",
paddingRight: 10
},
imageWrapper: {
background: "#eee",
width: 30,
height: 30,
textAlign: "center"
},
optionTextWrapper: {
marginLeft: 10,
whiteSpace: "nowrap",
textOverflow: "ellipsis",
overflow: "hidden"
}
};
export default function ITunes() {
const [searchTerm, setSearchTerm] = useState(null);
const songs = useSongSearch(searchTerm);
const handleSearchTermChange = event => setSearchTerm(event.target.value);
return (
<div style={{ maxWidth: 600, margin: "auto" }}>
<h2>iTunes Search</h2>
<Combobox ariaLabel="iTunes Search">
<ComboboxInput onChange={handleSearchTermChange} />
<ComboboxPopup>
<ComboboxList>
{songs &&
songs.map(song => (
<ComboboxOption
key={song.trackId}
value={`${song.trackName}: ${song.collectionName}, ${
song.artistName
}`}
style={styles.option}
>
{console.log(song)}
<div style={styles.imageWrapper}>
<img
alt={song.collectionName}
src={song.artworkUrl60}
height="30"
width="30"
/>
</div>
<div style={styles.optionTextWrapper}>
<ComboboxOptionText />
</div>
</ComboboxOption>
))}
</ComboboxList>
</ComboboxPopup>
</Combobox>
</div>
);
}
async function fetchSongs(value) {
try {
let res = await fetch(`https://itunes.now.sh/?term=${value}`);
let json = await res.json();
let songs = json.results.filter(song => song.trackName);
let unique = uniqBy(
songs,
song => `${song.trackName}, ${song.collectionName}`
);
return unique.slice(0, 10);
} catch (e) {
return Promise.resolve(null);
}
}
function useSongSearch(searchTerm) {
const [results, setResults] = useState([]);
const throttled = useThrottle(searchTerm, 500);
useEffect(
() => {
if (throttled) {
if (throttled.trim() !== "") {
let current = true;
console.log("fetching", throttled);
fetchSongs(throttled).then(results => {
console.log("fetch finished", throttled);
if (current) {
console.log("setting results", throttled);
setResults(results);
}
});
return () => (current = false);
}
}
},
[throttled]
);
return results;
}
@aaron-sf
Copy link
Copy Markdown

RandomFocasableJunk -> RandomFocusableJunk :)

@shrmn
Copy link
Copy Markdown

shrmn commented Apr 30, 2019

For reference in the other direction, Ryan's video demo of the above code can be found here.

@pspeter3
Copy link
Copy Markdown

pspeter3 commented May 7, 2019

Is this going to be part of the reach-ui packages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment