import { r as registerInstance, c as createEvent, h, d as getElement } from './core-da60324f.js';
import { c as createCommonjsModule } from './_commonjsHelpers-4ab098b6.js';

var fuzzy = createCommonjsModule(function (module, exports) {
/*
 * Fuzzy
 * https://github.com/myork/fuzzy
 *
 * Copyright (c) 2012 Matt York
 * Licensed under the MIT license.
 */

(function() {

var root = this;

var fuzzy = {};

// Use in node or in browser
if ('object' !== 'undefined') {
  module.exports = fuzzy;
} else {
  root.fuzzy = fuzzy;
}

// Return all elements of `array` that have a fuzzy
// match against `pattern`.
fuzzy.simpleFilter = function(pattern, array) {
  return array.filter(function(str) {
    return fuzzy.test(pattern, str);
  });
};

// Does `pattern` fuzzy match `str`?
fuzzy.test = function(pattern, str) {
  return fuzzy.match(pattern, str) !== null;
};

// If `pattern` matches `str`, wrap each matching character
// in `opts.pre` and `opts.post`. If no match, return null
fuzzy.match = function(pattern, str, opts) {
  opts = opts || {};
  var patternIdx = 0
    , result = []
    , len = str.length
    , totalScore = 0
    , currScore = 0
    // prefix
    , pre = opts.pre || ''
    // suffix
    , post = opts.post || ''
    // String to compare against. This might be a lowercase version of the
    // raw string
    , compareString =  opts.caseSensitive && str || str.toLowerCase()
    , ch;

  pattern = opts.caseSensitive && pattern || pattern.toLowerCase();

  // For each character in the string, either add it to the result
  // or wrap in template if it's the next string in the pattern
  for(var idx = 0; idx < len; idx++) {
    ch = str[idx];
    if(compareString[idx] === pattern[patternIdx]) {
      ch = pre + ch + post;
      patternIdx += 1;

      // consecutive characters should increase the score more than linearly
      currScore += 1 + currScore;
    } else {
      currScore = 0;
    }
    totalScore += currScore;
    result[result.length] = ch;
  }

  // return rendered string if we have a match for every char
  if(patternIdx === pattern.length) {
    // if the string is an exact match with pattern, totalScore should be maxed
    totalScore = (compareString === pattern) ? Infinity : totalScore;
    return {rendered: result.join(''), score: totalScore};
  }

  return null;
};

// The normal entry point. Filters `arr` for matches against `pattern`.
// It returns an array with matching values of the type:
//
//     [{
//         string:   '<b>lah' // The rendered string
//       , index:    2        // The index of the element in `arr`
//       , original: 'blah'   // The original element in `arr`
//     }]
//
// `opts` is an optional argument bag. Details:
//
//    opts = {
//        // string to put before a matching character
//        pre:     '<b>'
//
//        // string to put after matching character
//      , post:    '</b>'
//
//        // Optional function. Input is an entry in the given arr`,
//        // output should be the string to test `pattern` against.
//        // In this example, if `arr = [{crying: 'koala'}]` we would return
//        // 'koala'.
//      , extract: function(arg) { return arg.crying; }
//    }
fuzzy.filter = function(pattern, arr, opts) {
  if(!arr || arr.length === 0) {
    return [];
  }
  if (typeof pattern !== 'string') {
    return arr;
  }
  opts = opts || {};
  return arr
    .reduce(function(prev, element, idx, arr) {
      var str = element;
      if(opts.extract) {
        str = opts.extract(element);
      }
      var rendered = fuzzy.match(pattern, str, opts);
      if(rendered != null) {
        prev[prev.length] = {
            string: rendered.rendered
          , score: rendered.score
          , index: idx
          , original: element
        };
      }
      return prev;
    }, [])

    // Sort by score. Browsers are inconsistent wrt stable/unstable
    // sorting, so force stable by using the index in the case of tie.
    // See http://ofb.net/~sethml/is-sort-stable.html
    .sort(function(a,b) {
      var compare = b.score - a.score;
      if(compare) return compare;
      return a.index - b.index;
    });
};


}());
});

