Добавить элементы в Blueprint Выбрать компонент popover? - PullRequest
0 голосов
/ 01 сентября 2018

Blueprint's Select - это именно то, что мне нужно для моего текущего проекта React, с одним исключением: мне нужно добавить некоторые элементы в его popover и не вижу никакого способа сделать это.

В частности, я хотел бы добавить заголовок (например, элемент H2) над входом фильтра, а панель кнопок (например, некоторые компоненты кнопок в DIV) под списком. Выбор кажется легко настраиваемым, но я не вижу способа добавить элементы в поповер ... что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Предложения Джордана, приведенные выше, плюс небольшой эксперимент, в конечном итоге дали работоспособный ответ:

  1. Установите для filterable значение false, чтобы скрыть вход встроенного фильтра.
  2. Используйте itemListRenderer для визуализации не только выпадающих элементов, но и группы входных данных, служащей фильтром замены.
  3. Используйте опцию InputGroup inputRef для захвата ссылки на базовый ввод HTML. Используйте это, чтобы сфокусировать ввод, когда он появляется, через свойство onOpening в Select popoverProps prop.

Вот простой компонент, реализующий описанное выше:

// 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 работают, как и ожидалось, как клавиатурная навигация в меню, когда ввод фокусируется.

0 голосов
/ 04 сентября 2018

Если вы хотите расширить меню выбора и добавить в него пользовательские элементы, вам нужно предоставить itemListRenderer prop.

Вот что говорят документы :

По умолчанию Select отображает отображаемые элементы в меню. это поведение можно переопределить, предоставив itemListRenderer prop, давая вам полный контроль над расположением элементов. Например, вы может группировать элементы под общим заголовком или отображать большие наборы данных используя реагировать виртуализирован.

itemListRenderer пример:

Если предусмотрено, будет вызываться реквизит itemListRenderer для визуализации содержимого выпадающего меню. Он имеет доступ к элементам, текущему запросу и обратному вызову renderItem для отображения одного элемента. Также предоставляется обработчик ref (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={...}
/>
...