{"mappings":"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","sources":["packages/react-stately/src/tokenfield/TokenFieldValue.ts"],"sourcesContent":["/*\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport type TokenFieldSegment<T = any> = TextSegment | TokenSegment<T>;\n\nexport interface TextSegment {\n  type: 'text';\n  text: string;\n}\n\nexport interface TokenSegment<T = any> {\n  type: 'token';\n  text: string;\n  /** An arbitrary value associated with the token. */\n  value?: T;\n}\n\nexport interface Position {\n  /** Index of the segment in the list. */\n  index: number;\n  /** Text offset within the segment in UTF-16 code units. */\n  offset: number;\n}\n\n/** Represents a text selection in a TokenField. */\nexport class SelectedRange {\n  /** The anchor position. */\n  anchor: Position;\n  /** The current (i.e. caret) position. */\n  current: Position;\n\n  /**\n   * Creates a new selection range. If only a single position is provided, the selection is\n   * collapsed.\n   */\n  constructor(anchor: Position, current: Position = anchor) {\n    this.anchor = anchor;\n    this.current = current;\n  }\n\n  /** Whether the selection is collapsed to a single caret position. */\n  get isCollapsed() {\n    return this.anchor.index === this.current.index && this.anchor.offset === this.current.offset;\n  }\n\n  /** The side of the selection closest to the start of the value. */\n  get start() {\n    return compare(this.anchor, this.current) < 0 ? this.anchor : this.current;\n  }\n\n  /** The side of the selection closest to the end of the value. */\n  get end() {\n    return compare(this.anchor, this.current) < 0 ? this.current : this.anchor;\n  }\n\n  /** Returns whether this selection is equal to another. */\n  isEqual(other: SelectedRange) {\n    if (this === other) {\n      return true;\n    }\n    return (\n      this.anchor.index === other.anchor.index &&\n      this.anchor.offset === other.anchor.offset &&\n      this.current.index === other.current.index &&\n      this.current.offset === other.current.offset\n    );\n  }\n}\n\nfunction compare(a: Position, b: Position) {\n  if (a.index === b.index) {\n    return a.offset - b.offset;\n  }\n\n  return a.index - b.index;\n}\n\nenum Direction {\n  Forward = 1,\n  Backward = -1\n}\n\nexport interface TokenFieldValueOptions {\n  selectedRange?: SelectedRange | null;\n}\n\n/**\n * A list of segments containing editable text and non-editable tokens.\n */\nexport class TokenFieldValue<T = any> {\n  static readonly Direction = Direction;\n  static readonly SelectedRange = SelectedRange;\n\n  /** The text and token segments in the list. */\n  readonly segments: readonly TokenFieldSegment<T>[];\n  /** The selected range. */\n  selectedRange: SelectedRange;\n  // Linked list representing the undo/redo history.\n  private previous: this | null = null;\n  private next: this | null = null;\n  private isCoalescing = true;\n\n  /** Create a new list with the given segments. */\n  constructor(tokens: readonly TokenFieldSegment<T>[], options?: TokenFieldValueOptions) {\n    this.segments = tokens;\n    this.selectedRange = options?.selectedRange ?? new SelectedRange({index: 0, offset: 0});\n  }\n\n  protected createFieldValue(segments: readonly TokenFieldSegment<T>[]): this {\n    const Constructor = this.constructor as new (\n      segments: readonly TokenFieldSegment<T>[],\n      options?: TokenFieldValueOptions\n    ) => this;\n    return new Constructor(segments);\n  }\n\n  get caretPosition(): Position {\n    return this.selectedRange.current;\n  }\n\n  /** Create a new list with the caret position set to the given position. */\n  withSelectedRange(selectedRange: SelectedRange): this {\n    if (this.selectedRange.isEqual(selectedRange)) {\n      return this;\n    }\n\n    let result = this.createFieldValue(this.segments);\n    result.selectedRange = selectedRange;\n    result.previous = this.previous;\n    result.next = this.next;\n    result.isCoalescing = this.isCoalescing;\n    return result;\n  }\n\n  withCaretPosition(position: Position): this {\n    return this.withSelectedRange(new SelectedRange(position));\n  }\n\n  private splitSegment(\n    segment: TokenFieldSegment | undefined,\n    offset: number\n  ): [TokenFieldSegment | null, TokenFieldSegment | null] {\n    if (!segment) {\n      let empty = this.createTextSegment('');\n      return [offset > 0 ? empty : null, offset > 0 ? null : empty];\n    }\n\n    if (segment.type === 'token') {\n      return [offset > 0 ? {...segment} : null, offset > 0 ? null : {...segment}];\n    }\n\n    return [\n      offset > 0 ? {type: 'text', text: segment.text.slice(0, offset)} : null,\n      offset < segment.text.length ? this.createTextSegment(segment.text.slice(offset)) : null\n    ];\n  }\n\n  private createTextSegment(text: string): TextSegment {\n    return {type: 'text', text};\n  }\n\n  protected tokenize(text: string): TokenFieldSegment<T>[] {\n    return [this.createTextSegment(text)];\n  }\n\n  private clampPosition(position: Position): Position {\n    if (this.segments.length > 0 && position.index >= this.segments.length) {\n      return {\n        index: this.segments.length - 1,\n        offset: this.segments[this.segments.length - 1].text.length\n      };\n    }\n\n    if (position.index < 0) {\n      return {index: 0, offset: 0};\n    }\n    return position;\n  }\n\n  /** Replace the text between two positions with new text. */\n  replaceRange(start: Position, end: Position, text: string, coalesce = true): this {\n    return this.replaceRangeWithSegments(\n      start,\n      end,\n      text.length > 0 ? [this.createTextSegment(text)] : [],\n      coalesce\n    );\n  }\n\n  /** Replace the text between two positions with new segments. */\n  replaceRangeWithSegments(\n    start: Position,\n    end: Position,\n    insert: TokenFieldSegment<T>[],\n    coalesce = true\n  ): this {\n    start = this.clampPosition(start);\n    end = this.clampPosition(end);\n    let startSegment = this.segments[start.index];\n    let endSegment = this.segments[end.index];\n    let [startSplit] = this.splitSegment(startSegment, start.offset);\n    let [, endSplit] = this.splitSegment(endSegment, end.offset);\n\n    let newSegments = this.segments.slice(0, start.index);\n    if (startSplit) {\n      appendSegments(newSegments, [startSplit]);\n    }\n\n    if (insert.length) {\n      appendSegments(newSegments, insert, text => this.tokenize(text));\n    }\n\n    let lastSegment = newSegments[newSegments.length - 1];\n    let lastIsText = lastSegment && lastSegment.type === 'text';\n    let caret = {\n      index: lastIsText ? newSegments.length - 1 : newSegments.length,\n      offset: lastIsText ? lastSegment.text.length : 0\n    };\n\n    if (endSplit) {\n      appendSegments(newSegments, [endSplit]);\n    }\n\n    appendSegments(newSegments, this.segments.slice(end.index + 1));\n\n    let segments = this.createFieldValue(newSegments);\n    segments.selectedRange = new SelectedRange(caret);\n    segments.isCoalescing = coalesce;\n    if (this.isCoalescing && coalesce && this.previous) {\n      segments.previous = this.previous;\n      segments.previous.next = segments;\n    } else {\n      segments.previous = this;\n      this.selectedRange = new SelectedRange(start, end);\n      this.next = segments;\n    }\n    return segments;\n  }\n\n  /** Find the boundary before or after a position using an Intl.Segmenter. */\n  findBoundaryWithSegmenter(\n    position: Position,\n    segmenter: Intl.Segmenter,\n    direction: Direction\n  ): Position | null {\n    position = this.clampPosition(position);\n    for (let i = position.index; i >= 0 && i < this.segments.length; i += direction) {\n      let segment = this.segments[i];\n      switch (segment.type) {\n        case 'token':\n          if (\n            i !== position.index ||\n            (direction === Direction.Backward ? position.offset > 0 : position.offset === 0)\n          ) {\n            let index = i + direction;\n            return {\n              index: index >= 0 ? index : 0,\n              offset:\n                direction === Direction.Backward && index >= 0\n                  ? this.segments[index].text.length\n                  : 0\n            };\n          }\n          continue;\n        case 'text': {\n          let offset = direction === Direction.Backward ? segment.text.length : 0;\n          if (i === position.index) {\n            offset = position.offset;\n          }\n          if (direction === Direction.Backward) {\n            offset--;\n          }\n          if (offset < 0 || offset >= segment.text.length) {\n            continue;\n          }\n\n          let part = segmenter.segment(segment.text).containing(offset);\n          while (part && part.isWordLike === false) {\n            offset += direction;\n            part = segmenter.segment(segment.text).containing(offset);\n          }\n\n          if (part) {\n            return {\n              index: i,\n              offset:\n                direction === Direction.Backward ? part.index : part.index + part.segment.length\n            };\n          }\n          continue;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  /** Find a line boundary before or after a position. */\n  findLineBoundary(position: Position, direction: Direction): Position | null {\n    let res = this.findText(position, direction, '\\n');\n    if (res) {\n      return res;\n    }\n    return direction === Direction.Backward\n      ? {index: 0, offset: 0}\n      : {\n          index: this.segments.length - 1,\n          offset: this.segments[this.segments.length - 1].text.length\n        };\n  }\n\n  /** Find a string or regular expression match before or after a position. */\n  findText(position: Position, direction: Direction, search: string | RegExp): Position | null {\n    if (this.segments.length === 0) {\n      return null;\n    }\n\n    for (let i = position.index; i >= 0 && i < this.segments.length; i += direction) {\n      let segment = this.segments[i];\n      if (segment.type !== 'text') {\n        continue;\n      }\n      let offset = findInText(\n        segment.text,\n        search,\n        direction,\n        i === position.index ? position.offset : undefined\n      );\n      if (offset >= 0) {\n        return {\n          index: i,\n          offset: offset\n        };\n      }\n    }\n\n    return null;\n  }\n\n  /** Delete text at a position using a segmenter. */\n  delete(\n    position: Position,\n    segmenter: Intl.Segmenter,\n    direction: Direction,\n    coalesce = true\n  ): this {\n    let boundary = this.findBoundaryWithSegmenter(position, segmenter, direction);\n    if (boundary) {\n      return this.replaceRange(\n        direction === Direction.Backward ? boundary : position,\n        direction === Direction.Backward ? position : boundary,\n        '',\n        coalesce\n      );\n    }\n\n    return this.withSelectedRange(new SelectedRange(position));\n  }\n\n  /** Delete text to the next or previous line break. */\n  deleteLine(position: Position, direction: Direction, coalesce = true): this {\n    if (this.segments.length === 0) {\n      return this;\n    }\n\n    let boundary = this.findLineBoundary(position, direction);\n    if (boundary) {\n      return this.replaceRange(\n        direction === Direction.Backward ? boundary : position,\n        direction === Direction.Backward ? position : boundary,\n        '',\n        coalesce\n      );\n    }\n\n    return this.withSelectedRange(new SelectedRange(position));\n  }\n\n  /** Create a new list containing a subset of the segments. */\n  slice(start: Position, end: Position): this {\n    start = this.clampPosition(start);\n    end = this.clampPosition(end);\n    if (start.index === end.index && start.offset === end.offset) {\n      return this.createFieldValue([]);\n    }\n    if (start.index === end.index) {\n      let segment = this.segments[start.index];\n      if (segment.type === 'text') {\n        return this.createFieldValue([\n          {type: 'text', text: segment.text.slice(start.offset, end.offset)}\n        ]);\n      }\n      return this.createFieldValue([segment]);\n    }\n    let startSegment = this.segments[start.index];\n    let endSegment = this.segments[end.index];\n    let [, startSplit] = this.splitSegment(startSegment, start.offset);\n    let [endSplit] = this.splitSegment(endSegment, end.offset);\n\n    let result: TokenFieldSegment<T>[] = [];\n    if (startSplit) {\n      result.push(startSplit);\n    }\n    result.push(...this.segments.slice(start.index + 1, end.index));\n    if (endSplit) {\n      result.push(endSplit);\n    }\n    return this.createFieldValue(result);\n  }\n\n  /** Convert the list to a string. */\n  toString(): string {\n    return this.segments.map(seg => seg.text).join('');\n  }\n\n  /** Returns the previous list in the undo history. */\n  undo(): this {\n    return this.previous ?? this;\n  }\n\n  /** Returns the next list in the redo history. */\n  redo(): this {\n    return this.next ?? this;\n  }\n\n  /** End coalescing undo/redo history. */\n  endCoalescing(): void {\n    this.isCoalescing = false;\n  }\n}\n\nfunction findInText(\n  text: string,\n  search: string | RegExp,\n  direction: Direction,\n  fromOffset?: number\n): number {\n  if (typeof search === 'string') {\n    if (direction === Direction.Backward) {\n      return text.lastIndexOf(search, fromOffset !== undefined ? fromOffset - 1 : text.length - 1);\n    }\n    return text.indexOf(search, fromOffset ?? 0);\n  }\n\n  if (direction === Direction.Forward) {\n    let start = fromOffset ?? 0;\n    let index = text.slice(start).search(search);\n    return index >= 0 ? start + index : -1;\n  }\n\n  let limit = fromOffset !== undefined ? fromOffset : text.length;\n  if (limit < 0) {\n    return -1;\n  }\n\n  let re = search.flags.includes('g') ? search : new RegExp(search.source, search.flags + 'g');\n  let matches = Array.from(text.slice(0, limit).matchAll(re));\n  return matches.at(-1)?.index ?? -1;\n}\n\nfunction appendSegments(\n  segments: TokenFieldSegment[],\n  insert: TokenFieldSegment[],\n  tokenize?: (text: string) => TokenFieldSegment[]\n): TokenFieldSegment[] {\n  for (let segment of insert) {\n    if (segment.type === 'text' && segment.text.length === 0) {\n      continue;\n    }\n\n    let last = segments[segments.length - 1];\n    if (last && last.type === 'text' && segment.type === 'text') {\n      if (tokenize) {\n        let tokenized = tokenize(last.text + segment.text);\n        segments.splice(segments.length - 1, 1, ...tokenized);\n      } else {\n        segments[segments.length - 1] = {type: 'text', text: last.text + segment.text};\n      }\n    } else if (tokenize && segment.type === 'text') {\n      let tokenized = tokenize(segment.text);\n      segments.push(...tokenized);\n    } else {\n      segments.push(segment);\n    }\n  }\n  return segments;\n}\n"],"names":[],"version":3,"file":"TokenFieldValue.cjs.map"}