const PwcChoicesDropdown = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.dropdownOptionClicked = createEvent(this, "dropdownOptionClicked", 7);
    }
    optionsWatchHandler(newValue) {
        this.filteredOptions = this.doFilter(this.getWholeSearchInput(), newValue);
    }
    componentWillLoad() {
        this.filteredOptions = this.convertOptionsToFilterResultsAsIs(this.options);
    }
    constructDropdown() {
        return (h("div", { class: "dropdown" }, h("input", { type: "text", class: "search", placeholder: "Search by typing...", onInput: e => this.onSearchInput(e) }), h("ul", null, this.filteredOptions && this.filteredOptions.length === 0 ? (h("li", { id: "noOptionsListItem" }, " ", this.noOptionsString)) : (this.filteredOptions.map(option => this.constructDropdownOption(option))))));
    }
    doFilter(phrase, rawOptions) {
        if (phrase.length === 0) {
            return this.convertOptionsToFilterResultsAsIs(rawOptions);
        }
        return fuzzy.filter(phrase, rawOptions, {
            pre: "<mark>",
            post: "</mark>",
            extract: el => el.label
        });
    }
    onSearchInput(e) {
        e.stopPropagation();
        this.filteredOptions = this.doFilter(this.getWholeSearchInput(), this.options);
    }
    getWholeSearchInput() {
        const searchBar = this.root.querySelector(".search");
        return searchBar.value;
    }
    constructDropdownOption(option) {
        return (h("li", { onClick: e => this.onDropdownOptionClick(option, e) }, h("span", { innerHTML: option.string })));
    }
    onDropdownOptionClick(optionFilterResult, clickEvent) {
        const originalOption = optionFilterResult.original;
        clickEvent.preventDefault();
        clickEvent.stopPropagation();
        this.dropdownOptionClicked.emit({
            originalEvent: clickEvent,
            option: originalOption
        });
        /* We need to remove them here if we want to keep the
         * dropdown open after a selection. A bit unplesant,
         * but we have to.
         */
        this.options.splice(this.options.indexOf(originalOption), 1);
        this.filteredOptions.splice(this.filteredOptions.indexOf(optionFilterResult), 1);
    }
    convertOptionsToFilterResultsAsIs(rawOptions) {
        return rawOptions.map(o => {
            return {
                string: o.label,
                score: 0,
                index: 0,
                original: o
            };
        });
    }
    render() {
        return this.constructDropdown();
    }
    get root() { return getElement(this); }
    static get watchers() { return {
        "options": ["optionsWatchHandler"]
    }; }
    static get style() { return "* {\n  margin: 0;\n  padding: 0;\n  -webkit-transition: background-color ease 0.2s;\n  transition: background-color ease 0.2s;\n  font-size: medium;\n  font-family: Calibri, sans-serif;\n}\n\n.container {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  position: relative;\n  width: 100%;\n}\n\n.input-bar {\n  border: 1px solid black;\n  min-height: 44px;\n  padding: 5px;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-wrap: nowrap;\n  flex-wrap: nowrap;\n  border-radius: 5px;\n  overflow: hidden;\n  background-color: white;\n}\n\n.input-bar-main {\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-wrap: wrap;\n  flex-wrap: wrap;\n  -ms-flex-positive: 1;\n  flex-grow: 1;\n}\n\n.input-bar-dropdown-icon {\n  -ms-flex-positive: 0;\n  flex-grow: 0;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-wrap: wrap;\n  flex-wrap: wrap;\n  -ms-flex-line-pack: center;\n  align-content: center;\n  margin: 0 10px 0 10px;\n}\n\n.dropdown {\n  border: 1px solid black;\n  position: absolute;\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n  width: 100%;\n  border-radius: 5px;\n  background-color: white;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-direction: column;\n  flex-direction: column;\n  overflow: hidden;\n  z-index: 1000000;\n}\n\n.search {\n  padding: 10px;\n  border: 0;\n  border-bottom: 1px solid black;\n}\n\n.dropdown > ul {\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-direction: column;\n  flex-direction: column;\n  max-height: 250px;\n  overflow-y: scroll;\n  overflow-x: hidden;\n}\n\n.dropdown > ul > li {\n  cursor: pointer;\n  padding: 10px;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-align: center;\n  align-items: center;\n  -ms-flex-wrap: nowrap;\n  flex-wrap: nowrap;\n}\n\n.dropdown > ul > li:hover {\n  background-color: #eee;\n}\n\n.dropdown > ul > li + li {\n  border-top: 1px solid black;\n}\n\n.bubble {\n  border: 1px solid black;\n  border-radius: 5px;\n  padding: 5px 10px 5px 10px;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-align: center;\n  align-items: center;\n  -ms-flex-wrap: nowrap;\n  flex-wrap: nowrap;\n  margin: 5px;\n  min-height: 22px;\n}\n\n.bubble-closeButton {\n  margin-left: 10px;\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-align: center;\n  align-items: center;\n  cursor: pointer;\n}\n\n#placeholderBubble {\n  color: grey;\n}\n\n#noOptionsListItem {\n  cursor: default;\n  color: grey;\n}\n\n.singleSelectInputBarItem {\n  display: -ms-flexbox;\n  display: flex;\n  -ms-flex-align: center;\n  align-items: center;\n  margin: 10px;\n}\n\n.singleSelectInputBarPlaceholder {\n  color: grey;\n}"; }
};

export { PwcChoicesDropdown as pwc_choices_dropdown };
