# All files / src/movement findMatchIndex.ts

98% Statements 98/100
91.66% Branches 11/12
100% Functions 2/2
98% Lines 98/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
    75x
    75x

    75x
    75x
    75x
    75x
    244x
    244x
    54x
    54x
    244x
    21x
    21x
    21x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    53x
    53x
    53x
    3x
    3x
    50x
    50x
    50x
    50x
    50x
    50x
    50x
    53x
    18x
    18x
    18x
    18x
    18x
    18x
    18x
    18x
    50x
    50x
    50x
     /** @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;
    }