@magicx-eng/ai-autocomplete-react 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AIAutocomplete.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocomplete.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocompleteDropdown.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionGrid.module.css.js","../src/components/SuggestionItem.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionGrid.tsx","../src/AIAutocompleteDropdown.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/PillList.module.css.js","../src/components/PillList.tsx","../src/hooks/useAIAutocomplete.ts","../src/utils/filtering.ts","../src/utils/segments.ts","../src/hooks/useAutocompleteFetch.ts","../src/utils/api.ts","../src/utils/buildQuery.ts","../src/utils/overrides.ts","../src/hooks/useAutocompleteKeyboard.ts","../src/hooks/useAutocompletePills.ts"],"sourcesContent":["export { AIAutocomplete } from \"./AIAutocomplete\";\nexport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nexport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nexport type {\n AIAutocompleteDropdownProps,\n AIAutocompleteHandle,\n AIAutocompleteProps,\n APIConfig,\n AutocompleteResult,\n CompletedParam,\n CompletedParamState,\n OptionOverrides,\n Segment,\n Suggestion,\n SuggestionOption,\n TaskKind,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"./types\";\n","import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from \"react\";\nimport styles from \"./AIAutocomplete.module.css\";\nimport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nimport { PillList } from \"./components/PillList\";\nimport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nimport type { AIAutocompleteHandle, AIAutocompleteProps, AutocompleteResult } from \"./types\";\nimport { buildQuery } from \"./utils/buildQuery\";\n\nexport const AIAutocomplete = forwardRef<AIAutocompleteHandle, AIAutocompleteProps>(\n function AIAutocomplete(\n {\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n className,\n apiConfig,\n columns,\n typewriterEffect = true,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n },\n ref,\n ) {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n // Render-phase ref assignment — matches the pattern in useAIAutocomplete.ts\n const handleSubmitRef = useRef<(result: AutocompleteResult) => void>(() => {});\n const [revealCount, setRevealCount] = useState(0);\n const revealTimerRef = useRef<number | undefined>(undefined);\n\n useEffect(() => {\n textareaRef.current?.focus();\n return () => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n };\n }, []);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\n newParamId,\n clearNewParamId,\n inputProps,\n dropdownProps,\n reset,\n } = useAIAutocomplete({\n onSubmit: (result) => handleSubmitRef.current(result),\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n apiConfig,\n columns,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\n\n // Typewriter reveal for newly added param\n useEffect(() => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n if (!newParamId) {\n setRevealCount(0);\n return;\n }\n const param = completedParams.find((p) => p.id === newParamId);\n if (!param) return;\n const totalChars = param.text.length;\n\n if (!typewriterEffect) {\n // No typewriter — reveal all at once, shimmer sweep plays via CSS animation\n setRevealCount(totalChars);\n const timeoutId = window.setTimeout(() => clearNewParamId(), 650);\n return () => window.clearTimeout(timeoutId);\n }\n\n setRevealCount(0);\n const startTime = performance.now();\n const duration = 300;\n const tick = () => {\n const elapsed = performance.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const chars = Math.ceil(progress * totalChars);\n setRevealCount(chars);\n if (chars < totalChars) {\n revealTimerRef.current = requestAnimationFrame(tick);\n } else {\n // Defer cleanup to next frame to avoid a flash\n revealTimerRef.current = requestAnimationFrame(() => {\n clearNewParamId();\n });\n }\n };\n revealTimerRef.current = requestAnimationFrame(tick);\n return () => {\n if (revealTimerRef.current) cancelAnimationFrame(revealTimerRef.current);\n };\n }, [newParamId, completedParams, clearNewParamId, typewriterEffect]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => textareaRef.current?.focus(),\n reset,\n }),\n [reset],\n );\n\n const handleContainerClick = () => {\n textareaRef.current?.focus();\n };\n\n const canSubmit = !!inputProps.value || completedParams.length > 0;\n\n const handleSubmit = useCallback(() => {\n if (!canSubmit) return;\n const { rawQuery, completedParams: finalParams } = buildQuery(\n inputProps.value,\n completedParams,\n );\n onSubmit({\n query: inputProps.value.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n reset();\n }, [canSubmit, inputProps.value, completedParams, onSubmit, reset]);\n\n handleSubmitRef.current = handleSubmit;\n\n const { onChange, placeholder: inputPlaceholder, ...restProps } = inputProps;\n const isEmpty = !inputProps.value;\n\n return (\n <div className={`${styles.container} ${className ?? \"\"}`}>\n <AIAutocompleteDropdown {...dropdownProps} />\n {/* biome-ignore lint/a11y/useKeyWithClickEvents: container click delegates to textarea focus */}\n {/* biome-ignore lint/a11y/noStaticElementInteractions: wrapper delegates focus to textarea */}\n <div className={styles.inputWrapper} onClick={handleContainerClick}>\n <div className={styles.editorArea}>\n <div className={styles.sizerContent} aria-hidden=\"true\">\n {isEmpty && inputPlaceholder ? (\n <span className={styles.placeholderText}>{inputPlaceholder} </span>\n ) : (\n <span\n className={`${styles.sizerText} ${newParamId ? styles.sizerTextVisible : \"\"}`}\n >\n {segments.map((seg, i) => {\n const isNew = seg.type === \"completed\" && seg.param.id === newParamId;\n if (isNew) {\n if (!typewriterEffect) {\n // No typewriter — show all text, CSS animation handles the sweep\n const cls = `${styles.shimmerRevealed} ${styles.shimmerSweep}`;\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`} className={cls}>\n {seg.value}\n </span>\n );\n }\n const total = seg.value.length;\n const revealed = seg.value.slice(0, revealCount);\n const hidden = seg.value.slice(revealCount);\n const progress = total > 0 ? revealCount / total : 0;\n const bgPos = `${100 - progress * 100}% 0`;\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`} className={styles.shimmer}>\n <span\n className={styles.shimmerRevealed}\n style={{ backgroundPosition: bgPos }}\n >\n {revealed}\n </span>\n <span className={styles.shimmerHidden}>{hidden}</span>\n </span>\n );\n }\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\n );\n })}\n {segments.length === 0 && \"\\u00A0\"}\n </span>\n )}\n {\" \"}\n <PillList pills={suggestionPills} activePillIndex={0} onSelectPill={setActivePill} />\n </div>\n <textarea\n ref={textareaRef}\n className={`${styles.textarea} ${newParamId ? styles.textareaHidden : \"\"}`}\n rows={1}\n onChange={onChange}\n {...restProps}\n />\n </div>\n <button\n type=\"button\"\n className={styles.submitButton}\n disabled={!canSubmit}\n onClick={(e) => {\n e.stopPropagation();\n handleSubmit();\n }}\n aria-label=\"Submit\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n role=\"img\"\n aria-label=\"Submit\"\n >\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n );\n },\n);\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-cc65f4cc\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-cc65f4cc\";\n s.textContent = `.AIAutocomplete-module_container_KKjFU {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.AIAutocomplete-module_inputWrapper_FLq1b {\n min-height: 60px;\n padding: 24px;\n border: 1px solid var(--ac-color-border-default, #9ea5b2);\n border-radius: 23px;\n background: transparent;\n overflow: hidden;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.AIAutocomplete-module_editorArea_7rBWq {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.AIAutocomplete-module_sizerContent_DQgmV {\n position: relative;\n z-index: 1;\n pointer-events: none;\n min-height: 60px;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n}\n\n.AIAutocomplete-module_sizerText_iZIMK {\n color: transparent;\n}\n\n.AIAutocomplete-module_sizerTextVisible_HR-5h {\n color: var(--ac-color-text-default, #fff);\n}\n\n.AIAutocomplete-module_textareaHidden_UayJt {\n color: transparent !important;\n}\n\n.AIAutocomplete-module_placeholderText_K3ayy {\n color: var(--ac-color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.AIAutocomplete-module_textarea_eyn6A {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--ac-color-text-default, #fff);\n caret-color: var(--ac-color-text-default, #fff);\n font-family: inherit;\n font-size: 19px;\n line-height: 38px;\n white-space: pre-wrap;\n word-break: break-word;\n outline: none;\n resize: none;\n overflow: hidden;\n}\n\n.AIAutocomplete-module_textarea_eyn6A::placeholder {\n color: var(--ac-color-text-muted, #c1c4cb);\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: var(--ac-color-text-default, #fff);\n color: var(--ac-color-bg-default, #000);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: opacity 0.2s ease;\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi:hover {\n opacity: 0.85;\n}\n\n/* Text shimmer on newly added completed param.\n The sizer sits above the textarea (z-index: 1). Normally sizer text is\n transparent and the textarea shows the real text. During the shimmer, we\n make this span visible with a moving gradient clipped to the text shape,\n so the shimmer renders on top of the textarea's static white text. */\n\n.AIAutocomplete-module_shimmer_13AnY {\n position: relative;\n z-index: 2;\n display: inline;\n}\n\n.AIAutocomplete-module_shimmerRevealed_RR8dp {\n color: transparent;\n background: linear-gradient(\n 120deg,\n var(--ac-color-text-default, #fff) 0%,\n var(--ac-color-text-default, #fff) 44%,\n #b0b0b0 48%,\n #b0b0b0 52%,\n var(--ac-color-text-default, #fff) 56%,\n var(--ac-color-text-default, #fff) 100%\n );\n background-size: 200% 100%;\n -webkit-background-clip: text;\n background-clip: text;\n}\n\n.AIAutocomplete-module_shimmerSweep_ARCon {\n animation: AIAutocomplete-module_textShimmer_eCLdq 650ms ease-out forwards;\n}\n\n@keyframes AIAutocomplete-module_textShimmer_eCLdq {\n 0% {\n background-position: 100% 0;\n }\n 100% {\n background-position: -50% 0;\n }\n}\n\n.AIAutocomplete-module_shimmerHidden_45-Pf {\n color: transparent !important;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"container\":\"AIAutocomplete-module_container_KKjFU\",\"inputWrapper\":\"AIAutocomplete-module_inputWrapper_FLq1b\",\"editorArea\":\"AIAutocomplete-module_editorArea_7rBWq\",\"sizerContent\":\"AIAutocomplete-module_sizerContent_DQgmV\",\"sizerText\":\"AIAutocomplete-module_sizerText_iZIMK\",\"sizerTextVisible\":\"AIAutocomplete-module_sizerTextVisible_HR-5h\",\"textareaHidden\":\"AIAutocomplete-module_textareaHidden_UayJt\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\",\"shimmer\":\"AIAutocomplete-module_shimmer_13AnY\",\"shimmerRevealed\":\"AIAutocomplete-module_shimmerRevealed_RR8dp\",\"shimmerSweep\":\"AIAutocomplete-module_shimmerSweep_ARCon\",\"textShimmer\":\"AIAutocomplete-module_textShimmer_eCLdq\",\"shimmerHidden\":\"AIAutocomplete-module_shimmerHidden_45-Pf\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-2eef895d\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-2eef895d\";\n s.textContent = `.AIAutocompleteDropdown-module_dropdown_yz2KC {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 6px;\n background: var(--ac-color-background-default, #0b0247);\n border-radius: 23px;\n overflow: hidden;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.AIAutocompleteDropdown-module_visible_QCoXj {\n opacity: 1;\n pointer-events: auto;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"dropdown\":\"AIAutocompleteDropdown-module_dropdown_yz2KC\",\"visible\":\"AIAutocompleteDropdown-module_visible_QCoXj\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-d91f2b06\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-d91f2b06\";\n s.textContent = `.SuggestionGrid-module_grid_jvaPb {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 0 18px;\n padding: 18px 24px;\n max-height: 192px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar {\n width: 6px;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"grid\":\"SuggestionGrid-module_grid_jvaPb\"};","import { useRef, useState } from \"react\";\nimport type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionItem.module.css\";\n\ninterface SuggestionItemProps {\n option: SuggestionOption;\n isHighlighted: boolean;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: () => void;\n id: string;\n}\n\nexport function SuggestionItem({\n option,\n isHighlighted,\n onSelect,\n onHighlight,\n id,\n}: SuggestionItemProps) {\n const [pressed, setPressed] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const handleSelect = () => {\n if (!option.is_tappable || pressed) return;\n setPressed(true);\n onSelect(option);\n clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setPressed(false), 400);\n };\n\n const className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\n pressed ? styles.pressed : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={isHighlighted}\n className={className}\n tabIndex={option.is_tappable ? 0 : -1}\n onClick={handleSelect}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleSelect();\n }\n }}\n onMouseEnter={onHighlight}\n >\n <div className={styles.streaks} />\n <div className={styles.streaksVert} />\n <span className={styles.content}>\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </span>\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-f6bdc634\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-f6bdc634\";\n s.textContent = `.SuggestionItem-module_item_d4vpD {\n position: relative;\n overflow: visible;\n display: flex;\n align-items: center;\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n color: var(--ac-color-text-muted, #c1c4cb);\n white-space: normal;\n word-break: break-word;\n opacity: 0.35;\n border-radius: 12px;\n padding: 12px 10px;\n animation: SuggestionItem-module_fadeIn_I8u35 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes SuggestionItem-module_fadeIn_I8u35 {\n from {\n opacity: 0;\n }\n}\n\n.SuggestionItem-module_content_T-Qba {\n position: relative;\n z-index: 2;\n}\n\n.SuggestionItem-module_tappable_70KcX {\n cursor: pointer;\n}\n\n.SuggestionItem-module_tappable_70KcX:hover {\n color: var(--ac-color-text-default, #fff);\n}\n\n.SuggestionItem-module_nonTappable_xSZM- {\n cursor: default;\n opacity: 0.3;\n}\n\n.SuggestionItem-module_highlighted_Hb0SU {\n color: var(--ac-color-text-default, #fff);\n opacity: 0.5;\n}\n\n.SuggestionItem-module_tag_e3Fwe {\n font-size: 11px;\n margin-left: 6px;\n opacity: 0.5;\n}\n\n.SuggestionItem-module_pressed_98o-r {\n opacity: 0.8;\n color: var(--ac-color-text-default, #fff);\n background: rgba(255, 255, 255, 0.06);\n animation:\n SuggestionItem-module_glassFade_oyiSj 500ms ease forwards,\n SuggestionItem-module_tapDown_G3WGz 500ms ease forwards;\n}\n\n@keyframes SuggestionItem-module_tapDown_G3WGz {\n 0% {\n transform: scale(1);\n }\n 30% {\n transform: scale(0.97);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes SuggestionItem-module_glassFade_oyiSj {\n 0% {\n background: rgba(255, 255, 255, 0.1);\n }\n 100% {\n background: transparent;\n }\n}\n\n/* Border streaks — horizontal segments */\n\n.SuggestionItem-module_streaks_d9PEB {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Bottom horizontal: 40% from right → right corner */\n.SuggestionItem-module_streaks_d9PEB::before {\n content: \"\";\n position: absolute;\n bottom: -3px;\n left: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Top horizontal: 40% from left → left corner */\n.SuggestionItem-module_streaks_d9PEB::after {\n content: \"\";\n position: absolute;\n top: -3px;\n right: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Border streaks — vertical segments */\n\n.SuggestionItem-module_streaksVert_ERlV1 {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Right vertical: bottom-right corner → up */\n.SuggestionItem-module_streaksVert_ERlV1::before {\n content: \"\";\n position: absolute;\n bottom: 0;\n right: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Left vertical: top-left corner → down */\n.SuggestionItem-module_streaksVert_ERlV1::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::before {\n animation: SuggestionItem-module_streakHorizRight_aboGz 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::after {\n animation: SuggestionItem-module_streakHorizLeft_BreWJ 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::before {\n animation: SuggestionItem-module_streakVertUp_to1GD 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::after {\n animation: SuggestionItem-module_streakVertDown_OrcLh 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n/* Horizontal: bottom center-ish → right edge */\n@keyframes SuggestionItem-module_streakHorizRight_aboGz {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Horizontal: top center-ish → left edge */\n@keyframes SuggestionItem-module_streakHorizLeft_BreWJ {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Vertical segments start matching horizontal state at 200ms handoff */\n@keyframes SuggestionItem-module_streakVertUp_to1GD {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n\n@keyframes SuggestionItem-module_streakVertDown_OrcLh {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"content\":\"SuggestionItem-module_content_T-Qba\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\",\"pressed\":\"SuggestionItem-module_pressed_98o-r\",\"glassFade\":\"SuggestionItem-module_glassFade_oyiSj\",\"tapDown\":\"SuggestionItem-module_tapDown_G3WGz\",\"streaks\":\"SuggestionItem-module_streaks_d9PEB\",\"streaksVert\":\"SuggestionItem-module_streaksVert_ERlV1\",\"streakHorizRight\":\"SuggestionItem-module_streakHorizRight_aboGz\",\"streakHorizLeft\":\"SuggestionItem-module_streakHorizLeft_BreWJ\",\"streakVertUp\":\"SuggestionItem-module_streakVertUp_to1GD\",\"streakVertDown\":\"SuggestionItem-module_streakVertDown_OrcLh\"};","import type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionGrid.module.css\";\nimport { SuggestionItem } from \"./SuggestionItem\";\n\ninterface SuggestionGridProps {\n options: SuggestionOption[];\n activeIndex: number;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: (index: number) => void;\n listboxId: string;\n}\n\nexport function SuggestionGrid({\n options,\n activeIndex,\n onSelect,\n onHighlight,\n listboxId,\n}: SuggestionGridProps) {\n return (\n <div className={styles.grid}>\n {options.map((option, i) => (\n <SuggestionItem\n key={option.text}\n option={option}\n isHighlighted={i === activeIndex}\n onSelect={onSelect}\n onHighlight={() => onHighlight(i)}\n id={`${listboxId}-option-${i}`}\n />\n ))}\n </div>\n );\n}\n","import styles from \"./AIAutocompleteDropdown.module.css\";\nimport { SuggestionGrid } from \"./components/SuggestionGrid\";\nimport type { AIAutocompleteDropdownProps } from \"./types\";\n\nexport function AIAutocompleteDropdown({\n suggestions,\n activeIndex,\n onSelect,\n onHighlight,\n isOpen,\n id,\n className,\n}: AIAutocompleteDropdownProps) {\n const activeSuggestion = suggestions[0];\n const options = activeSuggestion?.options ?? [];\n const hasOptions = isOpen && options.length > 0;\n\n return (\n <div\n id={id}\n role=\"listbox\"\n className={`${styles.dropdown} ${hasOptions ? styles.visible : \"\"} ${className ?? \"\"}`}\n onMouseDown={(e) => e.preventDefault()}\n >\n {options.length > 0 && (\n <SuggestionGrid\n options={options}\n activeIndex={activeIndex}\n onSelect={onSelect}\n onHighlight={onHighlight}\n listboxId={id}\n />\n )}\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-b745b4fb\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-b745b4fb\";\n s.textContent = `.PillList-module_list_qvLqO {\n position: relative;\n z-index: 1;\n pointer-events: auto;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n vertical-align: middle;\n transform: translateY(-3px);\n}\n\n.PillList-module_pill_osSyz {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 7px 9px;\n border: none;\n border-radius: 6px;\n background: var(--ac-color-background-supportive, #313255);\n color: var(--ac-color-text-muted, #c1c4cb);\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 19px;\n line-height: 30px;\n cursor: pointer;\n white-space: nowrap;\n animation: PillList-module_fadeIn_Aezob 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.PillList-module_pill_osSyz:hover {\n filter: brightness(1.2);\n}\n\n.PillList-module_active_Oll-- {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes PillList-module_fadeIn_Aezob {\n from {\n opacity: 0;\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"list\":\"PillList-module_list_qvLqO\",\"pill\":\"PillList-module_pill_osSyz\",\"fadeIn\":\"PillList-module_fadeIn_Aezob\",\"active\":\"PillList-module_active_Oll--\"};","import type { Suggestion } from \"../types\";\nimport styles from \"./PillList.module.css\";\n\ninterface PillListProps {\n pills: Suggestion[];\n activePillIndex: number;\n onSelectPill: (index: number) => void;\n}\n\nfunction getPillOpacity(index: number): number {\n if (index === 0) return 0.4;\n if (index === 1) return 0.3;\n return 0.15;\n}\n\nexport function PillList({ pills, activePillIndex, onSelectPill }: PillListProps) {\n return (\n <span className={styles.list}>\n {pills.map((pill, i) => (\n <button\n key={`${pill.type}-${pill.text}`}\n type=\"button\"\n className={`${styles.pill} ${i === activePillIndex ? styles.active : \"\"}`}\n style={{ opacity: getPillOpacity(i) }}\n onClick={() => onSelectPill(i)}\n >\n {pill.text}\n </button>\n ))}\n </span>\n );\n}\n","import { type ChangeEvent, useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"../types\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { deriveSegments, reconcileParams } from \"../utils/segments\";\nimport { useAutocompleteFetch, useDebouncedFetch } from \"./useAutocompleteFetch\";\nimport { useAutocompleteKeyboard } from \"./useAutocompleteKeyboard\";\nimport { useAutocompletePills } from \"./useAutocompletePills\";\n\nlet idCounter = 0;\nfunction useStableId(): string {\n const id = useRef<string | null>(null);\n if (id.current === null) {\n id.current = `:ac-${++idCounter}:`;\n }\n return id.current;\n}\n\nexport function useAIAutocomplete({\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder: customPlaceholder,\n apiConfig,\n columns = 2,\n value: controlledValue,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n}: UseAIAutocompleteOptions): UseAIAutocompleteReturn {\n // === Controlled / uncontrolled state ===\n const isTextControlled = controlledValue !== undefined;\n const isParamsControlled = controlledParams !== undefined;\n\n const [internalText, setInternalText] = useState(\"\");\n const [internalCompletedParams, setInternalCompletedParams] = useState<CompletedParamState[]>([]);\n const [suggestions, setSuggestions] = useState<Suggestion[]>([]);\n const [activeDropdownIndex, setActiveDropdownIndex] = useState(-1);\n const [newParamId, setNewParamId] = useState<string | null>(null);\n const clearNewParamId = useCallback(() => setNewParamId(null), []);\n\n const text = isTextControlled ? controlledValue : internalText;\n const completedParams = isParamsControlled ? controlledParams : internalCompletedParams;\n\n // === Refs — must be before setText/setCompletedParams which read them ===\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n const onChangeRef = useRef(onChangeProp);\n onChangeRef.current = onChangeProp;\n const onParamsChangeRef = useRef(onParamsChange);\n onParamsChangeRef.current = onParamsChange;\n const controlledValueRef = useRef(controlledValue);\n controlledValueRef.current = controlledValue;\n const controlledParamsRef = useRef(controlledParams);\n controlledParamsRef.current = controlledParams;\n\n // Stable setText that reads controlled value + callback via refs (no stale closures)\n const setText = useCallback(\n (value: string | ((prev: string) => string)) => {\n if (typeof value === \"function\") {\n if (isTextControlled) {\n const newVal = value(controlledValueRef.current ?? \"\");\n onChangeRef.current?.(newVal);\n } else {\n setInternalText((prev) => {\n const newVal = value(prev);\n onChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isTextControlled) setInternalText(value);\n onChangeRef.current?.(value);\n }\n },\n [isTextControlled],\n );\n\n // Stable setCompletedParams — same ref pattern\n const setCompletedParams = useCallback(\n (value: CompletedParamState[] | ((prev: CompletedParamState[]) => CompletedParamState[])) => {\n if (typeof value === \"function\") {\n if (isParamsControlled) {\n const newVal = value(controlledParamsRef.current ?? []);\n onParamsChangeRef.current?.(newVal);\n } else {\n setInternalCompletedParams((prev) => {\n const newVal = value(prev);\n onParamsChangeRef.current?.(newVal);\n return newVal;\n });\n }\n } else {\n if (!isParamsControlled) setInternalCompletedParams(value);\n onParamsChangeRef.current?.(value);\n }\n },\n [isParamsControlled],\n );\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const optionOverridesRef = useRef(optionOverrides);\n optionOverridesRef.current = optionOverrides;\n const maskCompletedTextRef = useRef(maskCompletedText);\n maskCompletedTextRef.current = maskCompletedText;\n const apiConfigRef = useRef(apiConfig);\n apiConfigRef.current = apiConfig;\n const textRef = useRef(text);\n textRef.current = text;\n const suggestionsRef = useRef(suggestions);\n suggestionsRef.current = suggestions;\n const filterBaseRef = useRef(0);\n const filterInProgressRef = useRef(false);\n const pillTappedRef = useRef(false);\n const skipNextFetchRef = useRef(false);\n const listboxId = useStableId();\n\n // === Fetch ===\n const { doFetch, isLoading, error, isReady, lastRawQueryRef } = useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n });\n\n useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n });\n\n // === Derived ===\n const segments = useMemo(() => deriveSegments(text, completedParams), [text, completedParams]);\n\n filterBaseRef.current = Math.min(filterBaseRef.current, text.length);\n const filterQuery = extractFilterQuery(text, filterBaseRef.current, filterInProgressRef.current);\n\n const placeholderText = useMemo(() => {\n const serverPlaceholder = suggestions\n .filter((s) => s.type === \"placeholder\")\n .map((s) => s.text)\n .join(\" \");\n return serverPlaceholder || customPlaceholder || \"\";\n }, [suggestions, customPlaceholder]);\n const actionableSuggestions = useMemo(\n () => suggestions.filter((s) => s.type !== \"placeholder\"),\n [suggestions],\n );\n const activeSuggestion: Suggestion | undefined = actionableSuggestions[0];\n const overrideFn = activeSuggestion ? optionOverrides?.[activeSuggestion.type] : undefined;\n const baseOptions = activeSuggestion\n ? overrideFn\n ? overrideFn(filterQuery.trim())\n : (activeSuggestion.options ?? [])\n : [];\n const filteredOptions = useMemo(\n () => filterOptions(baseOptions, filterQuery),\n [baseOptions, filterQuery],\n );\n const hasPlaceholder = placeholderText.length > 0;\n const isDropdownOpen =\n !isLoading &&\n filteredOptions.length > 0 &&\n (!!text || pillTappedRef.current || !hasPlaceholder);\n\n // === Option selection ===\n const selectOption = useCallback(\n (option: SuggestionOption) => {\n if (!activeSuggestion) return;\n\n const base = filterBaseRef.current;\n let prefix = textRef.current.slice(0, base);\n\n // If input is empty and placeholder is visible, prepend placeholder\n const inputWasEmpty = prefix.length === 0 && textRef.current.length === 0;\n if (inputWasEmpty && placeholderText) {\n prefix = placeholderText + \" \";\n }\n\n if (prefix.length > 0 && !prefix.endsWith(\" \")) {\n const lastWord = prefix.split(/\\s+/).pop() ?? \"\";\n if (lastWord && option.text.toLowerCase().startsWith(lastWord.toLowerCase())) {\n prefix = prefix.slice(0, prefix.length - lastWord.length);\n }\n }\n\n const needsSpace = prefix.length > 0 && prefix[prefix.length - 1] !== \" \";\n const newText = prefix + (needsSpace ? \" \" : \"\") + option.text + \" \";\n // Capitalize the first character of the entire text when input was empty\n const finalText =\n inputWasEmpty && newText.length > 0 ? newText[0].toUpperCase() + newText.slice(1) : newText;\n // Find the option text as it appears in finalText (may be capitalized)\n const optionStart = finalText.toLowerCase().lastIndexOf(option.text.toLowerCase());\n const optionInFinal =\n optionStart >= 0\n ? finalText.slice(optionStart, optionStart + option.text.length)\n : option.text;\n\n const completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: optionInFinal,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n setText(finalText);\n filterBaseRef.current = finalText.length;\n setCompletedParams((prev) => [...prev, completed]);\n setNewParamId(completed.id);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n // Skip the debounced fetch if there are remaining cached suggestions\n const remainingActionable = actionableSuggestions.length - 1;\n if (remainingActionable > 0) {\n skipNextFetchRef.current = true;\n }\n // Delay suggestion removal so the dropdown streak animation can play\n setTimeout(() => {\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n }, 400);\n },\n [activeSuggestion, actionableSuggestions, placeholderText, setText, setCompletedParams],\n );\n\n // === Text change handler ===\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLTextAreaElement>) => {\n const raw = e.target.value;\n const shouldCapitalize =\n raw.length > 0 &&\n !(e.nativeEvent as InputEvent)?.isComposing &&\n raw[0] !== raw[0].toUpperCase();\n const newValue = shouldCapitalize ? raw[0].toUpperCase() + raw.slice(1) : raw;\n setText(newValue);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n\n const { valid, invalid } = reconcileParams(newValue, completedParams);\n if (invalid.length > 0) {\n setCompletedParams(() => valid);\n for (const param of invalid) {\n setSuggestions((prev) => [\n {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n },\n ...prev,\n ]);\n }\n }\n\n if (activeSuggestion && invalid.length === 0) {\n const newFilterQuery = extractFilterQuery(\n newValue,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(activeSuggestion.options, newFilterQuery);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: match.text,\n kind: match.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: match.metadata,\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n }\n }\n },\n [completedParams, activeSuggestion, setText, setCompletedParams],\n );\n\n // === Pills ===\n const pills = useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n });\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n pills.reEditParam(param).apply(setText);\n },\n [pills, setText],\n );\n\n // === Keyboard ===\n const { handleKeyDown } = useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill: pills.setActivePill,\n listboxId,\n pillTappedRef,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n });\n\n // === Reset ===\n const reset = useCallback(() => {\n setText(\"\");\n setCompletedParams(() => []);\n setSuggestions([]);\n setActiveDropdownIndex(-1);\n filterBaseRef.current = 0;\n filterInProgressRef.current = false;\n lastRawQueryRef.current = \"\";\n doFetch(\"\", []);\n }, [doFetch, setText, setCompletedParams, lastRawQueryRef]);\n\n const activeDescendantId =\n activeDropdownIndex >= 0 ? `${listboxId}-option-${activeDropdownIndex}` : undefined;\n\n return {\n completedParams,\n suggestionPills: actionableSuggestions,\n setActivePill: pills.setActivePill,\n removeLastParam: pills.removeLastParam,\n reEditParam,\n segments,\n newParamId,\n clearNewParamId,\n suggestions,\n activeIndex: activeDropdownIndex,\n isReady,\n isLoading,\n error,\n inputProps: {\n value: text,\n placeholder: placeholderText || undefined,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n role: \"combobox\" as const,\n \"aria-expanded\": isDropdownOpen,\n \"aria-activedescendant\": activeDescendantId,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-controls\": listboxId,\n },\n reset,\n dropdownProps: {\n suggestions: activeSuggestion ? [{ ...activeSuggestion, options: filteredOptions }] : [],\n activeIndex: activeDropdownIndex,\n onSelect: selectOption,\n onHighlight: setActiveDropdownIndex,\n isOpen: isDropdownOpen,\n id: listboxId,\n },\n };\n}\n","import type { SuggestionOption } from \"../types\";\n\n/**\n * Extracts the effective filter query from the region after filterBase.\n * If the server marked the region as in_progress, the full region is used.\n * Otherwise, filtering only starts after the first space (to avoid filtering\n * mid-word when the user continues typing a word that was already in the input).\n */\nexport function extractFilterQuery(\n text: string,\n filterBase: number,\n isInProgress: boolean,\n): string {\n const rawRegion = text.slice(filterBase);\n if (isInProgress || filterBase === 0 || text[filterBase - 1] === \" \") {\n return rawRegion;\n }\n const spaceIdx = rawRegion.indexOf(\" \");\n return spaceIdx === -1 ? \"\" : rawRegion.slice(spaceIdx + 1);\n}\n\n/**\n * Filters options using partial substring match on the text after the last completed param.\n */\nexport function filterOptions(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption[] {\n if (!options) return [];\n const trimmed = query.trimStart();\n if (!trimmed) return options;\n const lower = trimmed.toLowerCase();\n return options.filter((o) => !o.is_tappable || o.text.toLowerCase().includes(lower));\n}\n\n/**\n * Finds an exact match for the trimmed filter query against options.\n */\nexport function findExactMatch(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption | null {\n if (!options) return null;\n const trimmed = query.trim();\n if (!trimmed) return null;\n const lower = trimmed.toLowerCase();\n return options.find((o) => o.is_tappable && o.text.toLowerCase() === lower) ?? null;\n}\n","import type { CompletedParamState, Segment } from \"../types\";\n\n/**\n * Derives segments for overlay rendering by matching completed params in text.\n */\nexport function deriveSegments(text: string, completedParams: CompletedParamState[]): Segment[] {\n const result: Segment[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) continue;\n if (idx > pos) {\n result.push({ type: \"text\", value: text.slice(pos, idx) });\n }\n result.push({ type: \"completed\", value: param.text, param });\n pos = idx + param.text.length;\n }\n\n const remaining = text.slice(pos);\n if (remaining) {\n result.push({ type: \"text\", value: remaining });\n }\n\n return result;\n}\n\n/**\n * Checks which completed params still exist in the new text.\n */\nexport function reconcileParams(\n text: string,\n completedParams: CompletedParamState[],\n): { valid: CompletedParamState[]; invalid: CompletedParamState[] } {\n const valid: CompletedParamState[] = [];\n const invalid: CompletedParamState[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) {\n invalid.push(param);\n } else {\n valid.push(param);\n pos = idx + param.text.length;\n }\n }\n\n return { valid, invalid };\n}\n","import { type MutableRefObject, useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n APIConfig,\n CompletedParamState,\n OptionOverrides,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { fetchSuggestions } from \"../utils/api\";\nimport { buildQuery } from \"../utils/buildQuery\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../utils/filtering\";\nimport { applyOptionOverrides } from \"../utils/overrides\";\n\nconst DEBOUNCE_MS = 100;\nconst SLOW_DEBOUNCE_MS = 300;\nconst MIN_CHARS_DIFF = 2;\n\ninterface UseAutocompleteFetchOptions {\n textRef: MutableRefObject<string>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n maskCompletedTextRef: MutableRefObject<boolean | undefined>;\n apiConfigRef: MutableRefObject<APIConfig | undefined>;\n optionOverridesRef: MutableRefObject<OptionOverrides | undefined>;\n onErrorRef: MutableRefObject<((error: Error) => void) | undefined>;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n}\n\ninterface UseAutocompleteFetchReturn {\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n isLoading: boolean;\n error: Error | null;\n isReady: boolean;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useAutocompleteFetch({\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n}: UseAutocompleteFetchOptions): UseAutocompleteFetchReturn {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isReady, setIsReady] = useState(false);\n const fetchVersionRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n const lastRawQueryRef = useRef(\"\");\n\n const doFetch = useCallback(\n async (rawQuery: string, completed: CompletedParamState[]) => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n const version = ++fetchVersionRef.current;\n const textAtRequest = textRef.current.length;\n\n const hasSuggestions = suggestionsRef.current.some((s) => s.type !== \"placeholder\");\n if (!hasSuggestions) setIsLoading(true);\n setError(null);\n try {\n const res = await fetchSuggestions(rawQuery, completed, {\n maskCompletedText: maskCompletedTextRef.current,\n signal: controller.signal,\n apiConfig: apiConfigRef.current,\n });\n\n if (version !== fetchVersionRef.current) return;\n\n let newSuggestions = applyOptionOverrides(\n res.data.suggestions ?? [],\n optionOverridesRef.current,\n );\n setIsReady(res.data.is_ready ?? false);\n lastRawQueryRef.current = rawQuery;\n\n const input = res.data.input ?? [];\n const lastInput = input[input.length - 1];\n const currentText = textRef.current;\n if (lastInput?.state === \"in_progress\") {\n filterInProgressRef.current = true;\n const inProgressIdx = currentText.toLowerCase().lastIndexOf(lastInput.text.toLowerCase());\n if (inProgressIdx !== -1) {\n filterBaseRef.current = inProgressIdx;\n } else {\n filterBaseRef.current = textAtRequest;\n }\n } else {\n filterInProgressRef.current = false;\n filterBaseRef.current = textAtRequest;\n }\n\n // Check if the user already typed an exact match while waiting\n const actionable = newSuggestions.filter((s) => s.type !== \"placeholder\");\n const active = actionable[0];\n if (active) {\n const query = extractFilterQuery(\n currentText,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const match = findExactMatch(active.options, query);\n if (match) {\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: active.type,\n text: match.text,\n kind: match.kind,\n suggestionType: active.type,\n suggestionPlaceholder: active.text,\n options: active.options ?? [],\n metadata: match.metadata,\n },\n ]);\n newSuggestions = newSuggestions.filter((s) => s !== active);\n }\n }\n\n setSuggestions(newSuggestions);\n setIsLoading(false);\n setActiveDropdownIndex(-1);\n } catch (err) {\n if (version === fetchVersionRef.current) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n setError(caughtError);\n setIsLoading(false);\n onErrorRef.current?.(caughtError);\n }\n }\n },\n [\n textRef,\n suggestionsRef,\n filterBaseRef,\n filterInProgressRef,\n maskCompletedTextRef,\n apiConfigRef,\n optionOverridesRef,\n onErrorRef,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n ],\n );\n\n // Mount fetch\n useEffect(() => {\n doFetch(\"\", []);\n return () => {\n abortRef.current?.abort();\n };\n }, [doFetch]);\n\n return { doFetch, isLoading, error, isReady, lastRawQueryRef };\n}\n\ninterface UseDebouncedFetchOptions {\n text: string;\n completedParams: CompletedParamState[];\n doFetch: (rawQuery: string, completed: CompletedParamState[]) => Promise<void>;\n filterBaseRef: MutableRefObject<number>;\n filterInProgressRef: MutableRefObject<boolean>;\n skipNextFetchRef: MutableRefObject<boolean>;\n suggestionsRef: MutableRefObject<Suggestion[]>;\n lastRawQueryRef: MutableRefObject<string>;\n}\n\nexport function useDebouncedFetch({\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n}: UseDebouncedFetchOptions): void {\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const slowDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hasFetchedRef = useRef(true);\n\n useEffect(() => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n\n if (skipNextFetchRef.current) {\n skipNextFetchRef.current = false;\n return;\n }\n\n const attemptFetch = (minDiff: number): boolean => {\n if (!text && completedParams.length === 0) {\n if (!hasFetchedRef.current) {\n hasFetchedRef.current = true;\n return false;\n }\n doFetch(\"\", []);\n return true;\n }\n\n const currentQuery = extractFilterQuery(\n text,\n filterBaseRef.current,\n filterInProgressRef.current,\n );\n const currentSuggestions = suggestionsRef.current;\n const actionable = currentSuggestions.filter((s: Suggestion) => s.type !== \"placeholder\");\n const active = actionable[0];\n const currentFiltered = active ? filterOptions(active.options, currentQuery) : [];\n const tappableFiltered = currentFiltered.filter((o: SuggestionOption) => o.is_tappable);\n const hasExactMatch = active ? findExactMatch(active.options, currentQuery) !== null : false;\n\n const isInFilterZone = currentQuery.trim().length > 0;\n if (tappableFiltered.length > 0 && !hasExactMatch && isInFilterZone) return false;\n\n const { rawQuery, completedParams: updatedParams } = buildQuery(text, completedParams);\n const isDeleting = rawQuery.length < lastRawQueryRef.current.length;\n const charDiff = Math.abs(rawQuery.length - lastRawQueryRef.current.length);\n if (isDeleting || charDiff >= minDiff) {\n doFetch(rawQuery, updatedParams);\n return true;\n }\n return false;\n };\n\n debounceRef.current = setTimeout(() => {\n if (attemptFetch(MIN_CHARS_DIFF)) {\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n }\n }, DEBOUNCE_MS);\n\n slowDebounceRef.current = setTimeout(() => attemptFetch(1), SLOW_DEBOUNCE_MS);\n\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n if (slowDebounceRef.current) clearTimeout(slowDebounceRef.current);\n };\n }, [\n text,\n completedParams,\n doFetch,\n filterBaseRef,\n filterInProgressRef,\n skipNextFetchRef,\n suggestionsRef,\n lastRawQueryRef,\n ]);\n}\n","import type {\n APIConfig,\n AutocompleteRequest,\n AutocompleteResponse,\n CompletedParam,\n CompletedParamState,\n} from \"../types\";\n\n// Replaced at build time by tsup/vitest `define` config with the package.json version.\ndeclare const __SDK_VERSION__: string;\nconst SDK_VERSION = __SDK_VERSION__;\n\nlet hasWarnedMissingKey = false;\n\nfunction generateRequestId(): string {\n return crypto.randomUUID();\n}\n\nfunction toWireParam(param: CompletedParamState, includeText: boolean): CompletedParam {\n return {\n placeholder: param.placeholder,\n type: param.type,\n ...(includeText && { text: param.text }),\n kind: param.kind,\n };\n}\n\nexport async function fetchSuggestions(\n rawQuery: string,\n completedParams: CompletedParamState[],\n options?: {\n maskCompletedText?: boolean;\n signal?: AbortSignal;\n apiConfig?: APIConfig;\n },\n): Promise<AutocompleteResponse> {\n const apiConfig = options?.apiConfig;\n const apiKey = apiConfig?.apiKey ?? \"\";\n if (!apiKey && !hasWarnedMissingKey) {\n hasWarnedMissingKey = true;\n // biome-ignore lint/suspicious/noConsole: intentional dev warning\n console.warn(\n \"[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header.\",\n );\n }\n const authScheme = apiConfig?.authScheme ?? \"Bearer\";\n const includeText = !options?.maskCompletedText;\n\n const rawCount = completedParams.find(\n (p) => p.type === \"contact\" && p.metadata?.contact_account_count,\n )?.metadata?.contact_account_count;\n const contactAccountCount = typeof rawCount === \"number\" ? rawCount : undefined;\n\n const body: AutocompleteRequest = {\n data: {\n raw_query: rawQuery,\n completed_params: completedParams.map((p) => toWireParam(p, includeText)),\n ...(contactAccountCount != null && { contact_account_count: contactAccountCount }),\n },\n meta: {\n request_id: generateRequestId(),\n request_at: new Date().toISOString(),\n language: typeof navigator !== \"undefined\" ? navigator.language : \"en-US\",\n client_version: SDK_VERSION,\n },\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(apiConfig?.appIdentifier && { \"X-App-Identifier\": apiConfig.appIdentifier }),\n ...apiConfig?.headers,\n };\n if (apiKey) {\n headers.Authorization = authScheme === \"Basic\" ? `Basic ${btoa(apiKey)}` : `Bearer ${apiKey}`;\n }\n\n const response = await fetch(apiConfig?.endpoint ?? \"/ac/suggest\", {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json() as Promise<AutocompleteResponse>;\n}\n","import type { CompletedParamState } from \"../types\";\n\ninterface BuildQueryResult {\n rawQuery: string;\n completedParams: CompletedParamState[];\n}\n\n/**\n * Takes the raw input text and completed params (without placeholders),\n * replaces each completed param's text in the string with a {{TYPE_N}} token,\n * and returns the transformed query + params with placeholders filled in.\n *\n * Replacements happen left-to-right, first occurrence only per param.\n * Counter is per-type (e.g. {{TASK_1}}, {{GOAL_1}}, {{GOAL_2}}).\n */\nexport function buildQuery(text: string, completedParams: CompletedParamState[]): BuildQueryResult {\n let result = text;\n const typeCounts: Record<string, number> = {};\n const updatedParams: CompletedParamState[] = [];\n\n for (const param of completedParams) {\n const count = (typeCounts[param.type] ?? 0) + 1;\n typeCounts[param.type] = count;\n\n const typeKey = param.type.toUpperCase().replace(/\\s+/g, \"_\");\n const placeholder = `{{${typeKey}_${count}}}`;\n\n // Replace first occurrence of the param text in the string\n const index = result.indexOf(param.text);\n if (index !== -1) {\n result = result.slice(0, index) + placeholder + result.slice(index + param.text.length);\n }\n\n updatedParams.push({ ...param, placeholder });\n }\n\n return { rawQuery: result, completedParams: updatedParams };\n}\n","import type { Suggestion, SuggestionOption } from \"../types\";\n\n/**\n * Applies option overrides by calling the override function with an empty query,\n * then prepending results to suggestions that match by type, deduplicating by text.\n */\nexport function applyOptionOverrides(\n suggestions: Suggestion[],\n overrides?: Record<string, (query: string) => SuggestionOption[]>,\n): Suggestion[] {\n if (!overrides) return suggestions;\n return suggestions.map((s) => {\n const fn = overrides[s.type];\n if (!fn) return s;\n const extra = fn(\"\");\n if (extra.length === 0) return s;\n const existingTexts = new Set(extra.map((o) => o.text));\n const deduped = (s.options ?? []).filter((o) => !existingTexts.has(o.text));\n return { ...s, options: [...extra, ...deduped] };\n });\n}\n","import { type KeyboardEvent, type MutableRefObject, useCallback } from \"react\";\nimport type {\n AutocompleteResult,\n CompletedParamState,\n Suggestion,\n SuggestionOption,\n} from \"../types\";\nimport { buildQuery } from \"../utils/buildQuery\";\n\ninterface UseAutocompleteKeyboardOptions {\n activeDropdownIndex: number;\n setActiveDropdownIndex: (index: number) => void;\n filteredOptions: SuggestionOption[];\n selectOption: (option: SuggestionOption) => void;\n onSubmitRef: MutableRefObject<((result: AutocompleteResult) => void) | undefined>;\n text: string;\n completedParams: CompletedParamState[];\n isDropdownOpen: boolean;\n hasPlaceholder: boolean;\n placeholderText: string;\n suggestions: Suggestion[];\n actionableSuggestions: Suggestion[];\n setActivePill: (index: number) => void;\n listboxId: string;\n pillTappedRef: MutableRefObject<boolean>;\n filterBaseRef: MutableRefObject<number>;\n columns: number;\n setText: (value: string) => void;\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: (prev: Suggestion[]) => Suggestion[]) => void;\n}\n\nexport function useAutocompleteKeyboard({\n activeDropdownIndex,\n setActiveDropdownIndex,\n filteredOptions,\n selectOption,\n onSubmitRef,\n text,\n completedParams,\n isDropdownOpen,\n hasPlaceholder,\n placeholderText,\n suggestions,\n actionableSuggestions,\n setActivePill,\n listboxId,\n pillTappedRef,\n filterBaseRef,\n columns,\n setText,\n setCompletedParams,\n setSuggestions,\n}: UseAutocompleteKeyboardOptions) {\n const getTappableIndices = useCallback(() => {\n const tappable = filteredOptions\n .map((o, i) => (o.is_tappable ? i : -1))\n .filter((i) => i !== -1);\n // Column-first ordering: all column-0 items, then column-1, etc.\n const buckets: number[][] = Array.from({ length: columns }, () => []);\n for (const i of tappable) buckets[i % columns].push(i);\n return buckets.flat();\n }, [filteredOptions, columns]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n const tappableIndices = getTappableIndices();\n\n switch (e.key) {\n case \"ArrowDown\": {\n // Only navigate dropdown if cursor is at the end of the input\n const target = e.target as HTMLTextAreaElement;\n const cursorAtEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (!cursorAtEnd && activeDropdownIndex < 0) break;\n\n e.preventDefault();\n // If dropdown is closed but there are options available, open it and select the first option\n if (!isDropdownOpen && actionableSuggestions.length > 0) {\n pillTappedRef.current = true;\n const firstTappable = tappableIndices[0];\n setActiveDropdownIndex(firstTappable ?? 0);\n break;\n }\n if (tappableIndices.length === 0) return;\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const nextPos = currentPos < tappableIndices.length - 1 ? currentPos + 1 : 0;\n setActiveDropdownIndex(tappableIndices[nextPos]);\n break;\n }\n case \"ArrowUp\": {\n if (tappableIndices.length === 0 || activeDropdownIndex < 0) break;\n e.preventDefault();\n // If on the first row, deselect and return focus to the input\n const isFirstRow = activeDropdownIndex < columns;\n if (isFirstRow) {\n setActiveDropdownIndex(-1);\n break;\n }\n const currentPos = tappableIndices.indexOf(activeDropdownIndex);\n const prevPos = currentPos > 0 ? currentPos - 1 : tappableIndices.length - 1;\n setActiveDropdownIndex(tappableIndices[prevPos]);\n break;\n }\n case \"ArrowRight\": {\n if (activeDropdownIndex < 0) {\n // Only cycle pills if the cursor is at the end of the input\n const target = e.target as HTMLTextAreaElement;\n const atEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (atEnd && actionableSuggestions.length > 1) {\n e.preventDefault();\n setActivePill(1);\n }\n break;\n }\n const col = activeDropdownIndex % columns;\n if (col < columns - 1) {\n const rightNeighbor = activeDropdownIndex + 1;\n if (\n rightNeighbor < filteredOptions.length &&\n filteredOptions[rightNeighbor]?.is_tappable\n ) {\n e.preventDefault();\n setActiveDropdownIndex(rightNeighbor);\n }\n }\n break;\n }\n case \"ArrowLeft\": {\n if (activeDropdownIndex < 0) break;\n if (activeDropdownIndex % columns > 0) {\n const leftNeighbor = activeDropdownIndex - 1;\n if (leftNeighbor >= 0 && filteredOptions[leftNeighbor]?.is_tappable) {\n e.preventDefault();\n setActiveDropdownIndex(leftNeighbor);\n }\n }\n break;\n }\n case \"Enter\": {\n e.preventDefault();\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n const optionEl = document.getElementById(`${listboxId}-option-${activeDropdownIndex}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[activeDropdownIndex]);\n }\n } else if (onSubmitRef.current) {\n const { rawQuery, completedParams: finalParams } = buildQuery(text, completedParams);\n const result: AutocompleteResult = {\n query: text.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n };\n onSubmitRef.current(result);\n }\n break;\n }\n case \"Tab\": {\n if (activeDropdownIndex >= 0 && filteredOptions[activeDropdownIndex]?.is_tappable) {\n e.preventDefault();\n const optionEl = document.getElementById(`${listboxId}-option-${activeDropdownIndex}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[activeDropdownIndex]);\n }\n } else if (isDropdownOpen) {\n const firstTappableIdx = filteredOptions.findIndex((o) => o.is_tappable);\n if (firstTappableIdx >= 0) {\n e.preventDefault();\n const optionEl = document.getElementById(`${listboxId}-option-${firstTappableIdx}`);\n if (optionEl) {\n optionEl.click();\n } else {\n selectOption(filteredOptions[firstTappableIdx]);\n }\n }\n } else if (!text && hasPlaceholder) {\n e.preventDefault();\n const placeholderSuggestion = suggestions.find((s) => s.type === \"placeholder\");\n if (placeholderSuggestion) {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n setCompletedParams((prev) => [\n ...prev,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: placeholderSuggestion.type,\n text: placeholderText,\n kind: null,\n suggestionType: placeholderSuggestion.type,\n suggestionPlaceholder: placeholderSuggestion.text,\n options: placeholderSuggestion.options ?? [],\n },\n ]);\n setSuggestions((prev) => prev.filter((s) => s !== placeholderSuggestion));\n } else {\n setText(placeholderText);\n filterBaseRef.current = placeholderText.length;\n }\n }\n break;\n }\n case \"Escape\":\n setActiveDropdownIndex(-1);\n break;\n }\n },\n [\n actionableSuggestions,\n activeDropdownIndex,\n columns,\n completedParams,\n filteredOptions,\n filterBaseRef,\n getTappableIndices,\n hasPlaceholder,\n listboxId,\n pillTappedRef,\n isDropdownOpen,\n onSubmitRef,\n placeholderText,\n selectOption,\n setActiveDropdownIndex,\n setActivePill,\n setCompletedParams,\n setSuggestions,\n setText,\n suggestions,\n text,\n ],\n );\n\n return { handleKeyDown, getTappableIndices };\n}\n","import { type MutableRefObject, useCallback } from \"react\";\nimport type { CompletedParamState, Suggestion } from \"../types\";\n\ninterface UseAutocompletePillsOptions {\n completedParams: CompletedParamState[];\n suggestions: Suggestion[];\n setCompletedParams: (fn: (prev: CompletedParamState[]) => CompletedParamState[]) => void;\n setSuggestions: (fn: Suggestion[] | ((prev: Suggestion[]) => Suggestion[])) => void;\n setActiveDropdownIndex: (index: number) => void;\n filterBaseRef: MutableRefObject<number>;\n pillTappedRef: MutableRefObject<boolean>;\n}\n\nexport function useAutocompletePills({\n completedParams,\n suggestions,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n}: UseAutocompletePillsOptions) {\n const setActivePill = useCallback(\n (index: number) => {\n const actionable = suggestions.filter((s) => s.type !== \"placeholder\");\n if (index < 0 || index >= actionable.length) return;\n const moved = actionable[index];\n const rest = actionable.filter((_, i) => i !== index);\n const placeholders = suggestions.filter((s) => s.type === \"placeholder\");\n setSuggestions([...placeholders, moved, ...rest]);\n pillTappedRef.current = true;\n setActiveDropdownIndex(-1);\n },\n [suggestions, setSuggestions, setActiveDropdownIndex, pillTappedRef],\n );\n\n const removeLastParam = useCallback(() => {\n if (completedParams.length === 0) return;\n const lastParam = completedParams[completedParams.length - 1];\n const restoredSuggestion: Suggestion = {\n type: lastParam.suggestionType,\n text: lastParam.suggestionPlaceholder,\n required: true,\n options: lastParam.options,\n };\n setCompletedParams((prev) => prev.slice(0, -1));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n }, [completedParams, setCompletedParams, setSuggestions, setActiveDropdownIndex]);\n\n const reEditParam = useCallback(\n (param: CompletedParamState) => {\n const restoredSuggestion: Suggestion = {\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n };\n return {\n apply: (setText: (fn: (prev: string) => string) => void) => {\n setText((prev) => {\n let pos = 0;\n for (const p of completedParams) {\n const idx = prev.indexOf(p.text, pos);\n if (idx === -1) continue;\n if (p.id === param.id) {\n const before = prev.slice(0, idx);\n const after = prev.slice(idx + param.text.length);\n const cleaned = (before + after).replace(/ {2,}/g, \" \");\n filterBaseRef.current = Math.min(filterBaseRef.current, cleaned.length);\n return cleaned;\n }\n pos = idx + p.text.length;\n }\n return prev;\n });\n setCompletedParams((prev) => prev.filter((p) => p.id !== param.id));\n setSuggestions((prev: Suggestion[]) => [restoredSuggestion, ...prev]);\n setActiveDropdownIndex(-1);\n pillTappedRef.current = true;\n },\n };\n },\n [\n completedParams,\n setCompletedParams,\n setSuggestions,\n setActiveDropdownIndex,\n filterBaseRef,\n pillTappedRef,\n ],\n );\n\n return { setActivePill, removeLastParam, reEditParam };\n}\n"],"mappings":"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","names":["index_exports","__export","AIAutocomplete","AIAutocompleteDropdown","useAIAutocomplete","__toCommonJS","import_react","s","AIAutocomplete_module_css_default","s","AIAutocompleteDropdown_module_css_default","s","SuggestionGrid_module_css_default","import_react","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","pressed","setPressed","timerRef","handleSelect","className","SuggestionItem_module_css_default","e","import_jsx_runtime","SuggestionGrid","options","activeIndex","onSelect","onHighlight","listboxId","SuggestionGrid_module_css_default","option","i","SuggestionItem","import_jsx_runtime","AIAutocompleteDropdown","suggestions","activeIndex","onSelect","onHighlight","isOpen","id","className","options","hasOptions","AIAutocompleteDropdown_module_css_default","e","SuggestionGrid","s","PillList_module_css_default","import_jsx_runtime","getPillOpacity","index","PillList","pills","activePillIndex","onSelectPill","PillList_module_css_default","pill","i","import_react","extractFilterQuery","text","filterBase","isInProgress","rawRegion","spaceIdx","filterOptions","options","query","trimmed","lower","o","findExactMatch","deriveSegments","text","completedParams","result","pos","param","idx","remaining","reconcileParams","valid","invalid","import_react","SDK_VERSION","hasWarnedMissingKey","generateRequestId","toWireParam","param","includeText","fetchSuggestions","rawQuery","completedParams","options","apiConfig","apiKey","authScheme","rawCount","p","contactAccountCount","body","headers","response","buildQuery","text","completedParams","result","typeCounts","updatedParams","param","count","placeholder","index","applyOptionOverrides","suggestions","overrides","s","fn","extra","existingTexts","o","deduped","DEBOUNCE_MS","SLOW_DEBOUNCE_MS","MIN_CHARS_DIFF","useAutocompleteFetch","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","maskCompletedTextRef","apiConfigRef","optionOverridesRef","onErrorRef","setCompletedParams","setSuggestions","setActiveDropdownIndex","isLoading","setIsLoading","error","setError","isReady","setIsReady","fetchVersionRef","abortRef","lastRawQueryRef","doFetch","rawQuery","completed","controller","version","textAtRequest","s","res","fetchSuggestions","newSuggestions","applyOptionOverrides","input","lastInput","currentText","inProgressIdx","active","query","extractFilterQuery","match","findExactMatch","prev","err","caughtError","useDebouncedFetch","text","completedParams","skipNextFetchRef","debounceRef","slowDebounceRef","hasFetchedRef","attemptFetch","minDiff","currentQuery","tappableFiltered","filterOptions","o","hasExactMatch","isInFilterZone","updatedParams","buildQuery","isDeleting","charDiff","import_react","useAutocompleteKeyboard","activeDropdownIndex","setActiveDropdownIndex","filteredOptions","selectOption","onSubmitRef","text","completedParams","isDropdownOpen","hasPlaceholder","placeholderText","suggestions","actionableSuggestions","setActivePill","listboxId","pillTappedRef","filterBaseRef","columns","setText","setCompletedParams","setSuggestions","getTappableIndices","tappable","o","i","buckets","e","tappableIndices","target","firstTappable","currentPos","nextPos","prevPos","rightNeighbor","leftNeighbor","optionEl","rawQuery","finalParams","buildQuery","result","firstTappableIdx","placeholderSuggestion","prev","s","import_react","useAutocompletePills","completedParams","suggestions","setCompletedParams","setSuggestions","setActiveDropdownIndex","filterBaseRef","pillTappedRef","setActivePill","index","actionable","s","moved","rest","_","i","placeholders","removeLastParam","lastParam","restoredSuggestion","prev","reEditParam","param","setText","pos","p","idx","before","after","cleaned","idCounter","useStableId","id","useAIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","customPlaceholder","apiConfig","columns","controlledValue","controlledParams","onChangeProp","onParamsChange","isTextControlled","isParamsControlled","internalText","setInternalText","internalCompletedParams","setInternalCompletedParams","suggestions","setSuggestions","activeDropdownIndex","setActiveDropdownIndex","newParamId","setNewParamId","clearNewParamId","text","completedParams","onSubmitRef","onChangeRef","onParamsChangeRef","controlledValueRef","controlledParamsRef","setText","value","newVal","prev","setCompletedParams","onErrorRef","optionOverridesRef","maskCompletedTextRef","apiConfigRef","textRef","suggestionsRef","filterBaseRef","filterInProgressRef","pillTappedRef","skipNextFetchRef","listboxId","doFetch","isLoading","error","isReady","lastRawQueryRef","useAutocompleteFetch","useDebouncedFetch","segments","deriveSegments","filterQuery","extractFilterQuery","placeholderText","s","actionableSuggestions","activeSuggestion","overrideFn","baseOptions","filteredOptions","filterOptions","hasPlaceholder","isDropdownOpen","selectOption","option","base","prefix","inputWasEmpty","lastWord","needsSpace","newText","finalText","optionStart","optionInFinal","completed","handleChange","e","raw","newValue","valid","invalid","reconcileParams","param","newFilterQuery","match","findExactMatch","pills","useAutocompletePills","reEditParam","handleKeyDown","useAutocompleteKeyboard","reset","activeDescendantId","import_jsx_runtime","AIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","placeholder","className","apiConfig","columns","typewriterEffect","value","controlledParams","onChangeProp","onParamsChange","ref","textareaRef","handleSubmitRef","revealCount","setRevealCount","revealTimerRef","completedParams","suggestionPills","setActivePill","segments","newParamId","clearNewParamId","inputProps","dropdownProps","reset","useAIAutocomplete","result","param","p","totalChars","timeoutId","startTime","duration","tick","elapsed","progress","chars","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","cls","total","revealed","hidden","bgPos","PillList","e"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/AIAutocomplete.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocomplete.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/AIAutocompleteDropdown.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/PillList.module.css.js","../src/components/PillList.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionGrid.module.css.js","../src/components/SuggestionItem.tsx","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionGrid.tsx","../src/AIAutocompleteDropdown.tsx","../src/hooks/useAIAutocomplete.ts","../src/utils/filtering.ts","../src/utils/modeController.ts","../src/utils/segments.ts","../src/utils/tokenManager.ts","../src/utils/api.ts","../src/utils/buildQuery.ts","../src/utils/overrides.ts","../src/core/controllers/fetchController.ts","../src/core/controllers/keyboardController.ts","../src/core/controllers/pillsController.ts","../src/core/render/renderPills.ts","../src/core/render/renderDropdown.ts","../src/core/render/renderDropdownOnly.ts","../src/core/render/renderSegments.ts","../src/core/render/renderInput.ts","../src/core/state.ts","../src/core/styleInjector.ts","../src/core/AIAutocomplete.ts"],"sourcesContent":["export { AIAutocomplete } from \"./AIAutocomplete\";\nexport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nexport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nexport type {\n AccessTokenConfig,\n AccessTokenResult,\n AIAutocompleteDropdownProps,\n AIAutocompleteHandle,\n AIAutocompleteProps,\n APIConfig,\n APIKeyConfig,\n AppearanceMode,\n AutocompleteResult,\n CompletedParam,\n CompletedParamState,\n OptionOverrides,\n Segment,\n Suggestion,\n SuggestionOption,\n TaskKind,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"./types\";\n","import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from \"react\";\nimport styles from \"./AIAutocomplete.module.css\";\nimport { AIAutocompleteDropdown } from \"./AIAutocompleteDropdown\";\nimport \"./appearance.css\";\nimport { PillList } from \"./components/PillList\";\nimport { useAIAutocomplete } from \"./hooks/useAIAutocomplete\";\nimport type {\n AIAutocompleteHandle,\n AIAutocompleteProps,\n AppearanceMode,\n AutocompleteResult,\n} from \"./types\";\nimport { buildQuery } from \"./utils/buildQuery\";\nimport { ModeController } from \"./utils/modeController\";\n\nfunction resolveInitialMode(mode: AppearanceMode): \"light\" | \"dark\" {\n if (mode !== \"auto\") return mode;\n if (typeof window === \"undefined\") return \"dark\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n}\n\nexport const AIAutocomplete = forwardRef<AIAutocompleteHandle, AIAutocompleteProps>(\n function AIAutocomplete(\n {\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n className,\n apiConfig,\n columns,\n pillPlacement = \"inline\",\n mode = \"auto\",\n optionsPosition = \"below\",\n animations = true,\n dropdownTrigger,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n },\n ref,\n ) {\n const containerRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n // Render-phase ref assignment — matches the pattern in useAIAutocomplete.ts\n const handleSubmitRef = useRef<(result: AutocompleteResult) => void>(() => {});\n const modeControllerRef = useRef<ModeController | null>(null);\n\n useEffect(() => {\n textareaRef.current?.focus();\n }, []);\n\n // ModeController — keeps data-mode updated for live prefers-color-scheme changes\n // Initial data-mode is set synchronously in JSX via resolveInitialMode()\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n if (modeControllerRef.current) {\n modeControllerRef.current.setMode(mode);\n } else {\n modeControllerRef.current = new ModeController(el, mode);\n }\n return () => {\n modeControllerRef.current?.destroy();\n modeControllerRef.current = null;\n };\n }, [mode]);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\n newParamId,\n clearNewParamId,\n inputProps,\n dropdownProps,\n reset,\n } = useAIAutocomplete({\n onSubmit: (result) => handleSubmitRef.current(result),\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder,\n apiConfig,\n columns,\n dropdownTrigger,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\n\n // Clear shimmer after animation completes\n useEffect(() => {\n if (!newParamId) return;\n const timeoutId = window.setTimeout(() => clearNewParamId(), 650);\n return () => window.clearTimeout(timeoutId);\n }, [newParamId, clearNewParamId]);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => textareaRef.current?.focus(),\n reset,\n setMode: (m) => modeControllerRef.current?.setMode(m),\n }),\n [reset],\n );\n\n const handleContainerClick = () => {\n textareaRef.current?.focus();\n };\n\n const canSubmit = !!inputProps.value || completedParams.length > 0;\n\n const handleSubmit = useCallback(() => {\n if (!canSubmit) return;\n const { rawQuery, completedParams: finalParams } = buildQuery(\n inputProps.value,\n completedParams,\n );\n onSubmit({\n query: inputProps.value.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n reset();\n }, [canSubmit, inputProps.value, completedParams, onSubmit, reset]);\n\n handleSubmitRef.current = handleSubmit;\n\n const { onChange, placeholder: inputPlaceholder, ...restProps } = inputProps;\n const isEmpty = !inputProps.value;\n\n const showInlinePills = pillPlacement === \"inline\";\n const showDropdownPills = pillPlacement === \"dropdown\";\n\n return (\n <div\n ref={containerRef}\n className={`magicx-aia ${styles.container} ${className ?? \"\"}`}\n data-pill-placement={pillPlacement}\n data-options-position={optionsPosition}\n data-animations={animations ? \"on\" : \"off\"}\n data-mode={resolveInitialMode(mode)}\n >\n <AIAutocompleteDropdown {...dropdownProps} showPills={showDropdownPills} />\n {/* biome-ignore lint/a11y/useKeyWithClickEvents: container click delegates to textarea focus */}\n {/* biome-ignore lint/a11y/noStaticElementInteractions: wrapper delegates focus to textarea */}\n <div className={styles.inputWrapper} onClick={handleContainerClick}>\n <div className={styles.editorArea}>\n <div className={styles.sizerContent} aria-hidden=\"true\">\n {isEmpty && inputPlaceholder ? (\n <span className={styles.placeholderText}>{inputPlaceholder} </span>\n ) : (\n <span\n className={`${styles.sizerText} ${newParamId ? styles.sizerTextVisible : \"\"}`}\n >\n {segments.map((seg, i) => {\n const isNew = seg.type === \"completed\" && seg.param.id === newParamId;\n if (isNew) {\n const cls = `${styles.shimmerRevealed} ${styles.shimmerSweep}`;\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`} className={cls}>\n {seg.value}\n </span>\n );\n }\n return (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\n );\n })}\n {segments.length === 0 && \"\\u00A0\"}\n </span>\n )}\n {\" \"}\n {showInlinePills && (\n <PillList\n pills={suggestionPills}\n activePillIndex={0}\n onSelectPill={setActivePill}\n />\n )}\n </div>\n <textarea\n ref={textareaRef}\n className={`${styles.textarea} ${newParamId ? styles.textareaHidden : \"\"}`}\n rows={1}\n onChange={onChange}\n {...restProps}\n />\n </div>\n <button\n type=\"button\"\n className={styles.submitButton}\n disabled={!canSubmit}\n onClick={(e) => {\n e.stopPropagation();\n handleSubmit();\n }}\n aria-label=\"Submit\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n role=\"img\"\n aria-label=\"Submit\"\n >\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n );\n },\n);\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-cc65f4cc\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-cc65f4cc\";\n s.textContent = `.AIAutocomplete-module_container_KKjFU {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.AIAutocomplete-module_inputWrapper_FLq1b {\n min-height: 60px;\n padding: 24px;\n border: 1px solid var(--aia-color-border-default, #9ea5b2);\n border-radius: 23px;\n background: transparent;\n overflow: hidden;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.AIAutocomplete-module_editorArea_7rBWq {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.AIAutocomplete-module_sizerContent_DQgmV {\n position: relative;\n z-index: 1;\n pointer-events: none;\n min-height: 60px;\n white-space: pre-wrap;\n word-break: break-word;\n font-family: inherit;\n font-size: var(--aia-written-text-font-size, 19px);\n line-height: 38px;\n}\n\n.AIAutocomplete-module_sizerText_iZIMK {\n color: transparent;\n}\n\n.AIAutocomplete-module_sizerTextVisible_HR-5h {\n color: var(--aia-written-text-color, var(--aia-color-text-default, #fff));\n font-size: var(--aia-written-text-font-size, inherit);\n}\n\n.AIAutocomplete-module_textareaHidden_UayJt {\n color: transparent !important;\n}\n\n.AIAutocomplete-module_placeholderText_K3ayy {\n color: var(--aia-color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.AIAutocomplete-module_textarea_eyn6A {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--aia-written-text-color, var(--aia-color-text-default, #fff));\n caret-color: var(--aia-written-text-color, var(--aia-color-text-default, #fff));\n font-family: inherit;\n font-size: var(--aia-written-text-font-size, 19px);\n line-height: 38px;\n white-space: pre-wrap;\n word-break: break-word;\n outline: none;\n resize: none;\n overflow: hidden;\n}\n\n.AIAutocomplete-module_textarea_eyn6A::placeholder {\n color: var(--aia-color-text-muted, #c1c4cb);\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: var(--aia-color-text-default, #fff);\n color: var(--aia-color-bg-default, #000);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n transition: opacity 0.2s ease;\n}\n\n.AIAutocomplete-module_submitButton_sl1Mi:hover {\n opacity: 0.85;\n}\n\n/* Text shimmer on newly added completed param.\n The sizer sits above the textarea (z-index: 1). Normally sizer text is\n transparent and the textarea shows the real text. During the shimmer, we\n make this span visible with a moving gradient clipped to the text shape,\n so the shimmer renders on top of the textarea's static white text. */\n\n.AIAutocomplete-module_shimmer_13AnY {\n position: relative;\n z-index: 2;\n display: inline;\n}\n\n.AIAutocomplete-module_shimmerRevealed_RR8dp {\n color: transparent;\n background: linear-gradient(\n 120deg,\n var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 0%,\n var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 44%,\n #b0b0b0 48%,\n #b0b0b0 52%,\n var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 56%,\n var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 100%\n );\n background-size: 200% 100%;\n -webkit-background-clip: text;\n background-clip: text;\n}\n\n.AIAutocomplete-module_shimmerSweep_ARCon {\n animation: AIAutocomplete-module_textShimmer_eCLdq 650ms ease-out forwards;\n}\n\n@keyframes AIAutocomplete-module_textShimmer_eCLdq {\n 0% {\n background-position: 100% 0;\n }\n 100% {\n background-position: -50% 0;\n }\n}\n\n.AIAutocomplete-module_shimmerHidden_45-Pf {\n color: transparent !important;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"container\":\"AIAutocomplete-module_container_KKjFU\",\"inputWrapper\":\"AIAutocomplete-module_inputWrapper_FLq1b\",\"editorArea\":\"AIAutocomplete-module_editorArea_7rBWq\",\"sizerContent\":\"AIAutocomplete-module_sizerContent_DQgmV\",\"sizerText\":\"AIAutocomplete-module_sizerText_iZIMK\",\"sizerTextVisible\":\"AIAutocomplete-module_sizerTextVisible_HR-5h\",\"textareaHidden\":\"AIAutocomplete-module_textareaHidden_UayJt\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\",\"shimmer\":\"AIAutocomplete-module_shimmer_13AnY\",\"shimmerRevealed\":\"AIAutocomplete-module_shimmerRevealed_RR8dp\",\"shimmerSweep\":\"AIAutocomplete-module_shimmerSweep_ARCon\",\"textShimmer\":\"AIAutocomplete-module_textShimmer_eCLdq\",\"shimmerHidden\":\"AIAutocomplete-module_shimmerHidden_45-Pf\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-2eef895d\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-2eef895d\";\n s.textContent = `.AIAutocompleteDropdown-module_dropdown_yz2KC {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 6px;\n border-radius: 1rem;\n overflow: hidden;\n z-index: 10;\n opacity: 0;\n pointer-events: none;\n transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1);\n background: transparent;\n backdrop-filter: blur(12px);\n}\n\n.AIAutocompleteDropdown-module_visible_QCoXj {\n opacity: 1;\n pointer-events: auto;\n}\n\n.AIAutocompleteDropdown-module_pillBar_pwTXe {\n padding: 27px 27px 0px 27px;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"dropdown\":\"AIAutocompleteDropdown-module_dropdown_yz2KC\",\"visible\":\"AIAutocompleteDropdown-module_visible_QCoXj\",\"pillBar\":\"AIAutocompleteDropdown-module_pillBar_pwTXe\"};","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-b745b4fb\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-b745b4fb\";\n s.textContent = `.PillList-module_list_qvLqO {\n position: relative;\n z-index: 1;\n pointer-events: auto;\n display: inline-flex;\n gap: 5px;\n align-items: center;\n vertical-align: middle;\n transform: translateY(-3px);\n}\n\n.PillList-module_pill_osSyz {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n padding: 13px 13px;\n border: none;\n border-radius: 999px;\n background: rgba(49, 50, 85, 0.25);\n background: color-mix(\n in srgb,\n var(--aia-pill-bg, var(--aia-color-background-supportive, #313255)) 25%,\n transparent\n );\n color: var(--aia-pill-color, var(--aia-color-text-muted, #c1c4cb));\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: var(--aia-pill-font-size, 19px);\n line-height: 30px;\n cursor: pointer;\n white-space: nowrap;\n animation: PillList-module_fadeIn_Aezob 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.PillList-module_rounded_WvXy4 {\n border-radius: 999px;\n}\n\n.PillList-module_pill_osSyz:hover {\n filter: brightness(1.2);\n}\n\n.PillList-module_active_Oll-- {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes PillList-module_fadeIn_Aezob {\n from {\n opacity: 0;\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"list\":\"PillList-module_list_qvLqO\",\"pill\":\"PillList-module_pill_osSyz\",\"fadeIn\":\"PillList-module_fadeIn_Aezob\",\"rounded\":\"PillList-module_rounded_WvXy4\",\"active\":\"PillList-module_active_Oll--\"};","import type { Suggestion } from \"../types\";\nimport styles from \"./PillList.module.css\";\n\ninterface PillListProps {\n pills: Suggestion[];\n activePillIndex: number;\n onSelectPill: (index: number) => void;\n /** Use capsule-shaped pills (fully rounded). Default: false. */\n rounded?: boolean;\n}\n\nfunction getPillOpacity(index: number): number {\n if (index === 0) return 0.4;\n if (index === 1) return 0.3;\n return 0.15;\n}\n\nexport function PillList({ pills, activePillIndex, onSelectPill, rounded }: PillListProps) {\n return (\n <span className={styles.list}>\n {pills.map((pill, i) => (\n <button\n key={`${pill.type}-${pill.text}`}\n type=\"button\"\n className={`${styles.pill} ${rounded ? styles.rounded : \"\"} ${i === activePillIndex ? styles.active : \"\"}`}\n style={{ opacity: getPillOpacity(i) }}\n onClick={() => onSelectPill(i)}\n >\n {pill.text}\n </button>\n ))}\n </span>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-d91f2b06\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-d91f2b06\";\n s.textContent = `.SuggestionGrid-module_grid_jvaPb {\n display: grid;\n grid-template-columns: 1fr 1fr;\n padding: 13px 13px;\n max-height: 192px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: rgba(255, 255, 255, 0.3) transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar {\n width: 6px;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.SuggestionGrid-module_grid_jvaPb::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"grid\":\"SuggestionGrid-module_grid_jvaPb\"};","import { useEffect, useRef, useState } from \"react\";\nimport type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionItem.module.css\";\n\ninterface SuggestionItemProps {\n option: SuggestionOption;\n isHighlighted: boolean;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: () => void;\n id: string;\n}\n\nexport function SuggestionItem({\n option,\n isHighlighted,\n onSelect,\n onHighlight,\n id,\n}: SuggestionItemProps) {\n const [pressed, setPressed] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n useEffect(() => {\n return () => clearTimeout(timerRef.current);\n }, []);\n\n const handleSelect = () => {\n if (!option.is_tappable || pressed) return;\n setPressed(true);\n onSelect(option);\n clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setPressed(false), 400);\n };\n\n const className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\n pressed ? styles.pressed : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n id={id}\n role=\"option\"\n aria-selected={isHighlighted}\n className={className}\n tabIndex={option.is_tappable ? 0 : -1}\n onClick={handleSelect}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleSelect();\n }\n }}\n onMouseEnter={onHighlight}\n >\n <div className={styles.streaks} />\n <div className={styles.streaksVert} />\n <span className={styles.content}>\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </span>\n </div>\n );\n}\n","if (typeof document !== \"undefined\" && !document.getElementById(\"ac-style-f6bdc634\")) {\n const s = document.createElement(\"style\");\n s.id = \"ac-style-f6bdc634\";\n s.textContent = `.SuggestionItem-module_item_d4vpD {\n position: relative;\n overflow: visible;\n display: flex;\n align-items: center;\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: var(--aia-option-font-size, 19px);\n line-height: 30px;\n color: var(--aia-option-color, var(--aia-color-text-muted, #c1c4cb));\n white-space: normal;\n word-break: break-word;\n opacity: 0.4;\n border-radius: 12px;\n padding: 13px 13px;\n animation: SuggestionItem-module_fadeIn_I8u35 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes SuggestionItem-module_fadeIn_I8u35 {\n from {\n opacity: 0;\n }\n}\n\n.SuggestionItem-module_content_T-Qba {\n position: relative;\n z-index: 2;\n}\n\n.SuggestionItem-module_tappable_70KcX {\n cursor: pointer;\n}\n\n.SuggestionItem-module_tappable_70KcX:hover {\n color: var(--aia-option-color-selected, var(--aia-color-text-default, #fff));\n}\n\n.SuggestionItem-module_nonTappable_xSZM- {\n cursor: default;\n opacity: 0.3;\n}\n\n.SuggestionItem-module_highlighted_Hb0SU {\n color: var(--aia-option-color-selected, var(--aia-color-text-default, #fff));\n background: var(--aia-option-bg, transparent);\n opacity: 0.5;\n}\n\n.SuggestionItem-module_tag_e3Fwe {\n font-size: 11px;\n margin-left: 6px;\n opacity: 0.5;\n}\n\n.SuggestionItem-module_pressed_98o-r {\n opacity: 0.8;\n color: var(--aia-color-text-default, #fff);\n background: rgba(255, 255, 255, 0.06);\n animation:\n SuggestionItem-module_glassFade_oyiSj 500ms ease forwards,\n SuggestionItem-module_tapDown_G3WGz 500ms ease forwards;\n}\n\n@keyframes SuggestionItem-module_tapDown_G3WGz {\n 0% {\n transform: scale(1);\n }\n 30% {\n transform: scale(0.97);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes SuggestionItem-module_glassFade_oyiSj {\n 0% {\n background: rgba(255, 255, 255, 0.1);\n }\n 100% {\n background: transparent;\n }\n}\n\n/* Border streaks — horizontal segments */\n\n.SuggestionItem-module_streaks_d9PEB {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Bottom horizontal: 40% from right → right corner */\n.SuggestionItem-module_streaks_d9PEB::before {\n content: \"\";\n position: absolute;\n bottom: -3px;\n left: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Top horizontal: 40% from left → left corner */\n.SuggestionItem-module_streaks_d9PEB::after {\n content: \"\";\n position: absolute;\n top: -3px;\n right: 60%;\n width: 0;\n height: 6px;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.5) 0%,\n rgba(255, 255, 255, 0.2) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.2);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Border streaks — vertical segments */\n\n.SuggestionItem-module_streaksVert_ERlV1 {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n border-radius: inherit;\n overflow: hidden;\n}\n\n/* Right vertical: bottom-right corner → up */\n.SuggestionItem-module_streaksVert_ERlV1::before {\n content: \"\";\n position: absolute;\n bottom: 0;\n right: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n/* Left vertical: top-left corner → down */\n.SuggestionItem-module_streaksVert_ERlV1::after {\n content: \"\";\n position: absolute;\n top: 0;\n left: -3px;\n width: 6px;\n height: 0;\n background: radial-gradient(\n ellipse at center,\n rgba(255, 255, 255, 0.4) 0%,\n rgba(255, 255, 255, 0.15) 40%,\n transparent 70%\n );\n box-shadow: 0 0 12px 4px rgba(255, 255, 255, 0.15);\n filter: blur(1px);\n border-radius: 50%;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::before {\n animation: SuggestionItem-module_streakHorizRight_aboGz 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaks_d9PEB::after {\n animation: SuggestionItem-module_streakHorizLeft_BreWJ 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::before {\n animation: SuggestionItem-module_streakVertUp_to1GD 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n.SuggestionItem-module_pressed_98o-r .SuggestionItem-module_streaksVert_ERlV1::after {\n animation: SuggestionItem-module_streakVertDown_OrcLh 300ms cubic-bezier(0.3, 0, 0.2, 1) 200ms forwards;\n}\n\n/* Horizontal: bottom center-ish → right edge */\n@keyframes SuggestionItem-module_streakHorizRight_aboGz {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Horizontal: top center-ish → left edge */\n@keyframes SuggestionItem-module_streakHorizLeft_BreWJ {\n 0% {\n width: 0;\n height: 4px;\n opacity: 0;\n filter: blur(1px);\n box-shadow: 0 0 8px 3px rgba(255, 255, 255, 0.3);\n }\n 15% {\n height: 4px;\n opacity: 1;\n filter: blur(1px);\n box-shadow: 0 0 10px 4px rgba(255, 255, 255, 0.3);\n }\n 80% {\n width: 50%;\n height: 10px;\n opacity: 0.8;\n filter: blur(3px);\n box-shadow: 0 0 16px 6px rgba(255, 255, 255, 0.1);\n }\n 100% {\n width: 50%;\n height: 12px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 20px 8px rgba(255, 255, 255, 0.03);\n }\n}\n\n/* Vertical segments start matching horizontal state at 200ms handoff */\n@keyframes SuggestionItem-module_streakVertUp_to1GD {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n\n@keyframes SuggestionItem-module_streakVertDown_OrcLh {\n 0% {\n height: 0;\n width: 6px;\n opacity: 0.9;\n filter: blur(1.8px);\n box-shadow: 0 0 12px 5px rgba(255, 255, 255, 0.25);\n }\n 75% {\n height: 100%;\n width: 10px;\n opacity: 0.4;\n filter: blur(3px);\n box-shadow: 0 0 18px 8px rgba(255, 255, 255, 0.06);\n }\n 100% {\n height: 100%;\n width: 14px;\n opacity: 0;\n filter: blur(5px);\n box-shadow: 0 0 24px 10px rgba(255, 255, 255, 0.02);\n }\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"content\":\"SuggestionItem-module_content_T-Qba\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\",\"pressed\":\"SuggestionItem-module_pressed_98o-r\",\"glassFade\":\"SuggestionItem-module_glassFade_oyiSj\",\"tapDown\":\"SuggestionItem-module_tapDown_G3WGz\",\"streaks\":\"SuggestionItem-module_streaks_d9PEB\",\"streaksVert\":\"SuggestionItem-module_streaksVert_ERlV1\",\"streakHorizRight\":\"SuggestionItem-module_streakHorizRight_aboGz\",\"streakHorizLeft\":\"SuggestionItem-module_streakHorizLeft_BreWJ\",\"streakVertUp\":\"SuggestionItem-module_streakVertUp_to1GD\",\"streakVertDown\":\"SuggestionItem-module_streakVertDown_OrcLh\"};","import type { SuggestionOption } from \"../types\";\nimport styles from \"./SuggestionGrid.module.css\";\nimport { SuggestionItem } from \"./SuggestionItem\";\n\ninterface SuggestionGridProps {\n options: SuggestionOption[];\n activeIndex: number;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: (index: number) => void;\n listboxId: string;\n}\n\nexport function SuggestionGrid({\n options,\n activeIndex,\n onSelect,\n onHighlight,\n listboxId,\n}: SuggestionGridProps) {\n return (\n <div className={styles.grid}>\n {options.map((option, i) => (\n <SuggestionItem\n key={option.text}\n option={option}\n isHighlighted={i === activeIndex}\n onSelect={onSelect}\n onHighlight={() => onHighlight(i)}\n id={`${listboxId}-option-${i}`}\n />\n ))}\n </div>\n );\n}\n","import styles from \"./AIAutocompleteDropdown.module.css\";\nimport { PillList } from \"./components/PillList\";\nimport { SuggestionGrid } from \"./components/SuggestionGrid\";\nimport type { AIAutocompleteDropdownProps } from \"./types\";\n\nexport function AIAutocompleteDropdown({\n suggestions,\n activeIndex,\n onSelect,\n onHighlight,\n isOpen,\n id,\n className,\n pills,\n onPillClick,\n showPills = true,\n}: AIAutocompleteDropdownProps) {\n const activeSuggestion = suggestions[0];\n const options = activeSuggestion?.options ?? [];\n const hasPills = showPills && pills && pills.length > 0 && onPillClick;\n const hasOptions = isOpen && options.length > 0;\n const isVisible = hasOptions || (isOpen && hasPills);\n\n return (\n <div\n id={id}\n role=\"listbox\"\n data-aia-dropdown=\"\"\n className={`${styles.dropdown} ${isVisible ? styles.visible : \"\"} ${className ?? \"\"}`}\n onMouseDown={(e) => e.preventDefault()}\n >\n {hasPills && (\n <div className={styles.pillBar}>\n <PillList pills={pills} activePillIndex={0} onSelectPill={onPillClick} rounded />\n </div>\n )}\n {options.length > 0 && (\n <SuggestionGrid\n options={options}\n activeIndex={activeIndex}\n onSelect={onSelect}\n onHighlight={onHighlight}\n listboxId={id}\n />\n )}\n </div>\n );\n}\n","import {\n type ChangeEvent,\n type KeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { AIAutocomplete as CoreAIAutocomplete } from \"../core/AIAutocomplete\";\nimport type { CoreState } from \"../core/types\";\nimport type {\n Suggestion,\n SuggestionOption,\n UseAIAutocompleteOptions,\n UseAIAutocompleteReturn,\n} from \"../types\";\n\nexport function useAIAutocomplete({\n onSubmit,\n onError,\n optionOverrides,\n maskCompletedText,\n placeholder: customPlaceholder,\n apiConfig,\n columns = 2,\n dropdownTrigger,\n value: controlledValue,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n}: UseAIAutocompleteOptions): UseAIAutocompleteReturn {\n const instanceRef = useRef<CoreAIAutocomplete | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n // Refs for callbacks to avoid stale closures\n const onSubmitRef = useRef(onSubmit);\n onSubmitRef.current = onSubmit;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onChangeRef = useRef(onChangeProp);\n onChangeRef.current = onChangeProp;\n const onParamsChangeRef = useRef(onParamsChange);\n onParamsChangeRef.current = onParamsChange;\n\n // Create headless core instance once (guard for SSR where document is undefined)\n if (!instanceRef.current && typeof document !== \"undefined\") {\n instanceRef.current = new CoreAIAutocomplete(document.createElement(\"div\"), {\n renderMode: \"headless\",\n apiConfig,\n optionOverrides,\n maskCompletedText,\n placeholder: customPlaceholder,\n columns,\n dropdownTrigger,\n value: controlledValue,\n completedParams: controlledParams,\n onSubmit: (...args) => onSubmitRef.current?.(...args),\n onError: (...args) => onErrorRef.current?.(...args),\n onChange: (...args) => onChangeRef.current?.(...args),\n onParamsChange: (...args) => onParamsChangeRef.current?.(...args),\n });\n }\n\n const instance = instanceRef.current;\n\n // SSR bail-out — no instance, return safe empty defaults\n // Hooks below are unconditional (React rules of hooks) but guarded internally\n const noop = useCallback(() => {}, []);\n\n // Subscribe to core state changes\n useEffect(() => {\n if (!instance) return;\n setCoreState(instance.getState());\n const unsub = instance.subscribe((state) => {\n setCoreState(state);\n });\n return () => {\n unsub();\n instance.destroy();\n instanceRef.current = null;\n };\n }, [instance]);\n\n // Sync controlled value\n useEffect(() => {\n if (controlledValue !== undefined) instance?.setValue(controlledValue);\n }, [controlledValue, instance]);\n\n // Sync controlled params\n useEffect(() => {\n if (controlledParams !== undefined) instance?.setCompletedParams(controlledParams);\n }, [controlledParams, instance]);\n\n // Sync apiConfig/optionOverrides/dropdownTrigger when values change\n const apiConfigJson = JSON.stringify(apiConfig ?? null);\n const prevOverridesRef = useRef(optionOverrides);\n const overridesVersion = useRef(0);\n if (optionOverrides !== prevOverridesRef.current) {\n const prev = prevOverridesRef.current;\n const next = optionOverrides;\n const prevKeys = Object.keys(prev ?? {});\n const nextKeys = Object.keys(next ?? {});\n if (\n prevKeys.length !== nextKeys.length ||\n nextKeys.some(\n (k) =>\n !(prev as Record<string, unknown>)?.[k] ||\n (next as Record<string, unknown>)[k] !== (prev as Record<string, unknown>)[k],\n )\n ) {\n overridesVersion.current++;\n }\n prevOverridesRef.current = optionOverrides;\n }\n // biome-ignore lint/correctness/useExhaustiveDependencies: overridesVersion tracks shallow changes to fn-valued optionOverrides\n useEffect(() => {\n instance?.update({ apiConfig, optionOverrides, dropdownTrigger });\n }, [apiConfigJson, overridesVersion.current, dropdownTrigger, instance]);\n\n // Handle text change from textarea\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLTextAreaElement>) => {\n if (!instance) return;\n const raw = e.target.value;\n const shouldCapitalize =\n raw.length > 0 &&\n !(e.nativeEvent as InputEvent)?.isComposing &&\n raw[0] !== raw[0].toUpperCase();\n const newValue = shouldCapitalize ? raw[0].toUpperCase() + raw.slice(1) : raw;\n instance.handleTextChange(newValue);\n },\n [instance],\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n instance?.handleKeyDown(e.nativeEvent);\n },\n [instance],\n );\n\n // Actions\n const setActivePill = useCallback((index: number) => instance?.setActivePill(index), [instance]);\n const removeLastParam = useCallback(() => instance?.removeLastParam(), [instance]);\n const clearNewParamId = useCallback(() => instance?.clearNewParamId(), [instance]);\n const reset = useCallback(() => instance?.reset(), [instance]);\n const selectOption = useCallback(\n (option: SuggestionOption) => instance?.selectOption(option),\n [instance],\n );\n const setActiveDropdownIndex = useCallback(\n (index: number) => instance?.setActiveDropdownIndex(index),\n [instance],\n );\n\n // No instance (SSR) — return safe defaults\n if (!instance) {\n return {\n completedParams: controlledParams ?? [],\n suggestionPills: [],\n setActivePill: noop,\n removeLastParam: noop,\n segments: [],\n newParamId: null,\n clearNewParamId: noop,\n suggestions: [],\n activeIndex: -1,\n isReady: false,\n isLoading: true,\n error: null,\n inputProps: {\n value: controlledValue ?? \"\",\n placeholder: customPlaceholder,\n onChange: noop as unknown as UseAIAutocompleteReturn[\"inputProps\"][\"onChange\"],\n onKeyDown: noop as unknown as UseAIAutocompleteReturn[\"inputProps\"][\"onKeyDown\"],\n role: \"combobox\" as const,\n \"aria-expanded\": false,\n \"aria-activedescendant\": undefined,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-controls\": \"\",\n },\n reset: noop,\n dropdownProps: {\n suggestions: [],\n activeIndex: -1,\n onSelect: noop as unknown as (option: SuggestionOption) => void,\n onHighlight: noop as unknown as (index: number) => void,\n isOpen: false,\n id: \"\",\n pills: [],\n onPillClick: noop as unknown as (index: number) => void,\n },\n };\n }\n\n // Derive current state\n const state = coreState ?? instance.getState();\n const text = controlledValue !== undefined ? controlledValue : state.text;\n const completedParams = controlledParams !== undefined ? controlledParams : state.completedParams;\n\n const actionableSuggestions = state.actionableSuggestions;\n const activeSuggestion: Suggestion | undefined = actionableSuggestions[0];\n const filteredOptions = state.filteredOptions;\n\n const activeDescendantId =\n state.activeDropdownIndex >= 0\n ? `${instance.listboxId}-option-${state.activeDropdownIndex}`\n : undefined;\n\n return {\n completedParams,\n suggestionPills: actionableSuggestions,\n setActivePill,\n removeLastParam,\n segments: state.segments,\n newParamId: state.newParamId,\n clearNewParamId,\n suggestions: state.suggestions,\n activeIndex: state.activeDropdownIndex,\n isReady: state.isReady,\n isLoading: state.isLoading,\n error: state.error,\n inputProps: {\n value: text,\n placeholder: state.placeholderText || undefined,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n role: \"combobox\" as const,\n \"aria-expanded\": state.isDropdownOpen,\n \"aria-activedescendant\": activeDescendantId,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-controls\": instance.listboxId,\n },\n reset,\n dropdownProps: {\n suggestions: activeSuggestion ? [{ ...activeSuggestion, options: filteredOptions }] : [],\n activeIndex: state.activeDropdownIndex,\n onSelect: selectOption,\n onHighlight: setActiveDropdownIndex,\n isOpen: state.isDropdownOpen,\n id: instance.listboxId,\n pills: actionableSuggestions,\n onPillClick: setActivePill,\n },\n };\n}\n","import type { SuggestionOption } from \"../types\";\n\n/**\n * Extracts the effective filter query from the region after filterBase.\n * If the server marked the region as in_progress, the full region is used.\n * Otherwise, filtering only starts after the first space (to avoid filtering\n * mid-word when the user continues typing a word that was already in the input).\n */\nexport function extractFilterQuery(\n text: string,\n filterBase: number,\n isInProgress: boolean,\n): string {\n const rawRegion = text.slice(filterBase);\n if (isInProgress || filterBase === 0 || text[filterBase - 1] === \" \") {\n return rawRegion;\n }\n const spaceIdx = rawRegion.indexOf(\" \");\n return spaceIdx === -1 ? \"\" : rawRegion.slice(spaceIdx + 1);\n}\n\n/**\n * Finds the longest word-boundary-aligned suffix of `prefix` that matches a\n * prefix of `optionText` (case-insensitive). Returns the number of characters\n * to remove from the end of `prefix` to avoid duplication.\n */\nexport function findPrefixOverlap(prefix: string, optionText: string): number {\n // Normalize internal whitespace so words.join(\" \") roundtrips losslessly\n const trimmed = prefix.trimEnd().replace(/\\s+/g, \" \");\n if (trimmed.length === 0 || optionText.length === 0) return 0;\n\n const words = trimmed.split(\" \");\n const optionLower = optionText.toLowerCase();\n\n // Try from longest suffix (all words) to shortest (last word only)\n for (let i = 0; i < words.length; i++) {\n const candidate = words.slice(i).join(\" \");\n if (optionLower.startsWith(candidate.toLowerCase())) {\n const suffixStart = trimmed.length - candidate.length;\n return prefix.length - suffixStart;\n }\n }\n\n return 0;\n}\n\n/**\n * Filters options using partial substring match on the text after the last completed param.\n */\nexport function filterOptions(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption[] {\n if (!options) return [];\n const trimmed = query.trimStart();\n if (!trimmed) return options;\n const lower = trimmed.toLowerCase();\n return options.filter((o) => !o.is_tappable || o.text.toLowerCase().includes(lower));\n}\n\n/**\n * Finds an exact match for the trimmed filter query against options.\n */\nexport function findExactMatch(\n options: SuggestionOption[] | undefined,\n query: string,\n): SuggestionOption | null {\n if (!options) return null;\n const trimmed = query.trim();\n if (!trimmed) return null;\n const lower = trimmed.toLowerCase();\n return options.find((o) => o.is_tappable && o.text.toLowerCase() === lower) ?? null;\n}\n","import type { AppearanceMode } from \"../types\";\n\nexport class ModeController {\n private mediaQuery: MediaQueryList | null = null;\n\n constructor(\n private container: HTMLElement,\n private mode: AppearanceMode = \"auto\",\n ) {\n this.apply();\n }\n\n setMode(mode: AppearanceMode) {\n this.detachListener();\n this.mode = mode;\n this.apply();\n }\n\n destroy() {\n this.detachListener();\n }\n\n private apply() {\n if (this.mode === \"auto\") {\n this.mediaQuery ??= window.matchMedia(\"(prefers-color-scheme: dark)\");\n this.mediaQuery.addEventListener(\"change\", this.onSystemChange);\n this.container.dataset.mode = this.mediaQuery.matches ? \"dark\" : \"light\";\n } else {\n this.container.dataset.mode = this.mode;\n }\n }\n\n private onSystemChange = (e: MediaQueryListEvent) => {\n this.container.dataset.mode = e.matches ? \"dark\" : \"light\";\n };\n\n private detachListener() {\n this.mediaQuery?.removeEventListener(\"change\", this.onSystemChange);\n }\n}\n","import type { CompletedParamState, Segment } from \"../types\";\n\n/**\n * Derives segments for overlay rendering by matching completed params in text.\n */\nexport function deriveSegments(text: string, completedParams: CompletedParamState[]): Segment[] {\n const result: Segment[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) continue;\n if (idx > pos) {\n result.push({ type: \"text\", value: text.slice(pos, idx) });\n }\n result.push({ type: \"completed\", value: param.text, param });\n pos = idx + param.text.length;\n }\n\n const remaining = text.slice(pos);\n if (remaining) {\n result.push({ type: \"text\", value: remaining });\n }\n\n return result;\n}\n\n/**\n * Checks which completed params still exist in the new text.\n */\nexport function reconcileParams(\n text: string,\n completedParams: CompletedParamState[],\n): { valid: CompletedParamState[]; invalid: CompletedParamState[] } {\n const valid: CompletedParamState[] = [];\n const invalid: CompletedParamState[] = [];\n let pos = 0;\n\n for (const param of completedParams) {\n const idx = text.indexOf(param.text, pos);\n if (idx === -1) {\n invalid.push(param);\n } else {\n valid.push(param);\n pos = idx + param.text.length;\n }\n }\n\n return { valid, invalid };\n}\n","import type { AccessTokenConfig } from \"../types\";\n\n/** Refresh 30 seconds before stated expiry to absorb clock drift and request latency. */\nconst REFRESH_SKEW_MS = 30_000;\n\nexport class TokenManager {\n private current: string | null = null;\n private expiresAt: number | null = null;\n private inFlightRefresh: Promise<string> | null = null;\n\n constructor(private config: AccessTokenConfig) {\n if (config.accessToken) {\n this.current = config.accessToken;\n }\n }\n\n /** Returns a valid token, refreshing if needed. Single-flight: concurrent callers share one refresh. */\n async getToken(forceRefresh = false): Promise<string> {\n if (!forceRefresh && this.current && !this.isExpired()) {\n return this.current;\n }\n if (!forceRefresh && this.inFlightRefresh) {\n return this.inFlightRefresh;\n }\n this.inFlightRefresh = this.refresh();\n try {\n return await this.inFlightRefresh;\n } finally {\n this.inFlightRefresh = null;\n }\n }\n\n private async refresh(): Promise<string> {\n const result = await this.config.getAccessToken();\n this.current = result.accessToken;\n this.expiresAt = result.expiresAt ?? null;\n return this.current;\n }\n\n private isExpired(): boolean {\n if (this.expiresAt == null) return false;\n return Date.now() >= this.expiresAt - REFRESH_SKEW_MS;\n }\n}\n","import type {\n AccessTokenConfig,\n APIConfig,\n APIKeyConfig,\n AutocompleteRequest,\n AutocompleteResponse,\n CompletedParam,\n CompletedParamState,\n} from \"../types\";\nimport { TokenManager } from \"./tokenManager\";\n\n// Replaced at build time by tsup/vitest `define` config with the package.json version.\ndeclare const __SDK_VERSION__: string;\nconst SDK_VERSION = __SDK_VERSION__;\n\nlet hasWarnedMissingKey = false;\n\nfunction generateRequestId(): string {\n return crypto.randomUUID();\n}\n\nfunction toWireParam(param: CompletedParamState, includeText: boolean): CompletedParam {\n return {\n placeholder: param.placeholder,\n type: param.type,\n ...(includeText && { text: param.text }),\n kind: param.kind,\n };\n}\n\nfunction isAccessTokenConfig(config?: APIConfig): config is AccessTokenConfig {\n return config?.type === \"accessToken\";\n}\n\nfunction getApiKeyConfig(config?: APIConfig): APIKeyConfig | undefined {\n if (!config || isAccessTokenConfig(config)) return undefined;\n return config;\n}\n\n// Keyed by getAccessToken function reference (stable across React re-renders)\nconst tokenManagers = new WeakMap<AccessTokenConfig[\"getAccessToken\"], TokenManager>();\n\nfunction getTokenManager(config: AccessTokenConfig): TokenManager {\n let manager = tokenManagers.get(config.getAccessToken);\n if (!manager) {\n manager = new TokenManager(config);\n tokenManagers.set(config.getAccessToken, manager);\n }\n return manager;\n}\n\nfunction buildRequestBody(\n rawQuery: string,\n completedParams: CompletedParamState[],\n includeText: boolean,\n): AutocompleteRequest {\n const rawCount = completedParams.find(\n (p) => p.type === \"contact\" && p.metadata?.contact_account_count,\n )?.metadata?.contact_account_count;\n const contactAccountCount = typeof rawCount === \"number\" ? rawCount : undefined;\n\n return {\n data: {\n raw_query: rawQuery,\n completed_params: completedParams.map((p) => toWireParam(p, includeText)),\n ...(contactAccountCount != null && { contact_account_count: contactAccountCount }),\n },\n meta: {\n request_id: generateRequestId(),\n request_at: new Date().toISOString(),\n language: typeof navigator !== \"undefined\" ? navigator.language : \"en-US\",\n client_version: SDK_VERSION,\n },\n };\n}\n\nfunction buildHeaders(apiConfig?: APIConfig): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n ...(apiConfig?.appIdentifier && { \"X-App-Identifier\": apiConfig.appIdentifier }),\n ...apiConfig?.headers,\n };\n}\n\nasync function doFetch(\n endpoint: string,\n headers: Record<string, string>,\n token: string,\n body: string,\n signal?: AbortSignal,\n): Promise<Response> {\n return fetch(endpoint, {\n method: \"POST\",\n headers: { ...headers, Authorization: `Bearer ${token}` },\n body,\n signal,\n });\n}\n\nexport async function fetchSuggestions(\n rawQuery: string,\n completedParams: CompletedParamState[],\n options?: {\n maskCompletedText?: boolean;\n signal?: AbortSignal;\n apiConfig?: APIConfig;\n },\n): Promise<AutocompleteResponse> {\n const apiConfig = options?.apiConfig;\n const includeText = !options?.maskCompletedText;\n const body = buildRequestBody(rawQuery, completedParams, includeText);\n const headers = buildHeaders(apiConfig);\n const endpoint = apiConfig?.endpoint ?? \"/ac/suggest\";\n const jsonBody = JSON.stringify(body);\n\n // === Access token mode ===\n if (isAccessTokenConfig(apiConfig)) {\n const manager = getTokenManager(apiConfig);\n const token = await manager.getToken();\n\n let response = await doFetch(endpoint, headers, token, jsonBody, options?.signal);\n\n // 401 retry: force-refresh token and retry exactly once\n if (response.status === 401) {\n const newToken = await manager.getToken(true);\n response = await doFetch(endpoint, headers, newToken, jsonBody, options?.signal);\n }\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json() as Promise<AutocompleteResponse>;\n }\n\n // === API key mode (default) ===\n const apiKeyConfig = getApiKeyConfig(apiConfig);\n const apiKey = apiKeyConfig?.apiKey ?? \"\";\n\n if (!apiKey && !hasWarnedMissingKey) {\n hasWarnedMissingKey = true;\n // biome-ignore lint/suspicious/noConsole: intentional dev warning\n console.warn(\n \"[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header.\",\n );\n }\n\n if (apiKey) {\n const authScheme = apiKeyConfig?.authScheme ?? \"Bearer\";\n headers.Authorization = authScheme === \"Basic\" ? `Basic ${btoa(apiKey)}` : `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers,\n body: jsonBody,\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`API error: ${response.status} ${response.statusText}`);\n }\n\n return response.json() as Promise<AutocompleteResponse>;\n}\n","import type { CompletedParamState } from \"../types\";\n\ninterface BuildQueryResult {\n rawQuery: string;\n completedParams: CompletedParamState[];\n}\n\n/**\n * Takes the raw input text and completed params (without placeholders),\n * replaces each completed param's text in the string with a {{TYPE_N}} token,\n * and returns the transformed query + params with placeholders filled in.\n *\n * Replacements happen left-to-right, first occurrence only per param.\n * Counter is per-type (e.g. {{TASK_1}}, {{GOAL_1}}, {{GOAL_2}}).\n */\nexport function buildQuery(text: string, completedParams: CompletedParamState[]): BuildQueryResult {\n let result = text;\n const typeCounts: Record<string, number> = {};\n const updatedParams: CompletedParamState[] = [];\n\n for (const param of completedParams) {\n const count = (typeCounts[param.type] ?? 0) + 1;\n typeCounts[param.type] = count;\n\n const typeKey = param.type.toUpperCase().replace(/\\s+/g, \"_\");\n const placeholder = `{{${typeKey}_${count}}}`;\n\n // Replace first occurrence of the param text in the string\n const index = result.indexOf(param.text);\n if (index !== -1) {\n result = result.slice(0, index) + placeholder + result.slice(index + param.text.length);\n }\n\n updatedParams.push({ ...param, placeholder });\n }\n\n return { rawQuery: result, completedParams: updatedParams };\n}\n","import type { Suggestion, SuggestionOption } from \"../types\";\n\n/**\n * Applies option overrides by calling the override function with an empty query,\n * then prepending results to suggestions that match by type, deduplicating by text.\n */\nexport function applyOptionOverrides(\n suggestions: Suggestion[],\n overrides?: Record<string, (query: string) => SuggestionOption[]>,\n): Suggestion[] {\n if (!overrides) return suggestions;\n return suggestions.map((s) => {\n const fn = overrides[s.type];\n if (!fn) return s;\n const extra = fn(\"\");\n if (extra.length === 0) return s;\n const existingTexts = new Set(extra.map((o) => o.text));\n const deduped = (s.options ?? []).filter((o) => !existingTexts.has(o.text));\n return { ...s, options: [...extra, ...deduped] };\n });\n}\n","import type {\n APIConfig,\n CompletedParamState,\n OptionOverrides,\n Suggestion,\n SuggestionOption,\n} from \"../../types\";\nimport { fetchSuggestions } from \"../../utils/api\";\nimport { buildQuery } from \"../../utils/buildQuery\";\nimport { extractFilterQuery, filterOptions, findExactMatch } from \"../../utils/filtering\";\nimport { applyOptionOverrides } from \"../../utils/overrides\";\nimport type { Store } from \"../state\";\nimport type { CoreState } from \"../types\";\n\nconst DEBOUNCE_MS = 100;\nconst SLOW_DEBOUNCE_MS = 300;\nconst MIN_CHARS_DIFF = 2;\n\nexport class FetchController {\n private fetchVersion = 0;\n private abortController: AbortController | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private slowDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n private unsubscribe: (() => void) | null = null;\n\n constructor(\n private store: Store<CoreState>,\n private getApiConfig: () => APIConfig | undefined,\n private getOptionOverrides: () => OptionOverrides | undefined,\n private getMaskCompletedText: () => boolean | undefined,\n private getOnError: () => ((error: Error) => void) | undefined,\n ) {}\n\n start() {\n // Initial fetch\n this.doFetch(\"\", []);\n\n // Subscribe to state changes for debounced fetching\n let prevText = this.store.get().text;\n let prevParams = this.store.get().completedParams;\n this.unsubscribe = this.store.subscribe((next) => {\n if (next.text !== prevText || next.completedParams !== prevParams) {\n prevText = next.text;\n prevParams = next.completedParams;\n this.scheduleFetch();\n }\n });\n }\n\n dispose() {\n this.abortController?.abort();\n this.clearTimers();\n this.unsubscribe?.();\n }\n\n async doFetch(rawQuery: string, completed: CompletedParamState[]) {\n this.abortController?.abort();\n const controller = new AbortController();\n this.abortController = controller;\n const version = ++this.fetchVersion;\n const state = this.store.get();\n const textAtRequest = state.text.length;\n\n const hasSuggestions = state.suggestions.some((s) => s.type !== \"placeholder\");\n if (!hasSuggestions) this.store.set({ isLoading: true });\n this.store.set({ error: null });\n\n try {\n const res = await fetchSuggestions(rawQuery, completed, {\n maskCompletedText: this.getMaskCompletedText(),\n signal: controller.signal,\n apiConfig: this.getApiConfig(),\n });\n\n if (version !== this.fetchVersion) return;\n\n let newSuggestions = applyOptionOverrides(\n res.data.suggestions ?? [],\n this.getOptionOverrides(),\n );\n\n const input = res.data.input ?? [];\n const lastInput = input[input.length - 1];\n const currentText = this.store.get().text;\n let filterBase: number;\n let filterInProgress: boolean;\n\n if (lastInput?.state === \"in_progress\") {\n filterInProgress = true;\n const inProgressIdx = currentText.toLowerCase().lastIndexOf(lastInput.text.toLowerCase());\n filterBase = inProgressIdx !== -1 ? inProgressIdx : textAtRequest;\n } else {\n filterInProgress = false;\n filterBase = textAtRequest;\n }\n\n // Check if user already typed an exact match while waiting\n const actionable = newSuggestions.filter((s) => s.type !== \"placeholder\");\n const active = actionable[0];\n let extraParam: CompletedParamState | null = null;\n if (active) {\n const query = extractFilterQuery(currentText, filterBase, filterInProgress);\n const match = findExactMatch(active.options, query);\n if (match) {\n extraParam = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: active.type,\n text: match.text,\n kind: match.kind,\n suggestionType: active.type,\n suggestionPlaceholder: active.text,\n options: active.options ?? [],\n metadata: match.metadata,\n };\n newSuggestions = newSuggestions.filter((s) => s !== active);\n }\n }\n\n this.store.set((s) => ({\n suggestions: newSuggestions,\n isLoading: false,\n isReady: res.data.is_ready ?? false,\n lastRawQuery: rawQuery,\n activeDropdownIndex: -1,\n filterBase,\n filterInProgress,\n ...(extraParam ? { completedParams: [...s.completedParams, extraParam] } : {}),\n }));\n } catch (err) {\n if (version === this.fetchVersion) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n this.store.set({ error: caughtError, isLoading: false });\n this.getOnError()?.(caughtError);\n }\n }\n }\n\n private scheduleFetch() {\n this.clearTimers();\n const state = this.store.get();\n\n if (state.skipNextFetch) {\n this.store.set({ skipNextFetch: false });\n return;\n }\n\n const attemptFetch = (minDiff: number): boolean => {\n const s = this.store.get();\n if (!s.text && s.completedParams.length === 0) {\n this.doFetch(\"\", []);\n return true;\n }\n\n const currentQuery = extractFilterQuery(s.text, s.filterBase, s.filterInProgress);\n const actionable = s.suggestions.filter((sg: Suggestion) => sg.type !== \"placeholder\");\n const active = actionable[0];\n const currentFiltered = active ? filterOptions(active.options, currentQuery) : [];\n const tappableFiltered = currentFiltered.filter((o: SuggestionOption) => o.is_tappable);\n const hasExactMatch = active ? findExactMatch(active.options, currentQuery) !== null : false;\n\n const isInFilterZone = currentQuery.trim().length > 0;\n if (tappableFiltered.length > 0 && !hasExactMatch && isInFilterZone) return false;\n\n const { rawQuery, completedParams: updatedParams } = buildQuery(s.text, s.completedParams);\n const isDeleting = rawQuery.length < s.lastRawQuery.length;\n const charDiff = Math.abs(rawQuery.length - s.lastRawQuery.length);\n if (isDeleting || charDiff >= minDiff) {\n this.doFetch(rawQuery, updatedParams);\n return true;\n }\n return false;\n };\n\n this.debounceTimer = setTimeout(() => {\n if (attemptFetch(MIN_CHARS_DIFF)) {\n if (this.slowDebounceTimer) clearTimeout(this.slowDebounceTimer);\n }\n }, DEBOUNCE_MS);\n\n this.slowDebounceTimer = setTimeout(() => attemptFetch(1), SLOW_DEBOUNCE_MS);\n }\n\n private clearTimers() {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n if (this.slowDebounceTimer) clearTimeout(this.slowDebounceTimer);\n this.debounceTimer = null;\n this.slowDebounceTimer = null;\n }\n}\n","import type { AutocompleteResult, SuggestionOption } from \"../../types\";\nimport { buildQuery } from \"../../utils/buildQuery\";\nimport type { Store } from \"../state\";\nimport type { CoreState } from \"../types\";\n\nexport interface KeyboardContext {\n columns: number;\n listboxId: string;\n getOnSubmit: () => ((result: AutocompleteResult) => void) | undefined;\n selectOption: (option: SuggestionOption) => void;\n}\n\nexport class KeyboardController {\n constructor(\n private store: Store<CoreState>,\n private ctx: KeyboardContext,\n ) {}\n\n handleKeyDown(e: KeyboardEvent) {\n const state = this.store.get();\n const { columns, listboxId, getOnSubmit } = this.ctx;\n const onSubmit = getOnSubmit();\n const tappableIndices = this.getTappableIndices();\n\n switch (e.key) {\n case \"ArrowDown\": {\n const target = e.target as HTMLTextAreaElement;\n const cursorAtEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (!cursorAtEnd && state.activeDropdownIndex < 0) break;\n\n e.preventDefault();\n if (!state.isDropdownOpen && state.actionableSuggestions.length > 0) {\n this.store.set({ pillTapped: true, activeDropdownIndex: tappableIndices[0] ?? 0 });\n break;\n }\n if (tappableIndices.length === 0) return;\n const currentPos = tappableIndices.indexOf(state.activeDropdownIndex);\n const nextPos = currentPos < tappableIndices.length - 1 ? currentPos + 1 : 0;\n this.store.set({ activeDropdownIndex: tappableIndices[nextPos] });\n break;\n }\n case \"ArrowUp\": {\n if (tappableIndices.length === 0 || state.activeDropdownIndex < 0) break;\n e.preventDefault();\n if (state.activeDropdownIndex < columns) {\n this.store.set({ activeDropdownIndex: -1 });\n break;\n }\n const currentPos = tappableIndices.indexOf(state.activeDropdownIndex);\n const prevPos = currentPos > 0 ? currentPos - 1 : tappableIndices.length - 1;\n this.store.set({ activeDropdownIndex: tappableIndices[prevPos] });\n break;\n }\n case \"ArrowRight\": {\n if (state.activeDropdownIndex < 0) {\n const target = e.target as HTMLTextAreaElement;\n const atEnd =\n target.selectionStart != null && target.selectionStart === target.value.length;\n if (atEnd && state.actionableSuggestions.length > 1) {\n e.preventDefault();\n this.pillsSetActivePill(1);\n }\n break;\n }\n const col = state.activeDropdownIndex % columns;\n if (col < columns - 1) {\n const rightNeighbor = state.activeDropdownIndex + 1;\n if (\n rightNeighbor < state.filteredOptions.length &&\n state.filteredOptions[rightNeighbor]?.is_tappable\n ) {\n e.preventDefault();\n this.store.set({ activeDropdownIndex: rightNeighbor });\n }\n }\n break;\n }\n case \"ArrowLeft\": {\n if (state.activeDropdownIndex < 0) break;\n if (state.activeDropdownIndex % columns > 0) {\n const leftNeighbor = state.activeDropdownIndex - 1;\n if (leftNeighbor >= 0 && state.filteredOptions[leftNeighbor]?.is_tappable) {\n e.preventDefault();\n this.store.set({ activeDropdownIndex: leftNeighbor });\n }\n }\n break;\n }\n case \"Enter\": {\n e.preventDefault();\n if (\n state.activeDropdownIndex >= 0 &&\n state.filteredOptions[state.activeDropdownIndex]?.is_tappable\n ) {\n this.clickOrSelect(state.activeDropdownIndex, state.filteredOptions, listboxId);\n } else if (onSubmit) {\n const { rawQuery, completedParams: finalParams } = buildQuery(\n state.text,\n state.completedParams,\n );\n onSubmit({\n query: state.text.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n }\n break;\n }\n case \"Tab\": {\n if (\n state.activeDropdownIndex >= 0 &&\n state.filteredOptions[state.activeDropdownIndex]?.is_tappable\n ) {\n e.preventDefault();\n this.clickOrSelect(state.activeDropdownIndex, state.filteredOptions, listboxId);\n } else if (state.isDropdownOpen) {\n const firstTappableIdx = state.filteredOptions.findIndex((o) => o.is_tappable);\n if (firstTappableIdx >= 0) {\n e.preventDefault();\n this.clickOrSelect(firstTappableIdx, state.filteredOptions, listboxId);\n }\n } else if (!state.text && state.placeholderText) {\n e.preventDefault();\n const placeholderSuggestion = state.suggestions.find((s) => s.type === \"placeholder\");\n if (placeholderSuggestion) {\n this.store.set((s) => ({\n text: state.placeholderText,\n filterBase: state.placeholderText.length,\n completedParams: [\n ...s.completedParams,\n {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: placeholderSuggestion.type,\n text: state.placeholderText,\n kind: null,\n suggestionType: placeholderSuggestion.type,\n suggestionPlaceholder: placeholderSuggestion.text,\n options: placeholderSuggestion.options ?? [],\n },\n ],\n suggestions: s.suggestions.filter((sg) => sg !== placeholderSuggestion),\n }));\n } else {\n this.store.set({\n text: state.placeholderText,\n filterBase: state.placeholderText.length,\n });\n }\n }\n break;\n }\n case \"Escape\":\n this.store.set({ activeDropdownIndex: -1 });\n break;\n }\n }\n\n private getTappableIndices(): number[] {\n const state = this.store.get();\n const { columns } = this.ctx;\n const tappable = state.filteredOptions\n .map((o, i) => (o.is_tappable ? i : -1))\n .filter((i) => i !== -1);\n const buckets: number[][] = Array.from({ length: columns }, () => []);\n for (const i of tappable) buckets[i % columns].push(i);\n return buckets.flat();\n }\n\n private clickOrSelect(index: number, options: SuggestionOption[], listboxId: string) {\n const optionEl = document.getElementById(`${listboxId}-option-${index}`);\n if (optionEl) {\n optionEl.click();\n } else {\n this.ctx.selectOption(options[index]);\n }\n }\n\n /** Delegate to pills controller logic inline (avoids circular dep) */\n private pillsSetActivePill(index: number) {\n const state = this.store.get();\n const actionable = state.suggestions.filter((s) => s.type !== \"placeholder\");\n if (index < 0 || index >= actionable.length) return;\n const moved = actionable[index];\n const rest = actionable.filter((_, i) => i !== index);\n const placeholders = state.suggestions.filter((s) => s.type === \"placeholder\");\n this.store.set({\n suggestions: [...placeholders, moved, ...rest],\n pillTapped: true,\n activeDropdownIndex: -1,\n });\n }\n}\n","import type { Suggestion } from \"../../types\";\nimport type { Store } from \"../state\";\nimport type { CoreState } from \"../types\";\n\nexport class PillsController {\n constructor(private store: Store<CoreState>) {}\n\n setActivePill(index: number) {\n const state = this.store.get();\n const actionable = state.suggestions.filter((s) => s.type !== \"placeholder\");\n if (index < 0 || index >= actionable.length) return;\n const moved = actionable[index];\n const rest = actionable.filter((_, i) => i !== index);\n const placeholders = state.suggestions.filter((s) => s.type === \"placeholder\");\n this.store.set({\n suggestions: [...placeholders, moved, ...rest],\n pillTapped: true,\n activeDropdownIndex: -1,\n });\n }\n\n removeLastParam() {\n const state = this.store.get();\n if (state.completedParams.length === 0) return;\n const lastParam = state.completedParams[state.completedParams.length - 1];\n const restoredSuggestion: Suggestion = {\n type: lastParam.suggestionType,\n text: lastParam.suggestionPlaceholder,\n required: true,\n options: lastParam.options,\n };\n this.store.set((s) => ({\n completedParams: s.completedParams.slice(0, -1),\n suggestions: [restoredSuggestion, ...s.suggestions],\n activeDropdownIndex: -1,\n }));\n }\n}\n","import type { Suggestion } from \"../../types\";\n\nfunction getPillOpacity(index: number): number {\n if (index === 0) return 0.4;\n if (index === 1) return 0.3;\n return 0.15;\n}\n\nexport function renderPills(\n container: HTMLElement,\n pills: Suggestion[],\n activePillIndex: number,\n onSelectPill: (index: number) => void,\n rounded = false,\n) {\n // Reuse or create the list wrapper\n let list = container.querySelector<HTMLElement>(\".magicx-aia-pill-list\");\n if (!list) {\n list = document.createElement(\"span\");\n list.className = \"magicx-aia-pill-list\";\n container.appendChild(list);\n }\n\n // Diff by key (type-text)\n const existing = new Map<string, HTMLButtonElement>();\n for (const btn of list.querySelectorAll<HTMLButtonElement>(\".magicx-aia-pill\")) {\n existing.set(btn.dataset.pillKey ?? \"\", btn);\n }\n\n const used = new Set<string>();\n for (let i = 0; i < pills.length; i++) {\n const pill = pills[i];\n const key = `${pill.type}-${pill.text}`;\n used.add(key);\n\n let btn = existing.get(key);\n if (!btn) {\n btn = document.createElement(\"button\");\n btn.type = \"button\";\n btn.dataset.pillKey = key;\n btn.textContent = pill.text;\n }\n\n btn.className = `magicx-aia-pill${rounded ? \" magicx-aia-pill--rounded\" : \"\"}${i === activePillIndex ? \" magicx-aia-pill--active\" : \"\"}`;\n btn.style.opacity = String(getPillOpacity(i));\n btn.onclick = () => onSelectPill(i);\n\n // Ensure correct order\n if (list.children[i] !== btn) {\n list.insertBefore(btn, list.children[i] ?? null);\n }\n }\n\n // Remove stale pills\n for (const [key, btn] of existing) {\n if (!used.has(key)) btn.remove();\n }\n}\n\nexport function clearPills(container: HTMLElement) {\n container.querySelector(\".magicx-aia-pill-list\")?.remove();\n}\n","import type { Suggestion, SuggestionOption } from \"../../types\";\nimport { renderPills } from \"./renderPills\";\n\ninterface DropdownState {\n suggestions: Suggestion[];\n filteredOptions: SuggestionOption[];\n activeIndex: number;\n isOpen: boolean;\n listboxId: string;\n pills: Suggestion[];\n showPills: boolean;\n onSelect: (option: SuggestionOption) => void;\n onHighlight: (index: number) => void;\n onPillClick: (index: number) => void;\n}\n\nexport function createDropdown(listboxId: string): HTMLElement {\n const dropdown = document.createElement(\"div\");\n dropdown.id = listboxId;\n dropdown.setAttribute(\"role\", \"listbox\");\n dropdown.setAttribute(\"data-aia-dropdown\", \"\");\n dropdown.className = \"magicx-aia-dropdown\";\n dropdown.addEventListener(\"mousedown\", (e) => e.preventDefault());\n return dropdown;\n}\n\nexport function renderDropdown(dropdown: HTMLElement, state: DropdownState) {\n const {\n filteredOptions,\n activeIndex,\n isOpen,\n pills,\n showPills,\n onSelect,\n onHighlight,\n onPillClick,\n } = state;\n\n const hasPills = showPills && pills.length > 0;\n const hasOptions = isOpen && filteredOptions.length > 0;\n const isVisible = hasOptions || (isOpen && hasPills);\n\n // Toggle visibility\n if (isVisible) {\n dropdown.classList.add(\"magicx-aia-dropdown--visible\");\n } else {\n dropdown.classList.remove(\"magicx-aia-dropdown--visible\");\n }\n\n // --- Pill bar ---\n let pillBar = dropdown.querySelector<HTMLElement>(\".magicx-aia-pill-bar\");\n if (hasPills) {\n if (!pillBar) {\n pillBar = document.createElement(\"div\");\n pillBar.className = \"magicx-aia-pill-bar\";\n dropdown.insertBefore(pillBar, dropdown.firstChild);\n }\n renderPills(pillBar, pills, 0, onPillClick, true);\n } else if (pillBar) {\n pillBar.remove();\n }\n\n // --- Options grid ---\n let grid = dropdown.querySelector<HTMLElement>(\".magicx-aia-grid\");\n if (filteredOptions.length > 0) {\n if (!grid) {\n grid = document.createElement(\"div\");\n grid.className = \"magicx-aia-grid\";\n dropdown.appendChild(grid);\n }\n renderOptions(grid, filteredOptions, activeIndex, onSelect, onHighlight, state.listboxId);\n } else if (grid) {\n grid.innerHTML = \"\";\n }\n}\n\nfunction renderOptions(\n grid: HTMLElement,\n options: SuggestionOption[],\n activeIndex: number,\n onSelect: (option: SuggestionOption) => void,\n onHighlight: (index: number) => void,\n listboxId: string,\n) {\n const optionsKey = options.map((o) => o.text).join(\"\\0\");\n const lastKey = grid.dataset.optionsKey ?? \"\";\n const listChanged = optionsKey !== lastKey;\n grid.dataset.optionsKey = optionsKey;\n\n if (listChanged) {\n // Full rebuild — options changed (filter, new suggestion, etc.)\n const fragment = document.createDocumentFragment();\n\n for (let i = 0; i < options.length; i++) {\n const option = options[i];\n const item = createOptionElement(option, i, activeIndex, onSelect, onHighlight, listboxId);\n fragment.appendChild(item);\n }\n\n grid.innerHTML = \"\";\n grid.appendChild(fragment);\n } else {\n // Just update highlight classes — no DOM rebuild\n const items = grid.querySelectorAll<HTMLElement>(\".magicx-aia-option\");\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const isHighlighted = i === activeIndex;\n item.setAttribute(\"aria-selected\", String(isHighlighted));\n if (isHighlighted) {\n item.classList.add(\"magicx-aia-option--highlighted\");\n } else {\n item.classList.remove(\"magicx-aia-option--highlighted\");\n }\n }\n }\n}\n\nfunction createOptionElement(\n option: SuggestionOption,\n index: number,\n activeIndex: number,\n onSelect: (option: SuggestionOption) => void,\n onHighlight: (index: number) => void,\n listboxId: string,\n): HTMLElement {\n const item = document.createElement(\"div\");\n item.id = `${listboxId}-option-${index}`;\n item.setAttribute(\"role\", \"option\");\n item.setAttribute(\"aria-selected\", String(index === activeIndex));\n item.tabIndex = option.is_tappable ? 0 : -1;\n\n const classes = [\"magicx-aia-option\"];\n if (index === activeIndex) classes.push(\"magicx-aia-option--highlighted\");\n if (option.is_tappable) {\n classes.push(\"magicx-aia-option--tappable\");\n } else {\n classes.push(\"magicx-aia-option--non-tappable\");\n }\n item.className = classes.join(\" \");\n\n // Streaks\n const streaks = document.createElement(\"div\");\n streaks.className = \"magicx-aia-streaks\";\n item.appendChild(streaks);\n\n const streaksVert = document.createElement(\"div\");\n streaksVert.className = \"magicx-aia-streaks-vert\";\n item.appendChild(streaksVert);\n\n // Content\n const content = document.createElement(\"span\");\n content.className = \"magicx-aia-option-content\";\n content.textContent = option.icon ? `${option.icon} ${option.text}` : option.text;\n\n if (option.tag) {\n const tag = document.createElement(\"span\");\n tag.className = \"magicx-aia-option-tag\";\n tag.textContent = option.tag;\n content.appendChild(tag);\n }\n\n item.appendChild(content);\n\n // Events\n if (option.is_tappable) {\n item.addEventListener(\"click\", () => {\n item.classList.add(\"magicx-aia-option--pressed\");\n onSelect(option);\n setTimeout(() => item.classList.remove(\"magicx-aia-option--pressed\"), 400);\n });\n }\n item.addEventListener(\"mouseenter\", () => onHighlight(index));\n\n return item;\n}\n","import type { SuggestionOption } from \"../../types\";\nimport type { Store } from \"../state\";\nimport type { CoreState } from \"../types\";\nimport { createDropdown, renderDropdown } from \"./renderDropdown\";\n\ninterface DropdownOnlyRefs {\n dropdown: HTMLElement;\n}\n\ninterface DropdownOnlyOptions {\n store: Store<CoreState>;\n listboxId: string;\n selectOption: (option: SuggestionOption) => void;\n setActivePill: (index: number) => void;\n}\n\nexport function buildDropdownOnly(\n container: HTMLElement,\n opts: DropdownOnlyOptions,\n): DropdownOnlyRefs {\n const dropdown = createDropdown(opts.listboxId);\n container.appendChild(dropdown);\n return { dropdown };\n}\n\nexport function updateDropdownOnly(\n refs: DropdownOnlyRefs,\n state: CoreState,\n opts: DropdownOnlyOptions,\n) {\n renderDropdown(refs.dropdown, {\n suggestions:\n state.actionableSuggestions.length > 0\n ? [{ ...state.actionableSuggestions[0], options: state.filteredOptions }]\n : [],\n filteredOptions: state.filteredOptions,\n activeIndex: state.activeDropdownIndex,\n isOpen: state.isDropdownOpen,\n listboxId: opts.listboxId,\n pills: state.actionableSuggestions,\n showPills: true, // always show pills in dropdown-only mode\n onSelect: opts.selectOption,\n onHighlight: (i) => opts.store.set({ activeDropdownIndex: i }),\n onPillClick: opts.setActivePill,\n });\n}\n","import type { Segment } from \"../../types\";\n\n/**\n * Renders text segments into the sizer overlay.\n * Only rebuilds the DOM when segment content or newParamId changes,\n * preserving in-flight CSS animations (shimmer).\n * Cache keys stored on the DOM element to support multi-instance use.\n */\nexport function renderSegments(\n sizer: HTMLElement,\n segments: Segment[],\n newParamId: string | null,\n isEmpty: boolean,\n placeholderText: string,\n) {\n let sizerText = sizer.querySelector<HTMLElement>(\".magicx-aia-sizer-text\");\n let placeholder = sizer.querySelector<HTMLElement>(\".magicx-aia-placeholder\");\n\n if (isEmpty && placeholderText) {\n if (sizerText) sizerText.style.display = \"none\";\n if (!placeholder) {\n placeholder = document.createElement(\"span\");\n placeholder.className = \"magicx-aia-placeholder\";\n sizer.insertBefore(placeholder, sizer.firstChild);\n }\n placeholder.style.display = \"\";\n placeholder.textContent = `${placeholderText} `;\n sizer.dataset.segmentKey = \"\";\n return;\n }\n\n if (placeholder) placeholder.style.display = \"none\";\n if (!sizerText) {\n sizerText = document.createElement(\"span\");\n sizerText.className = \"magicx-aia-sizer-text\";\n sizer.insertBefore(sizerText, sizer.firstChild);\n }\n sizerText.style.display = \"\";\n sizerText.className = `magicx-aia-sizer-text${newParamId ? \" magicx-aia-sizer-text--visible\" : \"\"}`;\n\n const segmentKey = segments.map((s) => `${s.type}:${s.value}`).join(\"\\0\");\n const lastKey = sizer.dataset.segmentKey ?? \"\";\n const lastParamId = sizer.dataset.newParamId ?? \"\";\n if (segmentKey === lastKey && (newParamId ?? \"\") === lastParamId) {\n return; // Nothing changed — preserve existing DOM and animations\n }\n sizer.dataset.segmentKey = segmentKey;\n sizer.dataset.newParamId = newParamId ?? \"\";\n\n sizerText.innerHTML = \"\";\n for (const seg of segments) {\n const span = document.createElement(\"span\");\n if (seg.type === \"completed\") {\n const isNew = seg.param.id === newParamId;\n if (isNew) {\n span.className = \"magicx-aia-shimmer-revealed magicx-aia-shimmer-sweep\";\n } else {\n span.className = \"magicx-aia-segment magicx-aia-segment--completed\";\n }\n }\n span.textContent = seg.value;\n sizerText.appendChild(span);\n }\n\n if (segments.length === 0) {\n sizerText.textContent = \"\\u00A0\";\n }\n}\n","import type { AutocompleteResult } from \"../../types\";\nimport { buildQuery } from \"../../utils/buildQuery\";\nimport type { Store } from \"../state\";\nimport type { CoreState } from \"../types\";\nimport { createDropdown, renderDropdown } from \"./renderDropdown\";\nimport { renderPills } from \"./renderPills\";\nimport { renderSegments } from \"./renderSegments\";\n\ninterface RenderInputOptions {\n store: Store<CoreState>;\n listboxId: string;\n pillPlacement: \"inline\" | \"dropdown\" | \"hidden\";\n onSubmit?: (result: AutocompleteResult) => void;\n selectOption: (option: import(\"../../types\").SuggestionOption) => void;\n setActivePill: (index: number) => void;\n handleKeyDown: (e: KeyboardEvent) => void;\n handleChange: (value: string) => void;\n}\n\nexport interface DOMRefs {\n textarea: HTMLTextAreaElement;\n dropdown: HTMLElement;\n sizer: HTMLElement;\n submitButton: HTMLButtonElement;\n inlinePillContainer: HTMLElement;\n}\n\nconst SUBMIT_SVG = `<svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" role=\"img\" aria-label=\"Submit\"><path d=\"M9 14V4M9 4L4 9M9 4L14 9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\nexport function buildDOM(container: HTMLElement, opts: RenderInputOptions): DOMRefs {\n const { listboxId } = opts;\n\n // Dropdown\n const dropdown = createDropdown(listboxId);\n container.appendChild(dropdown);\n\n // Input wrapper\n const inputWrapper = document.createElement(\"div\");\n inputWrapper.className = \"magicx-aia-input-wrapper\";\n container.appendChild(inputWrapper);\n\n // Editor area\n const editor = document.createElement(\"div\");\n editor.className = \"magicx-aia-editor\";\n inputWrapper.appendChild(editor);\n\n // Sizer (overlay)\n const sizer = document.createElement(\"div\");\n sizer.className = \"magicx-aia-sizer\";\n sizer.setAttribute(\"aria-hidden\", \"true\");\n editor.appendChild(sizer);\n\n // Inline pill container (inside sizer, after segments)\n const inlinePillContainer = document.createElement(\"span\");\n sizer.appendChild(document.createTextNode(\" \"));\n sizer.appendChild(inlinePillContainer);\n\n // Textarea\n const textarea = document.createElement(\"textarea\");\n textarea.className = \"magicx-aia-textarea\";\n textarea.rows = 1;\n textarea.setAttribute(\"role\", \"combobox\");\n textarea.setAttribute(\"aria-autocomplete\", \"list\");\n textarea.setAttribute(\"aria-controls\", listboxId);\n editor.appendChild(textarea);\n\n // Submit button\n const submitButton = document.createElement(\"button\");\n submitButton.type = \"button\";\n submitButton.className = \"magicx-aia-submit\";\n submitButton.setAttribute(\"aria-label\", \"Submit\");\n submitButton.innerHTML = SUBMIT_SVG;\n inputWrapper.appendChild(submitButton);\n\n // --- Event wiring ---\n\n // Click wrapper → focus textarea\n inputWrapper.addEventListener(\"click\", () => textarea.focus());\n\n // Textarea change\n textarea.addEventListener(\"input\", () => {\n const raw = textarea.value;\n const shouldCapitalize = raw.length > 0 && raw[0] !== raw[0].toUpperCase();\n const newValue = shouldCapitalize ? raw[0].toUpperCase() + raw.slice(1) : raw;\n opts.handleChange(newValue);\n });\n\n // Keyboard\n textarea.addEventListener(\"keydown\", (e) => opts.handleKeyDown(e));\n\n // Submit button\n submitButton.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n const state = opts.store.get();\n const canSubmit = !!state.text || state.completedParams.length > 0;\n if (!canSubmit || !opts.onSubmit) return;\n const { rawQuery, completedParams: finalParams } = buildQuery(\n state.text,\n state.completedParams,\n );\n opts.onSubmit({\n query: state.text.trim(),\n raw_query: rawQuery,\n completed_params: finalParams,\n });\n });\n\n // Focus textarea on mount\n textarea.focus();\n\n return { textarea, dropdown, sizer, submitButton, inlinePillContainer };\n}\n\nexport function updateDOM(refs: DOMRefs, state: CoreState, opts: RenderInputOptions) {\n const { textarea, dropdown, sizer, submitButton, inlinePillContainer } = refs;\n const { pillPlacement, setActivePill, selectOption, store } = opts;\n\n // Textarea value\n if (textarea.value !== state.text) {\n textarea.value = state.text;\n }\n\n // Placeholder\n if (state.placeholderText) {\n textarea.placeholder = state.placeholderText;\n } else {\n textarea.removeAttribute(\"placeholder\");\n }\n\n // ARIA\n textarea.setAttribute(\"aria-expanded\", String(state.isDropdownOpen));\n const activeDescendant =\n state.activeDropdownIndex >= 0 ? `${opts.listboxId}-option-${state.activeDropdownIndex}` : \"\";\n if (activeDescendant) {\n textarea.setAttribute(\"aria-activedescendant\", activeDescendant);\n } else {\n textarea.removeAttribute(\"aria-activedescendant\");\n }\n\n // Shimmer: hide textarea text during animation\n if (state.newParamId) {\n textarea.classList.add(\"magicx-aia-textarea--hidden\");\n } else {\n textarea.classList.remove(\"magicx-aia-textarea--hidden\");\n }\n\n // Submit button disabled state\n const canSubmit = !!state.text || state.completedParams.length > 0;\n (submitButton as HTMLButtonElement).disabled = !canSubmit;\n\n // Segments overlay\n renderSegments(sizer, state.segments, state.newParamId, !state.text, state.placeholderText);\n\n // Inline pills\n if (pillPlacement === \"inline\") {\n renderPills(inlinePillContainer, state.actionableSuggestions, 0, setActivePill);\n } else {\n // Clear inline pills in dropdown mode\n inlinePillContainer.innerHTML = \"\";\n }\n\n // Dropdown\n renderDropdown(dropdown, {\n suggestions:\n state.actionableSuggestions.length > 0\n ? [{ ...state.actionableSuggestions[0], options: state.filteredOptions }]\n : [],\n filteredOptions: state.filteredOptions,\n activeIndex: state.activeDropdownIndex,\n isOpen: state.isDropdownOpen,\n listboxId: opts.listboxId,\n pills: state.actionableSuggestions,\n showPills: pillPlacement === \"dropdown\",\n onSelect: selectOption,\n onHighlight: (i) => store.set({ activeDropdownIndex: i }),\n onPillClick: setActivePill,\n });\n}\n","export type Listener<S> = (next: S, prev: S) => void;\n\nexport interface Store<S> {\n get: () => S;\n set: (patch: Partial<S> | ((s: S) => Partial<S>)) => void;\n subscribe: (listener: Listener<S>) => () => void;\n}\n\nexport function createStore<S>(initial: S): Store<S> {\n let state = initial;\n const listeners = new Set<Listener<S>>();\n return {\n get: () => state,\n set: (patch) => {\n const resolved = typeof patch === \"function\" ? patch(state) : patch;\n const next = { ...state, ...resolved };\n const prev = state;\n state = next;\n for (const l of listeners) l(next, prev);\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n","let injected = false;\n\n/** Inject core + appearance CSS into document.head once. Idempotent. */\nexport function injectStyles() {\n if (injected || typeof document === \"undefined\") return;\n if (document.querySelector(\"style[data-magicx-aia]\")) {\n injected = true;\n return;\n }\n injected = true;\n\n const style = document.createElement(\"style\");\n style.setAttribute(\"data-magicx-aia\", \"\");\n style.textContent = STYLES;\n document.head.appendChild(style);\n}\n\n// Replaced at build time by tsup.config.core.ts / vitest.config.ts\ndeclare const __MAGICX_AC_STYLES__: string;\nconst STYLES = __MAGICX_AC_STYLES__;\n","import type { AppearanceMode, CompletedParamState, Suggestion, SuggestionOption } from \"../types\";\nimport { extractFilterQuery, filterOptions, findPrefixOverlap } from \"../utils/filtering\";\nimport { ModeController } from \"../utils/modeController\";\nimport { deriveSegments, reconcileParams } from \"../utils/segments\";\nimport { FetchController } from \"./controllers/fetchController\";\nimport { KeyboardController } from \"./controllers/keyboardController\";\nimport { PillsController } from \"./controllers/pillsController\";\nimport { buildDropdownOnly, updateDropdownOnly } from \"./render/renderDropdownOnly\";\nimport { buildDOM, type DOMRefs, updateDOM } from \"./render/renderInput\";\nimport { createStore } from \"./state\";\nimport { injectStyles } from \"./styleInjector\";\nimport type { CoreOptions, CoreState, RenderMode } from \"./types\";\n\nlet idCounter = 0;\nfunction stableId(): string {\n return `:ac-${++idCounter}:`;\n}\n\nfunction initialState(): CoreState {\n return {\n text: \"\",\n completedParams: [],\n suggestions: [],\n activeDropdownIndex: -1,\n newParamId: null,\n isLoading: false,\n isReady: false,\n error: null,\n segments: [],\n actionableSuggestions: [],\n filteredOptions: [],\n placeholderText: \"\",\n isDropdownOpen: false,\n filterBase: 0,\n filterInProgress: false,\n pillTapped: false,\n skipNextFetch: false,\n lastRawQuery: \"\",\n };\n}\n\nexport class AIAutocomplete {\n private store = createStore<CoreState>(initialState());\n private _listboxId = stableId();\n private opts: CoreOptions;\n private fetchController: FetchController;\n private keyboardController: KeyboardController;\n private pillsController: PillsController;\n private modeController: ModeController | null = null;\n private container: HTMLElement;\n private unsubscribers: (() => void)[] = [];\n private derivedInProgress = false;\n private renderMode: RenderMode;\n private domRefs: DOMRefs | null = null;\n private dropdownRefs: { dropdown: HTMLElement } | null = null;\n private newParamTimer: number | undefined;\n private suggestionRemovalTimer: number | undefined;\n private externalListeners = new Set<(state: CoreState) => void>();\n\n constructor(container: HTMLElement, opts: CoreOptions = {}) {\n this.container = container;\n this.opts = opts;\n this.renderMode = opts.renderMode ?? \"full\";\n\n // Apply controlled initial values\n if (opts.value !== undefined) {\n this.store.set({ text: opts.value });\n }\n if (opts.completedParams !== undefined) {\n this.store.set({ completedParams: opts.completedParams });\n }\n\n // Controllers\n this.pillsController = new PillsController(this.store);\n\n this.fetchController = new FetchController(\n this.store,\n () => this.opts.apiConfig,\n () => this.opts.optionOverrides,\n () => this.opts.maskCompletedText,\n () => this.opts.onError,\n );\n\n this.keyboardController = new KeyboardController(this.store, {\n columns: opts.columns ?? 2,\n listboxId: this.listboxId,\n getOnSubmit: () => this.opts.onSubmit,\n selectOption: (option) => this.selectOption(option),\n });\n\n // Derived state recomputation\n this.unsubscribers.push(\n this.store.subscribe((next, prev) => {\n this.recomputeDerived(next, prev);\n }),\n );\n\n // Event callbacks\n this.unsubscribers.push(\n this.store.subscribe((next, prev) => {\n if (next.text !== prev.text) this.opts.onChange?.(next.text);\n if (next.completedParams !== prev.completedParams)\n this.opts.onParamsChange?.(next.completedParams);\n this.opts.onStateChange?.(next);\n }),\n );\n\n // Setup DOM based on render mode\n if (this.renderMode !== \"headless\") {\n injectStyles();\n this.setupContainer();\n }\n if (this.renderMode === \"full\") {\n this.buildAndRenderFull();\n } else if (this.renderMode === \"dropdown\") {\n this.buildAndRenderDropdown();\n }\n this.fetchController.start();\n }\n\n // === Public API ===\n\n focus() {\n this.domRefs?.textarea.focus();\n }\n\n reset() {\n this.store.set({\n ...initialState(),\n });\n this.fetchController.doFetch(\"\", []);\n }\n\n destroy() {\n this.fetchController.dispose();\n this.modeController?.destroy();\n if (this.newParamTimer) clearTimeout(this.newParamTimer);\n if (this.suggestionRemovalTimer) clearTimeout(this.suggestionRemovalTimer);\n this.externalListeners.clear();\n for (const unsub of this.unsubscribers) unsub();\n this.unsubscribers = [];\n this.domRefs = null;\n this.dropdownRefs = null;\n if (this.renderMode !== \"headless\") {\n this.container.innerHTML = \"\";\n }\n }\n\n setMode(mode: AppearanceMode) {\n this.modeController?.setMode(mode);\n }\n\n setValue(text: string) {\n this.store.set({ text });\n }\n\n setCompletedParams(params: CompletedParamState[]) {\n this.store.set({ completedParams: params });\n }\n\n setActivePill(index: number) {\n this.pillsController.setActivePill(index);\n }\n\n removeLastParam() {\n this.pillsController.removeLastParam();\n }\n\n clearNewParamId() {\n this.store.set({ newParamId: null });\n }\n\n setActiveDropdownIndex(index: number) {\n this.store.set({ activeDropdownIndex: index });\n }\n\n handleTextChange(value: string) {\n this.handleChange(value);\n }\n\n handleKeyDown(e: KeyboardEvent) {\n this.keyboardController.handleKeyDown(e);\n }\n\n /** Subscribe to state changes (fires after derived state is settled). Returns unsubscribe function. */\n subscribe(listener: (state: CoreState) => void): () => void {\n this.externalListeners.add(listener);\n return () => {\n this.externalListeners.delete(listener);\n };\n }\n\n getState(): CoreState {\n return this.store.get();\n }\n\n get listboxId(): string {\n return this._listboxId;\n }\n\n get isReady(): boolean {\n return this.store.get().isReady;\n }\n\n on(event: string, callback: (...args: unknown[]) => void): () => void {\n switch (event) {\n case \"submit\":\n this.opts.onSubmit = callback as CoreOptions[\"onSubmit\"];\n return () => {\n this.opts.onSubmit = undefined;\n };\n case \"error\":\n this.opts.onError = callback as CoreOptions[\"onError\"];\n return () => {\n this.opts.onError = undefined;\n };\n case \"change\":\n this.opts.onChange = callback as CoreOptions[\"onChange\"];\n return () => {\n this.opts.onChange = undefined;\n };\n case \"paramsChange\":\n this.opts.onParamsChange = callback as CoreOptions[\"onParamsChange\"];\n return () => {\n this.opts.onParamsChange = undefined;\n };\n case \"stateChange\":\n this.opts.onStateChange = callback as CoreOptions[\"onStateChange\"];\n return () => {\n this.opts.onStateChange = undefined;\n };\n default:\n return () => {};\n }\n }\n\n update(opts: Partial<CoreOptions>) {\n Object.assign(this.opts, opts);\n if (opts.mode !== undefined) {\n this.modeController?.setMode(opts.mode);\n }\n if (opts.optionsPosition !== undefined) {\n this.container.dataset.optionsPosition = opts.optionsPosition;\n }\n if (opts.animations !== undefined) {\n this.container.dataset.animations = opts.animations ? \"on\" : \"off\";\n }\n if (opts.pillPlacement !== undefined) {\n this.container.dataset.pillPlacement = opts.pillPlacement;\n this.store.set({});\n }\n if (opts.dropdownTrigger !== undefined) {\n // Trigger recompute so isDropdownOpen updates\n this.store.set({});\n }\n if (opts.value !== undefined) {\n this.store.set({ text: opts.value });\n }\n if (opts.completedParams !== undefined) {\n this.store.set({ completedParams: opts.completedParams });\n }\n }\n\n // === Public (for framework wrappers) ===\n\n selectOption(option: SuggestionOption) {\n const state = this.store.get();\n const activeSuggestion = state.actionableSuggestions[0];\n if (!activeSuggestion) return;\n\n const base = state.filterBase;\n let prefix = state.text.slice(0, base);\n\n const inputWasEmpty = prefix.length === 0 && state.text.length === 0;\n if (inputWasEmpty && state.placeholderText) {\n prefix = `${state.placeholderText} `;\n }\n\n const overlapChars = findPrefixOverlap(prefix, option.text);\n if (overlapChars > 0) {\n prefix = prefix.slice(0, prefix.length - overlapChars);\n }\n\n const needsSpace = prefix.length > 0 && prefix[prefix.length - 1] !== \" \";\n const newText = `${prefix}${needsSpace ? \" \" : \"\"}${option.text} `;\n const finalText =\n inputWasEmpty && newText.length > 0 ? newText[0].toUpperCase() + newText.slice(1) : newText;\n\n const optionStart = finalText.toLowerCase().lastIndexOf(option.text.toLowerCase());\n const optionInFinal =\n optionStart >= 0\n ? finalText.slice(optionStart, optionStart + option.text.length)\n : option.text;\n\n const completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: optionInFinal,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n\n const remainingActionable = state.actionableSuggestions.length - 1;\n\n this.store.set((s) => ({\n text: finalText,\n filterBase: finalText.length,\n completedParams: [...s.completedParams, completed],\n newParamId: completed.id,\n pillTapped: false,\n activeDropdownIndex: -1,\n skipNextFetch: remainingActionable > 0,\n }));\n\n // Delay suggestion removal for animation\n this.suggestionRemovalTimer = window.setTimeout(() => {\n this.store.set((s) => ({\n suggestions: s.suggestions.filter((sg) => sg !== activeSuggestion),\n }));\n }, 400);\n }\n\n private recomputeDerived(next: CoreState, _prev: CoreState) {\n if (this.derivedInProgress) return;\n this.derivedInProgress = true;\n const segments = deriveSegments(next.text, next.completedParams);\n const actionableSuggestions = next.suggestions.filter((s) => s.type !== \"placeholder\");\n const activeSuggestion = actionableSuggestions[0] as Suggestion | undefined;\n const overrideFn = activeSuggestion\n ? this.opts.optionOverrides?.[activeSuggestion.type]\n : undefined;\n\n // Clamp filterBase so it never exceeds text length (matches old React behavior)\n const clampedFilterBase = Math.min(next.filterBase, next.text.length);\n // When filterBase is 0 and no fetch has set it yet, don't filter by typed text —\n // the user is still typing the initial query and no server context exists\n const hasServerContext = next.lastRawQuery !== \"\" || clampedFilterBase > 0;\n const filterQuery = hasServerContext\n ? extractFilterQuery(next.text, clampedFilterBase, next.filterInProgress)\n : \"\";\n const baseOptions = activeSuggestion\n ? overrideFn\n ? overrideFn(filterQuery.trim())\n : (activeSuggestion.options ?? [])\n : [];\n const filteredOptions = filterOptions(baseOptions, filterQuery);\n\n const placeholderText =\n next.suggestions\n .filter((s) => s.type === \"placeholder\")\n .map((s) => s.text)\n .join(\" \") ||\n this.opts.placeholder ||\n \"\";\n\n const hasPlaceholder = placeholderText.length > 0;\n const trigger = this.opts.dropdownTrigger ?? \"auto\";\n let isDropdownOpen = false;\n if (trigger === \"auto\") {\n isDropdownOpen =\n !next.isLoading &&\n filteredOptions.length > 0 &&\n (!!next.text || next.pillTapped || !hasPlaceholder);\n } else if (trigger === \"manual\") {\n isDropdownOpen = !next.isLoading && filteredOptions.length > 0 && next.pillTapped;\n }\n\n this.store.set({\n segments,\n actionableSuggestions,\n filteredOptions,\n placeholderText,\n isDropdownOpen,\n });\n this.derivedInProgress = false;\n\n // Notify external listeners after derived state is settled\n const settled = this.store.get();\n for (const listener of this.externalListeners) {\n listener(settled);\n }\n }\n\n private setupContainer() {\n this.container.classList.add(\"magicx-aia\");\n // In dropdown mode, pills are always in the dropdown\n this.container.dataset.pillPlacement =\n this.renderMode === \"dropdown\" ? \"dropdown\" : (this.opts.pillPlacement ?? \"inline\");\n this.container.dataset.optionsPosition = this.opts.optionsPosition ?? \"below\";\n this.container.dataset.animations = (this.opts.animations ?? true) ? \"on\" : \"off\";\n\n // ModeController\n this.modeController = new ModeController(this.container, this.opts.mode ?? \"auto\");\n }\n\n private buildAndRenderFull() {\n const self = this;\n const renderOpts = {\n store: this.store,\n listboxId: this.listboxId,\n get pillPlacement() {\n return (self.opts.pillPlacement ?? \"inline\") as \"inline\" | \"dropdown\";\n },\n get onSubmit() {\n return self.opts.onSubmit;\n },\n selectOption: (option: SuggestionOption) => this.selectOption(option),\n setActivePill: (index: number) => this.pillsController.setActivePill(index),\n handleKeyDown: (e: KeyboardEvent) => this.keyboardController.handleKeyDown(e),\n handleChange: (value: string) => this.handleChange(value),\n };\n\n this.domRefs = buildDOM(this.container, renderOpts);\n\n this.subscribeBatchedRender(() => {\n if (this.domRefs) {\n updateDOM(this.domRefs, this.store.get(), renderOpts);\n }\n });\n\n // Initial render\n updateDOM(this.domRefs, this.store.get(), renderOpts);\n this.subscribeNewParamTimer();\n }\n\n private buildAndRenderDropdown() {\n const dropdownOpts = {\n store: this.store,\n listboxId: this.listboxId,\n selectOption: (option: SuggestionOption) => this.selectOption(option),\n setActivePill: (index: number) => this.pillsController.setActivePill(index),\n };\n\n this.dropdownRefs = buildDropdownOnly(this.container, dropdownOpts);\n\n this.subscribeBatchedRender(() => {\n if (this.dropdownRefs) {\n updateDropdownOnly(this.dropdownRefs, this.store.get(), dropdownOpts);\n }\n });\n\n // Initial render\n updateDropdownOnly(this.dropdownRefs, this.store.get(), dropdownOpts);\n this.subscribeNewParamTimer();\n }\n\n /** Batched render subscriber — coalesces multiple store.set calls into one DOM update. */\n private subscribeBatchedRender(render: () => void) {\n let scheduled = false;\n this.unsubscribers.push(\n this.store.subscribe(() => {\n if (scheduled) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n render();\n });\n }),\n );\n }\n\n /** Auto-clear newParamId after shimmer animation. */\n private subscribeNewParamTimer() {\n this.unsubscribers.push(\n this.store.subscribe((next, prev) => {\n if (next.newParamId && next.newParamId !== prev.newParamId) {\n if (this.newParamTimer) clearTimeout(this.newParamTimer);\n this.newParamTimer = window.setTimeout(() => {\n this.store.set({ newParamId: null });\n }, 650);\n }\n }),\n );\n }\n\n private handleChange(newValue: string) {\n const state = this.store.get();\n this.store.set({\n text: newValue,\n pillTapped: false,\n activeDropdownIndex: -1,\n });\n\n const { valid, invalid } = reconcileParams(newValue, state.completedParams);\n if (invalid.length > 0) {\n this.store.set((s) => ({\n completedParams: valid,\n suggestions: [\n ...invalid.map((param) => ({\n type: param.suggestionType,\n text: param.suggestionPlaceholder,\n required: true,\n options: param.options,\n })),\n ...s.suggestions,\n ],\n }));\n }\n }\n}\n"],"mappings":"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","names":["index_exports","__export","AIAutocomplete","AIAutocompleteDropdown","useAIAutocomplete","__toCommonJS","import_react","s","AIAutocomplete_module_css_default","s","AIAutocompleteDropdown_module_css_default","s","PillList_module_css_default","import_jsx_runtime","getPillOpacity","index","PillList","pills","activePillIndex","onSelectPill","rounded","PillList_module_css_default","pill","i","s","SuggestionGrid_module_css_default","import_react","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","pressed","setPressed","timerRef","handleSelect","className","SuggestionItem_module_css_default","e","import_jsx_runtime","SuggestionGrid","options","activeIndex","onSelect","onHighlight","listboxId","SuggestionGrid_module_css_default","option","i","SuggestionItem","import_jsx_runtime","AIAutocompleteDropdown","suggestions","activeIndex","onSelect","onHighlight","isOpen","id","className","pills","onPillClick","showPills","options","hasPills","isVisible","AIAutocompleteDropdown_module_css_default","e","PillList","SuggestionGrid","import_react","extractFilterQuery","text","filterBase","isInProgress","rawRegion","spaceIdx","findPrefixOverlap","prefix","optionText","trimmed","words","optionLower","i","candidate","suffixStart","filterOptions","options","query","lower","o","findExactMatch","ModeController","container","mode","deriveSegments","text","completedParams","result","pos","param","idx","remaining","reconcileParams","valid","invalid","TokenManager","config","forceRefresh","result","SDK_VERSION","hasWarnedMissingKey","generateRequestId","toWireParam","param","includeText","isAccessTokenConfig","config","getApiKeyConfig","tokenManagers","getTokenManager","manager","TokenManager","buildRequestBody","rawQuery","completedParams","rawCount","p","contactAccountCount","buildHeaders","apiConfig","doFetch","endpoint","headers","token","body","signal","fetchSuggestions","options","jsonBody","response","newToken","apiKeyConfig","apiKey","authScheme","buildQuery","text","completedParams","result","typeCounts","updatedParams","param","count","placeholder","index","applyOptionOverrides","suggestions","overrides","s","fn","extra","existingTexts","o","deduped","DEBOUNCE_MS","SLOW_DEBOUNCE_MS","MIN_CHARS_DIFF","FetchController","store","getApiConfig","getOptionOverrides","getMaskCompletedText","getOnError","prevText","prevParams","next","rawQuery","completed","controller","version","state","textAtRequest","res","fetchSuggestions","newSuggestions","applyOptionOverrides","input","lastInput","currentText","filterBase","filterInProgress","inProgressIdx","active","s","extraParam","query","extractFilterQuery","match","findExactMatch","err","caughtError","attemptFetch","minDiff","currentQuery","sg","tappableFiltered","filterOptions","o","hasExactMatch","isInFilterZone","updatedParams","buildQuery","isDeleting","charDiff","KeyboardController","store","ctx","state","columns","listboxId","getOnSubmit","onSubmit","tappableIndices","target","currentPos","nextPos","prevPos","rightNeighbor","leftNeighbor","rawQuery","finalParams","buildQuery","firstTappableIdx","o","placeholderSuggestion","s","sg","tappable","i","buckets","index","options","optionEl","actionable","moved","rest","_","placeholders","PillsController","store","index","state","actionable","s","moved","rest","_","i","placeholders","lastParam","restoredSuggestion","getPillOpacity","index","renderPills","container","pills","activePillIndex","onSelectPill","rounded","list","existing","btn","used","i","pill","key","createDropdown","listboxId","dropdown","e","renderDropdown","state","filteredOptions","activeIndex","isOpen","pills","showPills","onSelect","onHighlight","onPillClick","hasPills","pillBar","renderPills","grid","renderOptions","options","optionsKey","o","lastKey","listChanged","fragment","i","option","item","createOptionElement","items","isHighlighted","index","classes","streaks","streaksVert","content","tag","buildDropdownOnly","container","opts","dropdown","createDropdown","updateDropdownOnly","refs","state","renderDropdown","renderSegments","sizer","segments","newParamId","isEmpty","placeholderText","sizerText","placeholder","segmentKey","s","lastKey","lastParamId","seg","span","SUBMIT_SVG","buildDOM","container","opts","listboxId","dropdown","createDropdown","inputWrapper","editor","sizer","inlinePillContainer","textarea","submitButton","raw","newValue","e","state","rawQuery","finalParams","buildQuery","updateDOM","refs","pillPlacement","setActivePill","selectOption","store","activeDescendant","canSubmit","renderSegments","renderPills","renderDropdown","i","createStore","initial","state","listeners","patch","resolved","next","prev","l","listener","injected","injectStyles","style","STYLES","idCounter","stableId","initialState","AIAutocomplete","container","opts","createStore","PillsController","FetchController","KeyboardController","option","next","prev","injectStyles","unsub","mode","text","params","index","value","listener","event","callback","state","activeSuggestion","base","prefix","inputWasEmpty","overlapChars","findPrefixOverlap","needsSpace","newText","finalText","optionStart","optionInFinal","completed","remainingActionable","s","sg","_prev","segments","deriveSegments","actionableSuggestions","overrideFn","clampedFilterBase","filterQuery","extractFilterQuery","baseOptions","filteredOptions","filterOptions","placeholderText","hasPlaceholder","trigger","isDropdownOpen","settled","ModeController","self","renderOpts","e","buildDOM","updateDOM","dropdownOpts","buildDropdownOnly","updateDropdownOnly","render","scheduled","newValue","valid","invalid","reconcileParams","param","useAIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","customPlaceholder","apiConfig","columns","dropdownTrigger","controlledValue","controlledParams","onChangeProp","onParamsChange","instanceRef","coreState","setCoreState","onSubmitRef","onErrorRef","onChangeRef","onParamsChangeRef","AIAutocomplete","args","instance","noop","unsub","state","apiConfigJson","prevOverridesRef","overridesVersion","prev","next","prevKeys","nextKeys","k","handleChange","e","raw","newValue","handleKeyDown","setActivePill","index","removeLastParam","clearNewParamId","reset","selectOption","option","setActiveDropdownIndex","text","completedParams","actionableSuggestions","activeSuggestion","filteredOptions","activeDescendantId","import_jsx_runtime","resolveInitialMode","mode","AIAutocomplete","onSubmit","onError","optionOverrides","maskCompletedText","placeholder","className","apiConfig","columns","pillPlacement","optionsPosition","animations","dropdownTrigger","value","controlledParams","onChangeProp","onParamsChange","ref","containerRef","textareaRef","handleSubmitRef","modeControllerRef","el","ModeController","completedParams","suggestionPills","setActivePill","segments","newParamId","clearNewParamId","inputProps","dropdownProps","reset","useAIAutocomplete","result","timeoutId","m","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","showInlinePills","showDropdownPills","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","cls","PillList","e"]}