Skip to content

Instantly share code, notes, and snippets.

@JofArnold
Last active October 9, 2023 04:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JofArnold/c03326170ebd7bb9118fd6aa3bb8aaf1 to your computer and use it in GitHub Desktop.
Save JofArnold/c03326170ebd7bb9118fd6aa3bb8aaf1 to your computer and use it in GitHub Desktop.
Example of how to use Downshift as a controlled component with arbitrary items
// Untested code, but hopefully it gives you an idea.
// Ping me @jofarnold on Twitter if you get stuck
import React, { Component } from "react";
import Downshift from "downshift";
import PropTypes from "prop-types";
function nodeFromItem(id, items) {
return items.find(({ uuid }) => uuid === id);
}
class Dropdown extends Component {
constructor(props) {
super(props);
}
render() {
const { prompt, items, ...rest } = this.props;
return (
<Downshift {...rest}>
{({
getButtonProps,
getItemProps,
isOpen,
toggleMenu,
selectedItem: selectedUuid,
}) => {
return (
<span>
<button
{...getButtonProps()}
onClick={toggleMenu}
...etc
>
{selectedUuid === null
? prompt
: nodeFromItem(selectedUuid, items)}
</button>
{isOpen ? (
<span>
{items.map(({ uuid, node }) => (
<button
getItemProps={getItemProps}
key={uuid}
node={node}
uuid={uuid}
...etc
/>
))}
</span>
) : null}
</span>
);
}}
</Downshift>
);
}
}
// Your controlled dropdown.
// Takes `true` or `false` and outputs "Yes" or "No"
const TrueFalseDropdown = ({ value, onChange }) => {
const items = [{ uuid: "yes", node: <span>Yes!<span> }, { uuid: "no", node: <span>No</span> }];
return (
<Dropdown
items={items}
onChange={v => onChange(v === "yes")}
prompt="Are you feeling groovy?"
selectedItem={value === true ? "yes" : "no"}
/>
);
};
TrueFalseDropdown.propTypes = {
value: PropTypes.bool,
onChange: PropTypes.func,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment