alsoscotland / react-super-select

MIT License
95 stars 33 forks source link

Enhancement : option to expand dropdown on component mount #70

Closed amgohan closed 8 years ago

amgohan commented 8 years ago

We hope save clicks for our users, so we want when the page load, the dropdown fetch data and expand automatically.

It can be an option

alsoscotland commented 8 years ago

https://github.com/alsoscotland/react-super-select/pull/71

alsoscotland commented 8 years ago

https://github.com/alsoscotland/react-super-select/tree/v0.5.0

Thanks again @amgohan for filing all these issues! I think release v0.5.0 should address them all. (With the exception that you'll need a custom rendering function to do the highlighting) Please get in touch if you see any issues

amgohan commented 8 years ago

@alsoscotland : Thank you very much for releasing 0.5.0 quickly :+1: , I tried 0.5.0 it is awesome.

Thans again.

alsoscotland commented 8 years ago

@amgohan I got your message about focus: Glad that 0.5.0 is working for you. It is a bit too aggressive for me to auto-focus the control. It is not necessarily everyone's use-case that the control should be a focus point of the page, and manipulating focus directly is not typically a good idea for accessibility.

I will look into having an option to do so. Either an option for a callback function that will fire after mount, or just an option to focus it. I am trying to decide what would be better.

If you want a function to highlight text the simplest case would be something like this pseudo-code

var customItemTemplate = function(item, search) {

  var labelMarkup = item.label.replace(search, '<span class="highlight">' + search + '</span>');

  return(<div>
          { labelMarkup }
         </div>);
};
amgohan commented 8 years ago

@alsoscotland : I agree with you for auto-focus, it shouldn't be the default behaviour, but you can add it as option like "focusSearchOnExpand" or let the user extends the super-select-component and override some methods (OOP principales). for example in my case I want be able to override this method :

_focusCurrentFocusedId: function _focusCurrentFocusedId() {
    if (this.state.focusedId < 0) {
      this._focusSearch();
      return;
    }

    this._focusDOMOption();
  }

by :

_focusCurrentFocusedId: function _focusCurrentFocusedId() {
    this._focusSearch();
  }
highlight(item, search) {

        var labelMarkup = item.name.replace(search, '<b>' + search + '</b>');

        return(<div>
                { labelMarkup }
            </div>);
    }

this is the result : html_not_interpreted

alsoscotland commented 8 years ago

@amgohan Yes. Sorry. Not quite as simple to get the highlight that way. You have to use dangerouslySetInnerHTML if using raw html like this markup. There are other ways to accomplish this with regular expressions but I was trying to do a simpler case:

var getHighlightedSearchLabel = function(item, search) {
  var labelMarkup = item.label.replace(search, '<span style="background-color: #f90;">' + search + '</span>');
  return React.DOM.span({ dangerouslySetInnerHTML: { __html: labelMarkup } });
}

var groceryCartItemTemplate = function(item, search) {
  var itemClasses = classNames('grocery-item',
                               'example-' + item.group.toLowerCase()),
      iconClasses = classNames('grocery-icon',
                               'rss-grocery',
                              'rss-grocery-' + item.attributeName);

  return(
    <div className={itemClasses}>
      <span className={iconClasses}></span>
      <p>{getHighlightedSearchLabel(item, search)} - {'$' + item.price.toFixed(2)}</p>
    </div>);
};
alsoscotland commented 8 years ago

@amgohan In terms of the focus issue, Overriding the focus function like you requested would break the aria accessibility for the control.

amgohan commented 8 years ago

@alsoscotland : thanks for the hint about dangerouslySetInnerHtml, this is my highlight function :

highlight(item, search) {
        if(search) {
            const searched = search.replace('(', '\\(').replace(')', '\\)')
            const query = new RegExp("(" + searched + ")", "gim")
            var highlightedName = item.name.replace(query, '<span style="color:#009cde;font-weight: bold">$1</span>');
            return(
                <div dangerouslySetInnerHTML={{__html: highlightedName}}>
                </div>
            );
        } else {
            return(
                <span className="r-ss-selected-label">
                    {item.name}
                </span>
            );
        }
    }
alsoscotland commented 8 years ago

Added focusOnMount option in https://github.com/alsoscotland/react-super-select/tree/v0.5.1

amgohan commented 8 years ago

Cool I will try it