{"version":3,"file":"prompt-input-mentions.cjs","sources":["../../../components/prompt-input/prompt-input-mentions.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode, useEffect, useRef } from 'react';\nimport { isTriggerCharacter } from '../editor/mention';\nimport { usePromptInputContext } from './prompt-input-context';\nimport type {\n  PromptInputMentionItem,\n  PromptInputMentionRef\n} from './prompt-input-mention-registry';\n\nexport interface PromptInputMentionsProps {\n  /**\n   * The character that opens the menu.\n   * @defaultValue \"@\"\n   */\n  trigger?: string;\n  /** Sync data — filtered internally with match-sorter on the label. */\n  items?: PromptInputMentionItem[];\n  /**\n   * Async data — debounced ~150 ms, superseded requests aborted through\n   * `signal`, stale resolutions discarded. Wins over `items`.\n   */\n  onSearch?: (\n    query: string,\n    context: { trigger: string; signal: AbortSignal }\n  ) => Promise<PromptInputMentionItem[]>;\n  /**\n   * Fills in the icon, trailing content, `data` and a fresh label for chips\n   * parsed out of `value` / `defaultValue`, which cannot carry them. Batched\n   * into one call per trigger and cached by `trigger|type|id`.\n   */\n  resolveMentions?: (\n    refs: PromptInputMentionRef[]\n  ) => Promise<PromptInputMentionItem[]>;\n  /** Observes the menu's open state. */\n  onOpenChange?: (open: boolean) => void;\n  /**\n   * Empty-state content.\n   * @defaultValue \"No results\"\n   */\n  emptyMessage?: ReactNode;\n  /**\n   * Skeleton rows shown while `onSearch` is in flight.\n   * @defaultValue 3\n   */\n  loadingRowCount?: number;\n}\n\n/**\n * Declares a trigger and supplies its data. Renders nothing itself — the\n * caret-anchored menu belongs to `PromptInput.Editor`, which owns the document\n * the query lives in, because the query is the text the chip replaces.\n *\n * Requires `PromptInput.Editor`: next to a `Textarea` it no-ops and warns in\n * development, since a native textarea cannot host inline chips.\n */\nexport function PromptInputMentions({\n  trigger = '@',\n  items,\n  onSearch,\n  resolveMentions,\n  onOpenChange,\n  emptyMessage,\n  loadingRowCount\n}: PromptInputMentionsProps) {\n  const context = usePromptInputContext('Mentions');\n  const registry = context.mentions;\n  const editorMounted = context.editorMounted;\n\n  if (process.env.NODE_ENV !== 'production' && !isTriggerCharacter(trigger)) {\n    console.warn(\n      `[Apsara] PromptInput.Mentions trigger ${JSON.stringify(trigger)} is not ` +\n        'a single punctuation character, so a chip picked from it cannot ' +\n        'round-trip through the markup dialect. Use \"@\", \"/\", \"#\" or similar.'\n    );\n  }\n\n  useEffect(() => {\n    if (\n      process.env.NODE_ENV !== 'production' &&\n      registry.triggers().length > 0 &&\n      !registry.get(trigger)\n    ) {\n      console.warn(\n        '[Apsara] PromptInput accepts one <PromptInput.Mentions> in this ' +\n          'release. Additional triggers register and work, but only the first ' +\n          'is covered by the test suite.'\n      );\n    }\n\n    return registry.register(trigger);\n  }, [registry, trigger]);\n\n  // `Editor` registers itself during the commit that mounts it, which can land\n  // after this effect — so the check waits for the tree to settle, and the\n  // cleanup cancels it the moment an editor does show up.\n  const sawEditorRef = useRef(false);\n  useEffect(() => {\n    if (editorMounted) {\n      sawEditorRef.current = true;\n      return;\n    }\n    if (process.env.NODE_ENV === 'production' || sawEditorRef.current) return;\n    const timer = setTimeout(() => {\n      if (sawEditorRef.current) return;\n      console.warn(\n        '[Apsara] PromptInput.Mentions requires <PromptInput.Editor>; a ' +\n          'native <textarea> cannot host inline chips, so it does nothing ' +\n          'next to <PromptInput.Textarea>.'\n      );\n    }, 0);\n    return () => clearTimeout(timer);\n  }, [editorMounted]);\n\n  // Pushed after every render and compared field by field, so an inline `items`\n  // array or an inline `onSearch` stays live without churning the config\n  // identity — which would restart an in-flight debounce on every keystroke.\n  useEffect(() => {\n    registry.setData(trigger, {\n      items,\n      onSearch,\n      resolveMentions,\n      onOpenChange,\n      emptyMessage,\n      loadingRowCount\n    });\n  });\n\n  return null;\n}\n\nPromptInputMentions.displayName = 'PromptInput.Mentions';\n"],"names":[],"mappings":";;;;;;;AAgDA;;;;;;;AAOG;;AAUD;AACA;AACA;AAEA;;;AAIM;;;AAKJ;AAEE;AACA;;;AAKI;;AAIN;AACF;;;;AAKA;;;AAGI;;;;;AAIF;;;;;AAKM;;AAGN;AACF;;;;;AAME;;;;;;;AAOC;AACH;AAEA;AACF;AAEA;;"}