From 033f8254a0e2191d7dc48e0431bc233557c3a388 Mon Sep 17 00:00:00 2001 From: mertsincan Date: Tue, 1 Jun 2021 15:14:34 +0300 Subject: [PATCH] Refactor #2075 - For AutoComplete --- src/components/autocomplete/AutoComplete.js | 15 +- .../autocomplete/AutoCompletePanel.js | 128 ++++++++---------- 2 files changed, 65 insertions(+), 78 deletions(-) diff --git a/src/components/autocomplete/AutoComplete.js b/src/components/autocomplete/AutoComplete.js index 07627c03ee..876f5fd707 100644 --- a/src/components/autocomplete/AutoComplete.js +++ b/src/components/autocomplete/AutoComplete.js @@ -28,6 +28,7 @@ export class AutoComplete extends Component { optionGroupTemplate: null, forceSelection: false, autoHighlight: false, + virtualScrollerOptions: null, scrollHeight: '200px', dropdown: false, dropdownMode: 'blank', @@ -86,6 +87,7 @@ export class AutoComplete extends Component { optionGroupTemplate: PropTypes.any, forceSelection: PropTypes.bool, autoHighlight: PropTypes.bool, + virtualScrollerOptions: PropTypes.object, scrollHeight: PropTypes.string, dropdown: PropTypes.bool, dropdownMode: PropTypes.string, @@ -160,6 +162,7 @@ export class AutoComplete extends Component { this.onPanelClick = this.onPanelClick.bind(this); this.overlayRef = createRef(); + this.virtualScrollerRef = createRef(); this.inputRef = createRef(this.props.inputRef); } @@ -377,7 +380,7 @@ export class AutoComplete extends Component { } } else { - highlightItem = this.overlayRef.current.firstChild.firstChild; + highlightItem = DomHandler.findSingle(this.overlayRef.current, 'li'); if (DomHandler.hasClass(highlightItem, 'p-autocomplete-item-group')) { highlightItem = this.findNextItem(highlightItem); } @@ -834,13 +837,9 @@ export class AutoComplete extends Component { {input} {loader} {dropdown} - + ); } diff --git a/src/components/autocomplete/AutoCompletePanel.js b/src/components/autocomplete/AutoCompletePanel.js index 021d6685cf..a9e7940a55 100644 --- a/src/components/autocomplete/AutoCompletePanel.js +++ b/src/components/autocomplete/AutoCompletePanel.js @@ -1,53 +1,13 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import ObjectUtils from '../utils/ObjectUtils'; import { Ripple } from '../ripple/Ripple'; import { classNames } from '../utils/ClassNames'; import { CSSTransition } from '../transition/CSSTransition'; import { Portal } from '../portal/Portal'; +import { VirtualScroller } from '../virtualscroller/VirtualScroller'; class AutoCompletePanelComponent extends Component { - static defaultProps = { - suggestions: null, - field: null, - appendTo: null, - optionGroupLabel: null, - optionGroupChildren: null, - optionGroupTemplate: null, - itemTemplate: null, - onItemClick: null, - scrollHeight: '200px', - listId: null, - ariaSelected: null, - panelClassName: null, - panelStyle: null, - forwardRef: null, - onClick: null, - getOptionGroupLabel: null, - getOptionGroupChildren: null - } - - static propTypes = { - suggestions: PropTypes.array, - field: PropTypes.string, - appendTo: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - optionGroupLabel: PropTypes.string, - optionGroupChildren: PropTypes.string, - optionGroupTemplate: PropTypes.any, - itemTemplate: PropTypes.any, - onItemClick: PropTypes.func, - scrollHeight: PropTypes.string, - listId: PropTypes.any, - ariaSelected: PropTypes.any, - panelClassName: PropTypes.string, - panelStyle: PropTypes.object, - forwardRef: PropTypes.any, - onClick: PropTypes.func, - getOptionGroupLabel: PropTypes.func, - getOptionGroupChildren: PropTypes.func - }; - getOptionGroupRenderKey(optionGroup) { return ObjectUtils.resolveFieldData(optionGroup, this.props.optionGroupLabel); } @@ -68,53 +28,81 @@ class AutoCompletePanelComponent extends Component { ) } + renderItem(suggestion, index) { + if (this.props.optionGroupLabel) { + const groupContent = this.props.optionGroupTemplate ? ObjectUtils.getJSXElement(this.props.optionGroupTemplate, suggestion, index) : this.props.getOptionGroupLabel(suggestion); + const groupChildrenContent = this.renderGroupChildren(suggestion, index); + const key = index + '_' + this.getOptionGroupRenderKey(suggestion); + + return ( + +
  • + {groupContent} +
  • + {groupChildrenContent} +
    + ) + } + else { + let itemContent = this.props.itemTemplate ? ObjectUtils.getJSXElement(this.props.itemTemplate, suggestion, index) : this.props.field ? ObjectUtils.resolveFieldData(suggestion, this.props.field) : suggestion; + + return ( +
  • this.props.onItemClick(e, suggestion)}> + {itemContent} + +
  • + ); + } + } + renderItems() { if (this.props.suggestions) { - if (this.props.optionGroupLabel) { - return this.props.suggestions.map((suggestion, i) => { - const groupContent = this.props.optionGroupTemplate ? ObjectUtils.getJSXElement(this.props.optionGroupTemplate, suggestion, i) : this.props.getOptionGroupLabel(suggestion); - const groupChildrenContent = this.renderGroupChildren(suggestion, i); - const key = i + '_' + this.getOptionGroupRenderKey(suggestion); + return this.props.suggestions.map((suggestion, index) => this.renderItem(suggestion, index)); + } - return ( - -
  • - {groupContent} -
  • - {groupChildrenContent} -
    - ) - }); - } - else { - return this.props.suggestions.map((suggestion, index) => { - let itemContent = this.props.itemTemplate ? ObjectUtils.getJSXElement(this.props.itemTemplate, suggestion, index) : this.props.field ? ObjectUtils.resolveFieldData(suggestion, this.props.field) : suggestion; + return null; + } + + renderContent() { + if (this.props.virtualScrollerOptions) { + const virtualScrollerProps = { ...this.props.virtualScrollerOptions, ...{ + style: {...this.props.virtualScrollerOptions.style, ...{ height: this.props.scrollHeight || 'auto' }}, + items: this.props.suggestions, + itemTemplate: (item, options) => item && this.renderItem(item, options.index), + contentTemplate: (options) => { + const className = classNames('p-autocomplete-items', options.className); return ( -
  • this.props.onItemClick(e, suggestion)}> - {itemContent} - -
  • +
      + {options.children} +
    ); - }); - } + } + }}; + + return ; } + else { + const items = this.renderItems(); - return null; + return ( +
      + {items} +
    + ); + } } renderElement() { const panelClassName = classNames('p-autocomplete-panel p-component', this.props.panelClassName); const panelStyle = { maxHeight: this.props.scrollHeight, ...this.props.panelStyle }; - let items = this.renderItems(); + const content = this.renderContent(); return (
    -
      - {items} -
    + {content}
    );