Blueprint的Select组件正是我当前的React项目所需的组件,但有一个例外:我需要在其弹出框中添加一些元素,但看不到任何实现方法。
具体来说,我想在过滤器输入上方添加标题(例如H2元素),并在列表下方添加按钮栏(例如DIV中的某些Button组件)。 Select似乎具有很高的可配置性,但是我看不到在弹出框内添加元素的方法……我缺少什么?
答案 0 :(得分:1)
如果要扩展选择的菜单并向其中添加自定义元素,则必须提供itemListRenderer
道具。
默认情况下,“选择”呈现菜单中显示的项目。这个 行为可以通过提供 itemListRenderer 道具来覆盖, 让您完全控制项目的布局。例如你 可以将项目归为一个共同的标题,或呈现大型数据集 使用react-virtualized。
itemListRenderer 示例:
如果提供,则将调用itemListRenderer属性以呈现下拉菜单的内容。它可以访问项目,当前查询以及用于渲染单个项目的renderItem回调。还提供了一个引用处理程序(itemsParentRef);应该将其附加到呈现的菜单项的父元素上,以便当前选择的项可以自动滚动到视图中。
因此,在Menu
组件的正文中,您可以放置自定义标题和按钮:
import { ItemListRenderer } from "@blueprintjs/select";
const renderMenu: ItemListRenderer<Film> = ({ items, itemsParentRef, query, renderItem }) => {
const renderedItems = items.map(renderItem).filter(item => item != null);
return (
<Menu ulRef={itemsParentRef}>
<h2>Your heading can be styled here</h2>
<MenuItem
disabled={true}
text={`Found ${renderedItems.length} items matching "${query}"`}
/>
{renderedItems}
<div>
<button>Button name</button>
</div>
</Menu>
);
};
<FilmSelect
itemListRenderer={renderMenu}
itemPredicate={filterFilm}
itemRenderer={renderFilm}
items={...}
onItemSelect={...}
/>
答案 1 :(得分:1)
Jordan的上述建议,加上一些实验,最终得出了可行的答案:
filterable
设置为false可隐藏内置过滤器输入。itemListRenderer
不仅可以显示下拉菜单项,还可以使用InputGroup来代替替换过滤器。inputRef
属性来捕获对基础HTML输入的引用。通过Select的onOpening
道具的popoverProps
属性,使用它来集中显示输入内容。这是实现上述内容的简单组件:
// 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>
);
}
}
(请注意,我只是将Select的一些道具传递给自定义组件,如果我是经验丰富的React开发人员,我想我会知道一种将所有道具传递给别人的方法。)
这出乎意料地很好-例如,除了在输入时进行一些使焦点集中的工作之外,Select的所有其他内置行为都可以按预期工作,例如在焦点对准输入时菜单的键盘导航。