# All files findMatchIndex.ts

100% Statements 100/100
100% Branches 13/13
100% Functions 2/2
100% Lines 100/100

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    1011x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    57x
    57x
    1x
    1x
    56x
    56x
    56x
    57x
    221x
    221x
    39x
    39x
    221x
    17x
    17x
    17x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    38x
    38x
    38x
    3x
    3x
    35x
    35x
    35x
    35x
    35x
    35x
    35x
    38x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    14x
    35x
    35x
    35x
     /** @internal */
    export interface BaseOptions {
      /**
       * The current query string to find within the values
       */
      value: string;

      /**
       * The list of values to search within
       */
      values: readonly string[];

      /**
       * The start index for the search
       */
      startIndex: number;
    }

    /** @internal */
    export interface MatchInRangeOptions extends BaseOptions {
      /**
       * The end index for the search
       */
      endIndex: number;
    }

    /**
     * Attempts to find the first match index for a list of values that starts with
     * the provided query string and is within the start and end indexes. If no
     * matches are found, -1 will be returned instead.
     *
     * Since this is normally coming from a keydown event, the query *must* be a
     * string of all capital letters to work as each value will be converted to
     * uppercase before checking.
     * @internal
     */
    export function findMatchInRange(options: MatchInRangeOptions): number {
      const { values, startIndex, endIndex } = options;
      if (!values.length) {
        return -1;
      }

      const value = options.value.toUpperCase();

      for (let i = startIndex; i < endIndex; i += 1) {
        const content = values[i];
        if (content.toUpperCase().indexOf(value) === 0) {
          return i;
        }
      }

      return -1;
    }

    /** @internal */
    export interface MatchIndexOptions extends BaseOptions {
      /**
       * Boolean if the current index can be included in the search
       *
       * @defaultValue `true`
       */
      isSelfMatchable?: boolean;
    }

    /**
     * A function that is used to find the next match index within a list of values
     * by comparing the start values ignoring case.
     *
     * If a match can not be found from the search string, `-1` will be returned.
     * The search value is self-matchable by default, but it can be omitted by
     * disabling the `isSelfMatchable` argument. This will make a self-match return
     * `-1`.
     *
     * @internal
     */
    export function findMatchIndex(options: MatchIndexOptions): number {
      const { value, values, startIndex, isSelfMatchable = true } = options;
      // this was added to support comboboxes when there are no options available
      if (!values.length) {
        return -1;
      }

      let index = findMatchInRange({
        value,
        values,
        startIndex: startIndex + 1,
        endIndex: values.length,
      });
      if (index === -1) {
        const endIndex = startIndex + (isSelfMatchable ? 1 : 0);
        index = findMatchInRange({
          value,
          values,
          startIndex: 0,
          endIndex,
        });
      }

      return index;
    }