Blueprint's Select component is exactly what I need for my current React project, with one exception: I need to add some elements to its popover and don't see any way to do it.
Specifically, I'd like to add a title (e.g. an H2 element) above the filter input, and a bar of buttons (e.g., some Button components in a DIV) below the list. Select seems highly configurable but I see no way to add elements inside the popover...what am I missing?
Jordan's suggestions above, plus a little experimentation, ultimately yielded a workable answer:
filterable
to false to hide the built-in filter input.itemListRenderer
to render not only the dropdown items, but also an InputGroup to serve as a replacement filter.inputRef
prop to capture a ref to the underlying HTML input. Use that to focus the input when it appears, via the onOpening
property of Select's popoverProps
prop.Here's a simple component implementing the above:
// Extends Blueprint's Select component with header and footer props that
// can be any arbitrary elements or components
class ExtendedSelect extends Component {
constructor(props) {
super(props);
this.inputRef = null;
this.state = {query: ""};
}
handleInputChanged = event => {
this.setState({query: event.target.value});
}
receiveInputRef = (ref) => {
this.inputRef = ref;
}
handlePopoverOpening = () => {
if (this.inputRef) {
this.inputRef.focus();
}
}
listRenderer = ({filteredItems, renderItem}) => {
// Apply the supplied item renderer to the filtered list of items
const renderedItems = filteredItems.map(renderItem);
return (
<div>
{this.props.header}
<InputGroup inputRef={this.receiveInputRef} value={this.state.query} onChange={this.handleInputChanged} leftIcon="search" />
<Menu>
{renderedItems}
</Menu>
{this.props.footer}
</div>
);
}
render() {
return (
<Select
items={this.props.items}
filterable={false}
query={this.state.query}
itemListRenderer={this.listRenderer}
itemPredicate={this.props.itemPredicate}
itemRenderer={this.props.itemRenderer}
popoverProps={{onOpening:this.handlePopoverOpening}}
onItemSelect={this.props.onItemSelect}
>
{this.props.children}
</Select>
);
}
}
(Note that I'm only passing some of Select's props into the custom component—I suspect I'd know a way to pass them all were I a more experienced React developer.)
This works surprisingly well—e.g., other than a little work to focus the input when it appears, all of Select's other built-in behavior works as expected, like keyboard navigation of the menu while the input is focused.