{"mappings":"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","sources":["packages/@react-spectrum/ai/src/PromptField.tsx"],"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\nimport {ActionButton} from '@react-spectrum/s2/ActionButton';\nimport Attach from '@react-spectrum/s2/icons/Attach';\nimport {Attachment, AttachmentList, AttachmentListProps} from './AttachmentList';\nimport {Autocomplete} from 'react-aria-components/Autocomplete';\nimport {\n  baseColor,\n  color,\n  css,\n  iconStyle,\n  style,\n  StyleString\n} from '@react-spectrum/s2/style' with {type: 'macro'};\nimport {Button} from '@react-spectrum/s2/Button';\nimport {Cell} from './loader/data';\nimport {CenterBaseline} from '@react-spectrum/s2/CenterBaseline';\nimport {\n  createContext,\n  createRef,\n  forwardRef,\n  use,\n  useContext,\n  useDeferredValue,\n  useEffect,\n  useMemo,\n  useRef,\n  useState\n} from 'react';\nimport {DOMRef} from '@react-types/shared';\nimport {IconContext} from '@react-spectrum/s2';\nimport {Image, Text} from '@react-spectrum/s2/Card';\nimport intlMessages from '../intl/*.json';\n// @ts-ignore\nimport {isFileDropItem, useDrop} from 'react-aria-components/useDrop';\nimport {Link} from '@react-spectrum/s2/Link';\nimport {Menu, MenuItem, MenuItemProps, MenuTrigger} from '@react-spectrum/s2/Menu';\nimport Microphone from '@react-spectrum/s2/icons/Microphone';\nimport {PixelLoader} from './loader/react';\nimport Plus from '@react-spectrum/s2/icons/Add';\nimport {Popover, PopoverProps} from '@react-spectrum/s2/Popover';\nimport {\n  Position,\n  TokenFieldSegment,\n  TokenFieldValue,\n  TokenSegment\n} from 'react-stately/useTokenFieldState';\nimport {PromptFieldContainer} from './PromptFieldContainer';\nimport {PromptFocusContext} from './Chat';\nimport Send from '@react-spectrum/s2/icons/ArrowUpSend';\nimport {setTokenFieldSelection} from 'react-aria/useTokenField';\nimport Stop from '@react-spectrum/s2/icons/StopProcessing';\nimport {ToggleButton} from '@react-spectrum/s2/ToggleButton';\nimport {\n  Token,\n  TokenField,\n  tokenFieldPositionToDOMRange,\n  TokenInput,\n  TokenProps\n} from 'react-aria-components/TokenField';\nimport {Tooltip, TooltipTrigger} from '@react-spectrum/s2/Tooltip';\nimport {useControlledState} from 'react-stately/useControlledState';\nimport {useDOMRef} from './useDOMRef';\nimport {useEffectEvent} from 'react-aria/private/utils/useEffectEvent';\nimport {useFocusWithin} from 'react-aria/useFocusWithin';\nimport {useKeyboard} from 'react-aria/useKeyboard';\nimport {useLocale} from 'react-aria/I18nProvider';\nimport {useLocalizedStringFormatter} from 'react-aria/useLocalizedStringFormatter';\nimport {useVoiceInput, VoiceInputErrorCode} from './useVoiceInput';\n\nexport interface PromptFieldAttachment {\n  id: string;\n  file: File;\n  image: string;\n}\n\nexport interface PromptFieldProps {\n  children: React.ReactNode;\n  acceptedAttachmentTypes?: string[];\n  value?: TokenFieldValue;\n  defaultValue?: TokenFieldValue;\n  onChange?: (value: TokenFieldValue) => void;\n  attachments?: PromptFieldAttachment[];\n  defaultAttachments?: PromptFieldAttachment[];\n  onAttachmentsChange?: (attachments: PromptFieldAttachment[]) => void;\n  onSubmit?: (prompt: TokenFieldValue, attachments: PromptFieldAttachment[]) => void;\n  isGenerating?: boolean;\n  onStop?: () => void;\n  onAddAttachments?: (attachments: PromptFieldAttachment[]) => void;\n  onRemoveAttachments?: (attachments: PromptFieldAttachment[]) => void;\n  styles?: StyleString;\n  variant?: 'balanced' | 'prominent' | 'subtle';\n  brandColor?: string;\n}\n\ninterface PromptFieldState {\n  attachments: PromptFieldAttachment[];\n  setAttachments: React.Dispatch<React.SetStateAction<PromptFieldAttachment[]>>;\n  acceptedAttachmentTypes?: string[];\n  prompt: TokenFieldValue;\n  setPrompt: React.Dispatch<React.SetStateAction<TokenFieldValue>>;\n  inputRef: React.RefObject<HTMLDivElement | null>;\n  onSubmit?: () => void;\n  onStop?: () => void;\n  isGenerating: boolean;\n  onAddAttachments?: (attachments: PromptFieldAttachment[]) => void;\n  onRemoveAttachments?: (attachments: PromptFieldAttachment[]) => void;\n  isListening: boolean;\n  setListening: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\n// TODO: make this customizable\nconst tokenRegex = /(?<=\\s|^)(https?:\\/\\/)?(www\\.)?([^/\\s]+\\.[a-z]{2,}(\\/\\S+)?)(?=\\s)/g;\nfunction tokenizeURLs(text: string): TokenFieldSegment[] {\n  if (text.length === 0) {\n    return [{type: 'text', text}];\n  }\n\n  tokenRegex.lastIndex = 0;\n\n  let match: RegExpExecArray | null = null;\n  let start = 0;\n  let segments: TokenFieldSegment[] = [];\n  while ((match = tokenRegex.exec(text))) {\n    if (match.index > start) {\n      segments.push({type: 'text', text: text.slice(start, match.index)});\n    }\n    segments.push({type: 'token', text: match[3], value: {type: 'url', url: match[0]}});\n    start = match.index + match[0].length;\n  }\n\n  if (start < text.length) {\n    segments.push({type: 'text', text: text.slice(start)});\n  }\n\n  return segments;\n}\n\nexport class PromptFieldValue extends TokenFieldValue {\n  tokenize(text: string): TokenFieldSegment[] {\n    return tokenizeURLs(text);\n  }\n}\n\nconst PromptFieldContext = createContext<PromptFieldState>({\n  attachments: [],\n  setAttachments: () => {},\n  prompt: new PromptFieldValue([]),\n  setPrompt: () => {},\n  inputRef: createRef(),\n  isGenerating: false,\n  isListening: false,\n  setListening: () => {}\n});\n\n// to communicate the anchor position to the menu items in the completion popover\n// need this so we can replace the inline filter text rather than inserting it at the current caret\n// aka the difference between a slash command and using the + menu which won't have filter text\nconst PromptCompletionAnchorContext = createContext<Position | null>(null);\n\nfunction matchMimeType(mimeType: string, acceptedMimeTypes: string[]): boolean {\n  return acceptedMimeTypes.some(type => {\n    if (type === '*/*') {\n      return true;\n    }\n    if (type.endsWith('/*')) {\n      return mimeType.startsWith(type.slice(0, -2));\n    }\n    return mimeType === type;\n  });\n}\n\nexport const PromptField = forwardRef(function PromptField(\n  props: PromptFieldProps,\n  ref: DOMRef<HTMLDivElement>\n) {\n  let {\n    children,\n    acceptedAttachmentTypes,\n    isGenerating,\n    onStop,\n    styles,\n    onAddAttachments,\n    onRemoveAttachments,\n    variant = 'balanced',\n    brandColor\n  } = props;\n  let domRef = useDOMRef(ref);\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n  let [prompt, setPrompt] = useControlledState(\n    props.value,\n    props.defaultValue ?? new PromptFieldValue([]),\n    props.onChange\n  );\n  let [attachments, setAttachments] = useControlledState(\n    props.attachments,\n    props.defaultAttachments ?? [],\n    props.onAttachmentsChange\n  );\n\n  // Not using RAC DropZone because it adds its own focusable button,\n  // and we want to avoid an extra tab. We support pasting files directly into the input.\n  let inputRef = useRef<HTMLDivElement>(null);\n  let {dropProps, isDropTarget} = useDrop({\n    ref: inputRef,\n    hasDropButton: true,\n    isDisabled: !acceptedAttachmentTypes,\n    getDropOperation(types) {\n      return acceptedAttachmentTypes && types.has(acceptedAttachmentTypes) ? 'copy' : 'cancel';\n    },\n    async onDrop(e) {\n      let files = await Promise.all(\n        e.items\n          .filter(isFileDropItem)\n          .filter(item => matchMimeType(item.type, acceptedAttachmentTypes!))\n          .map(async item => ({\n            id: crypto.randomUUID(),\n            file: await item.getFile(),\n            image: item.type.startsWith('image/') ? URL.createObjectURL(await item.getFile()) : ''\n          }))\n      );\n      onAddAttachments?.(files);\n      setAttachments(attachments => [...attachments, ...files]);\n    }\n  });\n\n  let [isListening, setListening] = useState(false);\n  let {onFocusChange} = useContext(PromptFocusContext);\n  let {focusWithinProps} = useFocusWithin({onFocusWithinChange: onFocusChange});\n\n  let isPromptControlled = props.value !== undefined;\n  let isAttachmentsControlled = props.attachments !== undefined;\n  let onSubmit = () => {\n    if (prompt.segments.length === 0) {\n      return;\n    }\n\n    props.onSubmit?.(prompt, attachments);\n    if (!isPromptControlled) {\n      setPrompt(new PromptFieldValue([]));\n    }\n    if (!isAttachmentsControlled) {\n      setAttachments([]);\n    }\n    inputRef.current?.focus();\n  };\n\n  return (\n    <PromptFieldContext.Provider\n      value={{\n        attachments,\n        setAttachments,\n        acceptedAttachmentTypes,\n        prompt,\n        setPrompt,\n        inputRef,\n        onSubmit,\n        isGenerating: isGenerating ?? false,\n        isListening,\n        setListening,\n        onStop,\n        onAddAttachments,\n        onRemoveAttachments\n      }}>\n      <div ref={domRef} {...focusWithinProps}>\n        <PromptFieldContainer\n          {...dropProps}\n          role=\"group\"\n          variant={variant}\n          brandColor={brandColor}\n          isGenerating={isGenerating ?? false}\n          isDropTarget={isDropTarget}\n          styles={styles}\n          inputRef={inputRef}>\n          {children}\n        </PromptFieldContainer>\n        <p className={style({font: 'ui-sm', textAlign: 'center'})}>\n          {stringFormatter.format('promptfield.aiDisclaimer')}{' '}\n          <Link\n            variant=\"secondary\"\n            href=\"https://www.adobe.com/legal/licenses-terms/adobe-gen-ai-user-guidelines.html\"\n            target=\"_blank\">\n            {stringFormatter.format('promptfield.aiUserGuidlines')}\n          </Link>\n        </p>\n      </div>\n    </PromptFieldContext.Provider>\n  );\n});\n\nexport interface PromptFieldAttachmentListProps extends AttachmentListProps<PromptFieldAttachment> {\n  children?: (attachment: PromptFieldAttachment) => React.ReactNode;\n}\n\nexport function PromptFieldAttachmentList(props: PromptFieldAttachmentListProps) {\n  let {children} = props;\n  let {attachments, setAttachments, onRemoveAttachments, inputRef} = useContext(PromptFieldContext);\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n  if (attachments.length === 0) {\n    return null;\n  }\n\n  return (\n    <AttachmentList\n      {...props}\n      aria-label={stringFormatter.format('promptfield.attachments')}\n      onRemove={keys => {\n        let removedAttachments = attachments.filter(attachment => keys.has(attachment.id));\n        onRemoveAttachments?.(removedAttachments);\n        setAttachments(attachments => attachments.filter(attachment => !keys.has(attachment.id)));\n        if (removedAttachments.length === attachments.length) {\n          inputRef.current?.focus();\n        }\n      }}\n      items={attachments}>\n      {children ||\n        (attachment => (\n          <Attachment>\n            {attachment.image && <Image src={attachment.image} slot=\"thumbnail\" />}\n          </Attachment>\n        ))}\n    </AttachmentList>\n  );\n}\n\nexport interface PromptTokenFieldProps {\n  completionTrigger?: RegExp;\n  renderCompletions?: (\n    filterValue: string\n  ) => React.ReactNode[] | null | Promise<React.ReactNode[] | null>;\n  children?: (segment: TokenSegment) => React.ReactElement;\n  pixelLoader?: Cell[] | Cell[][];\n  placeholder?: string;\n  onKeyDown?: (e: React.KeyboardEvent<HTMLDivElement>) => void;\n}\n\nexport function PromptTokenField(props: PromptTokenFieldProps) {\n  let {\n    completionTrigger,\n    renderCompletions,\n    children,\n    pixelLoader,\n    placeholder,\n    onKeyDown: onKeyDownProp\n  } = props;\n  let {keyboardProps} = useKeyboard({onKeyDown: onKeyDownProp});\n  let {\n    prompt,\n    setPrompt,\n    acceptedAttachmentTypes,\n    setAttachments,\n    onAddAttachments,\n    inputRef,\n    onSubmit,\n    isGenerating,\n    isListening\n  } = useContext(PromptFieldContext);\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n  let [isFocused, setFocused] = useState(false);\n\n  let [filterAnchor, filterValue] = useMemo(() => {\n    if (completionTrigger) {\n      let filterAnchor = prompt.findText(\n        prompt.caretPosition,\n        TokenFieldValue.Direction.Backward,\n        completionTrigger\n      );\n      if (filterAnchor != null) {\n        let filterValue = prompt.slice(filterAnchor, prompt.caretPosition).toString();\n        return [filterAnchor, filterValue];\n      }\n    }\n    return [null, null];\n  }, [completionTrigger, prompt]);\n\n  let items = useMemo(() => {\n    return filterValue != null ? renderCompletions?.(filterValue) : null;\n  }, [filterValue, renderCompletions]);\n\n  return (\n    <div\n      className={style({\n        display: 'flex',\n        gap: 12,\n        alignItems: 'baseline',\n        color: {\n          default: 'transparent-overlay-600',\n          isFocused: 'body'\n        },\n        transition: 'default',\n        transitionDuration: 350,\n        paddingStart: 4,\n        width: 'full'\n      })({isFocused: isFocused || prompt.segments.length > 0})}>\n      <CenterBaseline>\n        <PixelLoader isPlaying={isGenerating} icon={pixelLoader} />\n      </CenterBaseline>\n      <Autocomplete>\n        <TokenField\n          value={prompt}\n          onChange={setPrompt}\n          allowsNewlines\n          className={style({flexGrow: 1})}\n          aria-label={stringFormatter.format('promptfield.label')}\n          isReadOnly={isListening}\n          onSubmit={onSubmit}\n          onFocus={e => {\n            if (e.isTrusted) {\n              setFocused(true);\n            }\n          }}\n          onBlur={e => {\n            if (e.isTrusted) {\n              setFocused(false);\n            }\n          }}\n          onPaste={\n            acceptedAttachmentTypes\n              ? e => {\n                  let clipboardData = e.clipboardData as DataTransfer;\n                  let attachments: PromptFieldAttachment[] = [];\n                  for (let item of clipboardData.items) {\n                    if (matchMimeType(item.type, acceptedAttachmentTypes)) {\n                      let file = item.getAsFile()!;\n                      attachments.push({\n                        id: crypto.randomUUID(),\n                        file,\n                        image: file.type.startsWith('image/') ? URL.createObjectURL(file) : ''\n                      });\n                    }\n                  }\n                  if (attachments.length > 0) {\n                    onAddAttachments?.(attachments);\n                    setAttachments(prev => [...prev, ...attachments]);\n                  }\n                }\n              : undefined\n          }>\n          <TokenInput\n            {...keyboardProps}\n            data-placeholder={placeholder || stringFormatter.format('promptfield.placeholder')}\n            ref={inputRef}\n            className={renderProps =>\n              css('&:empty::before { content: attr(data-placeholder); }') +\n              style({\n                font: 'body',\n                color: {\n                  default: baseColor('neutral'),\n                  ':empty': {\n                    default: 'gray-600',\n                    forcedColors: 'GrayText'\n                  }\n                },\n                width: 'full',\n                outlineStyle: 'none',\n                cursor: 'text'\n              })(renderProps)\n            }>\n            {children || (segment => <PromptToken>{segment.text}</PromptToken>)}\n          </TokenInput>\n        </TokenField>\n        <PromptTokenFieldPopover\n          filterAnchor={filterAnchor}\n          items={useDeferredValue(items)}\n          isFocused={isFocused}\n        />\n      </Autocomplete>\n    </div>\n  );\n}\n\nexport interface PromptTokenFieldPopoverProps extends Omit<PopoverProps, 'shouldSkipAnimation'> {\n  filterAnchor?: Position | null;\n  items?: React.ReactNode[] | null | Promise<React.ReactNode[] | null>;\n  isFocused?: boolean;\n}\n\nfunction PromptTokenFieldPopover(props: PromptTokenFieldPopoverProps) {\n  let {filterAnchor, items, isFocused} = props;\n  let {inputRef} = useContext(PromptFieldContext);\n\n  let resolvedItems = items instanceof Promise ? use(items) : items;\n  let isOpen =\n    isFocused && filterAnchor != null && resolvedItems != null && resolvedItems.length > 0;\n\n  // Cache items so that popover content doesn't flicker to empty while animating out\n  let [menuItems, setMenuItems] = useState(resolvedItems);\n  if (resolvedItems !== menuItems && resolvedItems != null && resolvedItems.length > 0) {\n    setMenuItems(resolvedItems);\n  }\n\n  return (\n    <Popover\n      triggerRef={inputRef}\n      isOpen={isOpen}\n      isNonModal\n      hideArrow\n      placement=\"bottom start\"\n      getTargetRect={target => {\n        return tokenFieldPositionToDOMRange(target, filterAnchor!).getBoundingClientRect();\n      }}>\n      <PromptCompletionAnchorContext.Provider value={filterAnchor ?? null}>\n        <Menu>{menuItems}</Menu>\n      </PromptCompletionAnchorContext.Provider>\n    </Popover>\n  );\n}\n\nexport interface PromptTokenProps extends Omit<TokenProps, 'children' | 'render'> {\n  children: React.ReactNode;\n}\n\nexport function PromptToken(props: PromptTokenProps) {\n  return (\n    <Token\n      {...props}\n      className={style({\n        font: 'ui',\n        backgroundColor: {\n          default: 'transparent-overlay-1000/10',\n          isSelected: 'blue-800',\n          '::selection': 'transparent'\n        },\n        color: {\n          default: 'body',\n          isSelected: 'white'\n        },\n        outlineStyle: 'solid',\n        outlineWidth: 1,\n        outlineColor: 'transparent-overlay-1000/10',\n        outlineOffset: -1,\n        borderRadius: 'pill',\n        boxShadow: `[inset 0 24px 32px 0 ${color('transparent-white-50')}, 0 8px 32px 0 ${color('transparent-black-50')}]`,\n        paddingX: 8,\n        paddingY: 4,\n        lineHeight: '[1em]',\n        cursor: 'default',\n        '--iconPrimary': {\n          type: 'fill',\n          value: 'currentColor'\n        },\n        display: 'inline-flex',\n        alignItems: 'baseline',\n        gap: 4,\n        verticalAlign: 'baseline'\n      })}>\n      <IconContext.Provider\n        value={{\n          styles: iconStyle({size: 'XS'}),\n          render: icon => <CenterBaseline>{icon}</CenterBaseline>\n        }}>\n        {props.children}\n      </IconContext.Provider>\n    </Token>\n  );\n}\n\nexport interface PromptFieldToolbarProps {\n  children: React.ReactNode;\n}\n\nexport function PromptFieldToolbar(props: PromptFieldToolbarProps) {\n  let {children} = props;\n  return (\n    <div\n      className={style({\n        display: 'flex',\n        justifyContent: 'space-between',\n        alignItems: 'center',\n        marginTop: 16\n      })}>\n      {children}\n    </div>\n  );\n}\n\nexport interface PromptFieldSubmitButtonProps {}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport function PromptFieldSubmitButton(props: PromptFieldSubmitButtonProps) {\n  let {prompt, isGenerating, onSubmit, onStop} = useContext(PromptFieldContext);\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n  return (\n    <Button\n      variant=\"primary\"\n      staticColor=\"auto\"\n      // TODO: should it be possible to submit a prompt with only attachments?\n      isDisabled={prompt.segments.length === 0 && !isGenerating}\n      aria-label={\n        isGenerating\n          ? stringFormatter.format('promptfield.stopButton')\n          : stringFormatter.format('promptfield.submitButton')\n      }\n      onPress={isGenerating ? onStop : onSubmit}>\n      {isGenerating ? <Stop /> : <Send />}\n    </Button>\n  );\n}\n\nexport interface PromptFieldVoiceButtonProps {\n  lang?: string;\n  isDisabled?: boolean;\n  onError?: (code: VoiceInputErrorCode) => void;\n}\n\nexport function PromptFieldVoiceButton(props: PromptFieldVoiceButtonProps) {\n  let {lang: langProp, isDisabled: isDisabledProp, onError} = props;\n  let {locale} = useLocale();\n  let lang = langProp ?? locale;\n  let {prompt, setPrompt, inputRef, setListening} = useContext(PromptFieldContext);\n  let isDisabled = isDisabledProp;\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n\n  let basePromptRef = useRef<TokenFieldValue>(prompt);\n  let updateBasePrompt = useEffectEvent(() => {\n    basePromptRef.current = prompt;\n  });\n\n  let {\n    isSupported,\n    isListening: isVoiceListening,\n    transcript,\n    toggle,\n    stop\n  } = useVoiceInput({lang, onError, onListeningChange: setListening});\n\n  let restoreFocus = useEffectEvent(() => {\n    if (!inputRef.current) {\n      return;\n    }\n    // similar to useInsertPromptSegment, calling programatic focus on the input causes the caret positioning\n    // to be inaccurate\n    let finalPrompt = buildVoicePrompt(basePromptRef.current, transcript);\n    inputRef.current.focus();\n    setTokenFieldSelection(inputRef.current, finalPrompt.caretPosition, finalPrompt.caretPosition);\n    setPrompt(finalPrompt);\n  });\n\n  let wasListeningRef = useRef(false);\n  useEffect(() => {\n    if (isVoiceListening) {\n      updateBasePrompt();\n      wasListeningRef.current = true;\n    } else if (wasListeningRef.current) {\n      wasListeningRef.current = false;\n      restoreFocus();\n    }\n  }, [isVoiceListening]);\n\n  let applyVoiceTranscript = useEffectEvent(() => {\n    if (!transcript || !isVoiceListening) {\n      return;\n    }\n\n    setPrompt(buildVoicePrompt(basePromptRef.current, transcript));\n  });\n  useEffect(() => {\n    applyVoiceTranscript();\n  }, [transcript, isVoiceListening]);\n\n  useEffect(() => {\n    if (isDisabled && isVoiceListening) {\n      stop();\n    }\n  }, [isDisabled, isVoiceListening, stop]);\n\n  if (!isSupported) {\n    return null;\n  }\n\n  let label = isVoiceListening\n    ? stringFormatter.format('voicebutton.stopListening')\n    : stringFormatter.format('voicebutton.startListening');\n\n  return (\n    <TooltipTrigger>\n      <ToggleButton\n        staticColor=\"auto\"\n        isQuiet\n        isSelected={isVoiceListening}\n        isDisabled={isDisabled}\n        aria-label={label}\n        onPress={toggle}>\n        <Microphone />\n      </ToggleButton>\n      <Tooltip>{label}</Tooltip>\n    </TooltipTrigger>\n  );\n}\n\nfunction buildVoicePrompt(base: TokenFieldValue, voiceText: string): PromptFieldValue {\n  if (!voiceText) {\n    return base as PromptFieldValue;\n  }\n  return base.replaceRange(base.caretPosition, base.caretPosition, voiceText) as PromptFieldValue;\n}\n\nexport interface InsertMenuItemProps {\n  children: React.ReactNode;\n}\n\nexport function InsertMenuButton(props: InsertMenuItemProps) {\n  let {children} = props;\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/ai');\n  return (\n    <MenuTrigger>\n      <ActionButton\n        isQuiet\n        staticColor=\"auto\"\n        aria-label={stringFormatter.format('promptfield.insertButton')}>\n        <Plus />\n      </ActionButton>\n      <Menu>{children}</Menu>\n    </MenuTrigger>\n  );\n}\n\nexport function AttachFileMenuItem() {\n  let {acceptedAttachmentTypes, setAttachments, onAddAttachments} = useContext(PromptFieldContext);\n  return (\n    <MenuItem\n      onAction={() => {\n        let input = document.createElement('input');\n        input.type = 'file';\n        if (acceptedAttachmentTypes) {\n          input.accept = acceptedAttachmentTypes.join(',');\n        }\n        input.multiple = true;\n        input.onchange = e => {\n          let files = (e.currentTarget as HTMLInputElement).files;\n          if (files && acceptedAttachmentTypes) {\n            let attachments = Array.from(files)\n              .filter(file => matchMimeType(file.type, acceptedAttachmentTypes))\n              .map(file => ({\n                id: crypto.randomUUID(),\n                file,\n                image: file.type.startsWith('image/') ? URL.createObjectURL(file) : ''\n              }));\n            if (attachments.length > 0) {\n              onAddAttachments?.(attachments);\n              setAttachments(prev => [...prev, ...attachments]);\n            }\n          }\n        };\n        input.click();\n      }}>\n      <Attach />\n      <Text>Attach a file</Text>\n    </MenuItem>\n  );\n}\n\n// either replace the filter text (aka token replace) or insert value at current caret position (aka plain text inject)\nfunction useInsertPromptSegment(buildSegments: (item: any) => TokenFieldSegment[]) {\n  let {setPrompt, inputRef} = useContext(PromptFieldContext);\n  let anchor = useContext(PromptCompletionAnchorContext);\n  let pendingCaret = useRef<Position | null>(null);\n  return (item: any) => {\n    setPrompt(value => {\n      let newValue = value.replaceRangeWithSegments(\n        anchor ?? value.caretPosition,\n        value.caretPosition,\n        buildSegments(item),\n        false // Don't coalesce in undo/redo history.\n      );\n      pendingCaret.current = newValue.caretPosition;\n      return newValue;\n    });\n\n    if (anchor == null) {\n      // Wait for popover animation, then restore cursor to after the inserted content.\n      setTimeout(() => {\n        if (inputRef.current && pendingCaret.current) {\n          let position = pendingCaret.current;\n          pendingCaret.current = null;\n          inputRef.current.focus();\n          // we need to update the position manually since TokenField's update caret logic only happens if the field is focused\n          // but this insert can happen from the + menu aka the field isn't focused until this gets called which is too late\n          setTokenFieldSelection(inputRef.current, position, position);\n          // the above focus and setCursor call can cause the internally tracked caret position to be reset incorrectly\n          // seemingly due to TokenField's isProgrammaticSelectionChange being flipped to false by setCursor and thus reset to 0 by the .focus\n          // fix this by resetting to proper position below\n          // happens when injecting multiple tokens one after another via + menu\n          setPrompt(value => value.withCaretPosition(position));\n        }\n      }, 400);\n    }\n  };\n}\n\nexport interface InsertTokenMenuItemProps extends Omit<\n  MenuItemProps,\n  | 'UNSAFE_className'\n  | 'UNSAFE_style'\n  | 'download'\n  | 'href'\n  | 'hrefLang'\n  | 'ping'\n  | 'referrerPolicy'\n  | 'rel'\n  | 'routerOptions'\n  | 'target'\n> {}\n\nexport function InsertTokenMenuItem(props: InsertTokenMenuItemProps) {\n  let insert = useInsertPromptSegment(item => [\n    {type: 'token', text: 'command' in item ? item.command : item.title, value: item},\n    {type: 'text', text: ' '}\n  ]);\n\n  return (\n    <MenuItem\n      {...props}\n      onAction={() => {\n        insert(props.value);\n        props.onAction?.();\n      }}\n    />\n  );\n}\n\nexport interface InsertTextMenuItemProps extends Omit<\n  MenuItemProps,\n  | 'UNSAFE_className'\n  | 'UNSAFE_style'\n  | 'download'\n  | 'href'\n  | 'hrefLang'\n  | 'ping'\n  | 'referrerPolicy'\n  | 'rel'\n  | 'routerOptions'\n  | 'target'\n> {}\n\nexport function InsertTextMenuItem(props: InsertTextMenuItemProps) {\n  let insert = useInsertPromptSegment(item => [\n    {type: 'text', text: `${'command' in item ? item.command : item.title} `}\n  ]);\n\n  return (\n    <MenuItem\n      {...props}\n      onAction={() => {\n        insert(props.value);\n        props.onAction?.();\n      }}\n    />\n  );\n}\n\nexport interface CommandMenuItemProps extends Omit<\n  MenuItemProps,\n  | 'UNSAFE_className'\n  | 'UNSAFE_style'\n  | 'download'\n  | 'href'\n  | 'hrefLang'\n  | 'ping'\n  | 'referrerPolicy'\n  | 'rel'\n  | 'routerOptions'\n  | 'target'\n> {}\n// specifically for menu items that only trigger a callback in the autocomplete menu\n// since they dont end up inserting a token or text, we need to clear the partial text that the user used\n// to filter the menu\nexport function CommandMenuItem(props: CommandMenuItemProps) {\n  let insert = useInsertPromptSegment(() => []);\n  return (\n    <MenuItem\n      {...props}\n      onAction={() => {\n        insert(undefined);\n        props.onAction?.();\n      }}\n    />\n  );\n}\n"],"names":[],"version":3,"file":"PromptField.cjs.map"}