@magicx-eng/ai-autocomplete-react 0.1.13 → 0.1.14

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 CHANGED
@@ -29,7 +29,7 @@
29
29
  white-space: pre-wrap;
30
30
  word-break: break-word;
31
31
  font-family: inherit;
32
- font-size: 21px;
32
+ font-size: 19px;
33
33
  line-height: 38px;
34
34
  }
35
35
 
@@ -54,7 +54,7 @@
54
54
  color: var(--ac-color-text-default, #fff);
55
55
  caret-color: var(--ac-color-text-default, #fff);
56
56
  font-family: inherit;
57
- font-size: 21px;
57
+ font-size: 19px;
58
58
  line-height: 38px;
59
59
  white-space: pre-wrap;
60
60
  word-break: break-word;
@@ -92,7 +92,7 @@
92
92
  right: 0;
93
93
  top: 100%;
94
94
  margin-top: 6px;
95
- background: var(--ac-color-background-default, #00002d);
95
+ background: var(--ac-color-background-default, #0b0247);
96
96
  border-radius: 23px;
97
97
  overflow: hidden;
98
98
  z-index: 10;
@@ -128,14 +128,15 @@
128
128
  background: rgba(255, 255, 255, 0.3);
129
129
  border-radius: 3px;
130
130
  }
131
- `,document.head.appendChild(e)}var Te={grid:"SuggestionGrid-module_grid_jvaPb"};if(typeof document<"u"&&!document.getElementById("ac-style-f6bdc634")){let e=document.createElement("style");e.id="ac-style-f6bdc634",e.textContent=`.SuggestionItem-module_item_d4vpD {
131
+ `,document.head.appendChild(e)}var Ee={grid:"SuggestionGrid-module_grid_jvaPb"};if(typeof document<"u"&&!document.getElementById("ac-style-f6bdc634")){let e=document.createElement("style");e.id="ac-style-f6bdc634",e.textContent=`.SuggestionItem-module_item_d4vpD {
132
132
  display: flex;
133
133
  align-items: center;
134
134
  font-family: "IBM Plex Sans", sans-serif;
135
- font-size: 21px;
135
+ font-size: 19px;
136
136
  line-height: 30px;
137
137
  color: var(--ac-color-text-muted, #c1c4cb);
138
- white-space: nowrap;
138
+ white-space: normal;
139
+ word-break: break-word;
139
140
  opacity: 0.35;
140
141
  animation: SuggestionItem-module_fadeIn_I8u35 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
141
142
  }
@@ -165,11 +166,11 @@
165
166
  }
166
167
 
167
168
  .SuggestionItem-module_tag_e3Fwe {
168
- font-size: 13px;
169
+ font-size: 11px;
169
170
  margin-left: 6px;
170
171
  opacity: 0.5;
171
172
  }
172
- `,document.head.appendChild(e)}var J={item:"SuggestionItem-module_item_d4vpD",fadeIn:"SuggestionItem-module_fadeIn_I8u35",tappable:"SuggestionItem-module_tappable_70KcX",nonTappable:"SuggestionItem-module_nonTappable_xSZM-",highlighted:"SuggestionItem-module_highlighted_Hb0SU",tag:"SuggestionItem-module_tag_e3Fwe"};var ae=require("react/jsx-runtime");function Ee({option:e,isHighlighted:n,onSelect:t,onHighlight:o,id:r}){let i=[J.item,n?J.highlighted:"",e.is_tappable?J.tappable:J.nonTappable].filter(Boolean).join(" ");return(0,ae.jsxs)("div",{id:r,role:"option","aria-selected":n,className:i,tabIndex:e.is_tappable?0:-1,onClick:()=>e.is_tappable&&t(e),onKeyDown:s=>{e.is_tappable&&(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),t(e))},onMouseEnter:o,children:[e.icon?`${e.icon} ${e.text}`:e.text,e.tag&&(0,ae.jsx)("span",{className:J.tag,children:e.tag})]})}var _e=require("react/jsx-runtime");function Le({options:e,activeIndex:n,onSelect:t,onHighlight:o,listboxId:r}){return(0,_e.jsx)("div",{className:Te.grid,children:e.map((i,s)=>(0,_e.jsx)(Ee,{option:i,isHighlighted:s===n,onSelect:t,onHighlight:()=>o(s),id:`${r}-option-${s}`},i.text))})}var ve=require("react/jsx-runtime");function se({suggestions:e,activeIndex:n,onSelect:t,onHighlight:o,isOpen:r,id:i,className:s}){let m=e[0]?.options??[],c=r&&m.length>0;return(0,ve.jsx)("div",{id:i,role:"listbox",className:`${Ae.dropdown} ${c?Ae.visible:""} ${s??""}`,onMouseDown:u=>u.preventDefault(),children:m.length>0&&(0,ve.jsx)(Le,{options:m,activeIndex:n,onSelect:t,onHighlight:o,listboxId:i})})}if(typeof document<"u"&&!document.getElementById("ac-style-b745b4fb")){let e=document.createElement("style");e.id="ac-style-b745b4fb",e.textContent=`.PillList-module_list_qvLqO {
173
+ `,document.head.appendChild(e)}var J={item:"SuggestionItem-module_item_d4vpD",fadeIn:"SuggestionItem-module_fadeIn_I8u35",tappable:"SuggestionItem-module_tappable_70KcX",nonTappable:"SuggestionItem-module_nonTappable_xSZM-",highlighted:"SuggestionItem-module_highlighted_Hb0SU",tag:"SuggestionItem-module_tag_e3Fwe"};var ae=require("react/jsx-runtime");function Te({option:e,isHighlighted:n,onSelect:t,onHighlight:o,id:r}){let i=[J.item,n?J.highlighted:"",e.is_tappable?J.tappable:J.nonTappable].filter(Boolean).join(" ");return(0,ae.jsxs)("div",{id:r,role:"option","aria-selected":n,className:i,tabIndex:e.is_tappable?0:-1,onClick:()=>e.is_tappable&&t(e),onKeyDown:s=>{e.is_tappable&&(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),t(e))},onMouseEnter:o,children:[e.icon?`${e.icon} ${e.text}`:e.text,e.tag&&(0,ae.jsx)("span",{className:J.tag,children:e.tag})]})}var _e=require("react/jsx-runtime");function Le({options:e,activeIndex:n,onSelect:t,onHighlight:o,listboxId:r}){return(0,_e.jsx)("div",{className:Ee.grid,children:e.map((i,s)=>(0,_e.jsx)(Te,{option:i,isHighlighted:s===n,onSelect:t,onHighlight:()=>o(s),id:`${r}-option-${s}`},i.text))})}var ve=require("react/jsx-runtime");function se({suggestions:e,activeIndex:n,onSelect:t,onHighlight:o,isOpen:r,id:i,className:s}){let m=e[0]?.options??[],c=r&&m.length>0;return(0,ve.jsx)("div",{id:i,role:"listbox",className:`${Ae.dropdown} ${c?Ae.visible:""} ${s??""}`,onMouseDown:u=>u.preventDefault(),children:m.length>0&&(0,ve.jsx)(Le,{options:m,activeIndex:n,onSelect:t,onHighlight:o,listboxId:i})})}if(typeof document<"u"&&!document.getElementById("ac-style-b745b4fb")){let e=document.createElement("style");e.id="ac-style-b745b4fb",e.textContent=`.PillList-module_list_qvLqO {
173
174
  position: relative;
174
175
  z-index: 1;
175
176
  pointer-events: auto;
@@ -191,7 +192,7 @@
191
192
  background: var(--ac-color-background-supportive, #313255);
192
193
  color: var(--ac-color-text-muted, #c1c4cb);
193
194
  font-family: "IBM Plex Sans", sans-serif;
194
- font-size: 21px;
195
+ font-size: 19px;
195
196
  line-height: 30px;
196
197
  cursor: pointer;
197
198
  white-space: nowrap;
@@ -211,5 +212,5 @@
211
212
  opacity: 0;
212
213
  }
213
214
  }
214
- `,document.head.appendChild(e)}var le={list:"PillList-module_list_qvLqO",pill:"PillList-module_pill_osSyz",fadeIn:"PillList-module_fadeIn_Aezob",active:"PillList-module_active_Oll--"};var Pe=require("react/jsx-runtime");function st(e){return e===0?.4:e===1?.3:.15}function Ue({pills:e,activePillIndex:n,onSelectPill:t}){return(0,Pe.jsx)("span",{className:le.list,children:e.map((o,r)=>(0,Pe.jsx)("button",{type:"button",className:`${le.pill} ${r===n?le.active:""}`,style:{opacity:st(r)},onClick:()=>t(r),children:o.text},`${o.type}-${o.text}`))})}var p=require("react");function Y(e,n,t){let o=e.slice(n);if(t||n===0||e[n-1]===" ")return o;let r=o.indexOf(" ");return r===-1?"":o.slice(r+1)}function ce(e,n){if(!e)return[];let t=n.trimStart();if(!t)return e;let o=t.toLowerCase();return e.filter(r=>!r.is_tappable||r.text.toLowerCase().includes(o))}function re(e,n){if(!e)return null;let t=n.trim();if(!t)return null;let o=t.toLowerCase();return e.find(r=>r.is_tappable&&r.text.toLowerCase()===o)??null}function De(e,n){let t=[],o=0;for(let i of n){let s=e.indexOf(i.text,o);s!==-1&&(s>o&&t.push({type:"text",value:e.slice(o,s)}),t.push({type:"completed",value:i.text,param:i}),o=s+i.text.length)}let r=e.slice(o);return r&&t.push({type:"text",value:r}),t}function Ke(e,n){let t=[],o=[],r=0;for(let i of n){let s=e.indexOf(i.text,r);s===-1?o.push(i):(t.push(i),r=s+i.text.length)}return{valid:t,invalid:o}}var R=require("react");var lt="0.1.13",je=!1;function ct(){return crypto.randomUUID()}function ut(e,n){return{placeholder:e.placeholder,type:e.type,...n&&{text:e.text},kind:e.kind}}async function ze(e,n,t){let o=t?.apiConfig,r=o?.apiKey??"";!r&&!je&&(je=!0,console.warn("[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header."));let i=o?.authScheme??"Bearer",s=!t?.maskCompletedText,h=n.find(g=>g.type==="contact"&&g.metadata?.contact_account_count)?.metadata?.contact_account_count,m=typeof h=="number"?h:void 0,c={data:{raw_query:e,completed_params:n.map(g=>ut(g,s)),...m!=null&&{contact_account_count:m}},meta:{request_id:ct(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:lt}},u={"Content-Type":"application/json",...o?.appIdentifier&&{"X-App-Identifier":o.appIdentifier},...o?.headers};r&&(u.Authorization=i==="Basic"?`Basic ${btoa(r)}`:`Bearer ${r}`);let y=await fetch(o?.endpoint??"/ac/suggest",{method:"POST",headers:u,body:JSON.stringify(c),signal:t?.signal});if(!y.ok)throw new Error(`API error: ${y.status} ${y.statusText}`);return y.json()}function ee(e,n){let t=e,o={},r=[];for(let i of n){let s=(o[i.type]??0)+1;o[i.type]=s;let m=`{{${i.type.toUpperCase().replace(/\s+/g,"_")}_${s}}}`,c=t.indexOf(i.text);c!==-1&&(t=t.slice(0,c)+m+t.slice(c+i.text.length)),r.push({...i,placeholder:m})}return{rawQuery:t,completedParams:r}}function Fe(e,n){return n?e.map(t=>{let o=n[t.type];if(!o)return t;let r=o("");if(r.length===0)return t;let i=new Set(r.map(h=>h.text)),s=(t.options??[]).filter(h=>!i.has(h.text));return{...t,options:[...r,...s]}}):e}var pt=100,dt=300,mt=2;function qe({textRef:e,suggestionsRef:n,filterBaseRef:t,filterInProgressRef:o,maskCompletedTextRef:r,apiConfigRef:i,optionOverridesRef:s,onErrorRef:h,setCompletedParams:m,setSuggestions:c,setActiveDropdownIndex:u}){let[y,g]=(0,R.useState)(!1),[f,_]=(0,R.useState)(null),[x,v]=(0,R.useState)(!1),w=(0,R.useRef)(0),A=(0,R.useRef)(null),I=(0,R.useRef)(""),b=(0,R.useCallback)(async(d,a)=>{A.current?.abort();let l=new AbortController;A.current=l;let K=++w.current,k=e.current.length;n.current.some(E=>E.type!=="placeholder")||g(!0),_(null);try{let E=await ze(d,a,{maskCompletedText:r.current,signal:l.signal,apiConfig:i.current});if(K!==w.current)return;let j=Fe(E.data.suggestions??[],s.current);v(E.data.is_ready??!1),I.current=d;let L=E.data.input??[],M=L[L.length-1],U=e.current;if(M?.state==="in_progress"){o.current=!0;let N=U.toLowerCase().lastIndexOf(M.text.toLowerCase());N!==-1?t.current=N:t.current=k}else o.current=!1,t.current=k;let q=j.filter(N=>N.type!=="placeholder")[0];if(q){let N=Y(U,t.current,o.current),B=re(q.options,N);B&&(m(V=>[...V,{id:crypto.randomUUID(),placeholder:"",type:q.type,text:B.text,kind:B.kind,suggestionType:q.type,suggestionPlaceholder:q.text,options:q.options??[],metadata:B.metadata}]),j=j.filter(V=>V!==q))}c(j),g(!1),u(-1)}catch(E){if(K===w.current){let j=E instanceof Error?E:new Error(String(E));_(j),g(!1),h.current?.(j)}}},[e,n,t,o,r,i,s,h,m,c,u]);return(0,R.useEffect)(()=>(b("",[]),()=>{A.current?.abort()}),[b]),{doFetch:b,isLoading:y,error:f,isReady:x,lastRawQueryRef:I}}function Ne({text:e,completedParams:n,doFetch:t,filterBaseRef:o,filterInProgressRef:r,skipNextFetchRef:i,suggestionsRef:s,lastRawQueryRef:h}){let m=(0,R.useRef)(null),c=(0,R.useRef)(null),u=(0,R.useRef)(!0);(0,R.useEffect)(()=>{m.current&&clearTimeout(m.current),c.current&&clearTimeout(c.current);let y=g=>{if(i.current)return i.current=!1,!1;if(!e&&n.length===0)return u.current?(t("",[]),!0):(u.current=!0,!1);let f=Y(e,o.current,r.current),v=s.current.filter(k=>k.type!=="placeholder")[0],A=(v?ce(v.options,f):[]).filter(k=>k.is_tappable),I=v?re(v.options,f)!==null:!1,b=f.trim().length>0;if(A.length>0&&!I&&b)return!1;let{rawQuery:d,completedParams:a}=ee(e,n),l=d.length<h.current.length,K=Math.abs(d.length-h.current.length);return l||K>=g?(t(d,a),!0):!1};return m.current=setTimeout(()=>{y(mt)&&c.current&&clearTimeout(c.current)},pt),c.current=setTimeout(()=>y(1),dt),()=>{m.current&&clearTimeout(m.current),c.current&&clearTimeout(c.current)}},[e,n,t,o,r,i,s,h])}var Ce=require("react");function Qe({activeDropdownIndex:e,setActiveDropdownIndex:n,filteredOptions:t,selectOption:o,onSubmitRef:r,text:i,completedParams:s,isDropdownOpen:h,hasPlaceholder:m,placeholderText:c,suggestions:u,actionableSuggestions:y,setActivePill:g,filterBaseRef:f,columns:_,setText:x,setCompletedParams:v,setSuggestions:w}){let A=(0,Ce.useCallback)(()=>{let b=t.map((a,l)=>a.is_tappable?l:-1).filter(a=>a!==-1),d=Array.from({length:_},()=>[]);for(let a of b)d[a%_].push(a);return d.flat()},[t,_]);return{handleKeyDown:(0,Ce.useCallback)(b=>{let d=A();switch(b.key){case"ArrowDown":{if(b.preventDefault(),d.length===0)return;let a=d.indexOf(e),l=a<d.length-1?a+1:0;n(d[l]);break}case"ArrowUp":{if(b.preventDefault(),d.length===0)return;let a=d.indexOf(e),l=a>0?a-1:d.length-1;n(d[l]);break}case"ArrowRight":{if(e<0){y.length>1&&(b.preventDefault(),g(1));break}if(e%_<_-1){let l=e+1;l<t.length&&t[l]?.is_tappable&&(b.preventDefault(),n(l))}break}case"ArrowLeft":{if(e<0)break;if(e%_>0){let a=e-1;a>=0&&t[a]?.is_tappable&&(b.preventDefault(),n(a))}break}case"Enter":{if(b.preventDefault(),e>=0&&t[e]?.is_tappable)o(t[e]);else if(r.current){let{rawQuery:a,completedParams:l}=ee(i,s),K={query:i.trim(),raw_query:a,completed_params:l};r.current(K)}break}case"Tab":{if(e>=0&&t[e]?.is_tappable)b.preventDefault(),o(t[e]);else if(h){let a=t.find(l=>l.is_tappable);a&&(b.preventDefault(),o(a))}else if(!i&&m){b.preventDefault();let a=u.find(l=>l.type==="placeholder");a?(x(c),f.current=c.length,v(l=>[...l,{id:crypto.randomUUID(),placeholder:"",type:a.type,text:c,kind:null,suggestionType:a.type,suggestionPlaceholder:a.text,options:a.options??[]}]),w(l=>l.filter(K=>K!==a))):(x(c),f.current=c.length)}break}case"Escape":n(-1);break}},[y,e,_,s,t,f,A,m,h,r,c,o,n,g,v,w,x,u,i]),getTappableIndices:A}}var ue=require("react");function $e({completedParams:e,suggestions:n,setCompletedParams:t,setSuggestions:o,setActiveDropdownIndex:r,filterBaseRef:i,pillTappedRef:s}){let h=(0,ue.useCallback)(u=>{let y=n.filter(x=>x.type!=="placeholder");if(u<0||u>=y.length)return;let g=y[u],f=y.filter((x,v)=>v!==u),_=n.filter(x=>x.type==="placeholder");o([..._,g,...f]),s.current=!0,r(-1)},[n,o,r,s]),m=(0,ue.useCallback)(()=>{if(e.length===0)return;let u=e[e.length-1],y={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};t(g=>g.slice(0,-1)),o(g=>[y,...g]),r(-1)},[e,t,o,r]),c=(0,ue.useCallback)(u=>{let y={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};return{apply:g=>{g(f=>{let _=0;for(let x of e){let v=f.indexOf(x.text,_);if(v!==-1){if(x.id===u.id){let w=f.slice(0,v),A=f.slice(v+u.text.length),I=(w+A).replace(/ {2,}/g," ");return i.current=Math.min(i.current,I.length),I}_=v+x.text.length}}return f}),t(f=>f.filter(_=>_.id!==u.id)),o(f=>[y,...f]),r(-1),s.current=!0}}},[e,t,o,r,i,s]);return{setActivePill:h,removeLastParam:m,reEditParam:c}}var gt=0;function ft(){let e=(0,p.useRef)(null);return e.current===null&&(e.current=`:ac-${++gt}:`),e.current}function pe({onSubmit:e,onError:n,optionOverrides:t,maskCompletedText:o,placeholder:r,apiConfig:i,columns:s=2,eagerSuggestions:h=!0,value:m,completedParams:c,onChange:u,onParamsChange:y}){let g=m!==void 0,f=c!==void 0,[_,x]=(0,p.useState)(""),[v,w]=(0,p.useState)([]),[A,I]=(0,p.useState)([]),[b,d]=(0,p.useState)(-1),a=g?m:_,l=f?c:v,K=(0,p.useRef)(e);K.current=e;let k=(0,p.useRef)(u);k.current=u;let $=(0,p.useRef)(y);$.current=y;let E=(0,p.useRef)(m);E.current=m;let j=(0,p.useRef)(c);j.current=c;let L=(0,p.useCallback)(S=>{if(typeof S=="function")if(g){let C=S(E.current??"");k.current?.(C)}else x(C=>{let H=S(C);return k.current?.(H),H});else g||x(S),k.current?.(S)},[g]),M=(0,p.useCallback)(S=>{if(typeof S=="function")if(f){let C=S(j.current??[]);$.current?.(C)}else w(C=>{let H=S(C);return $.current?.(H),H});else f||w(S),$.current?.(S)},[f]),U=(0,p.useRef)(n);U.current=n;let W=(0,p.useRef)(t);W.current=t;let q=(0,p.useRef)(o);q.current=o;let N=(0,p.useRef)(i);N.current=i;let B=(0,p.useRef)(a);B.current=a;let V=(0,p.useRef)(A);V.current=A;let z=(0,p.useRef)(0),te=(0,p.useRef)(!1),ie=(0,p.useRef)(!1),Ie=(0,p.useRef)(!1),de=ft(),{doFetch:me,isLoading:we,error:He,isReady:We,lastRawQueryRef:ge}=qe({textRef:B,suggestionsRef:V,filterBaseRef:z,filterInProgressRef:te,maskCompletedTextRef:q,apiConfigRef:N,optionOverridesRef:W,onErrorRef:U,setCompletedParams:M,setSuggestions:I,setActiveDropdownIndex:d});Ne({text:a,completedParams:l,doFetch:me,filterBaseRef:z,filterInProgressRef:te,skipNextFetchRef:Ie,suggestionsRef:V,lastRawQueryRef:ge});let Ve=(0,p.useMemo)(()=>De(a,l),[a,l]);z.current=Math.min(z.current,a.length);let fe=Y(a,z.current,te.current),be=(0,p.useMemo)(()=>A.filter(C=>C.type==="placeholder").map(C=>C.text).join(" ")||r||"",[A,r]),oe=(0,p.useMemo)(()=>A.filter(S=>S.type!=="placeholder"),[A]),P=oe[0],Oe=P?t?.[P.type]:void 0,Re=P?Oe?Oe(fe.trim()):P.options??[]:[],he=(0,p.useMemo)(()=>ce(Re,fe),[Re,fe]),ke=be.length>0,ye=!we&&he.length>0&&(!!a||ie.current||!ke),Me=(0,p.useCallback)(S=>{if(!P)return;let C={id:crypto.randomUUID(),placeholder:"",type:P.type,text:S.text,kind:S.kind,suggestionType:P.type,suggestionPlaceholder:P.text,options:P.options??[],metadata:S.metadata},H=z.current,D=B.current.slice(0,H);if(D.length>0&&!D.endsWith(" ")){let O=D.split(/\s+/).pop()??"";O&&S.text.toLowerCase().startsWith(O.toLowerCase())&&(D=D.slice(0,D.length-O.length))}let Se=D.length>0&&D[D.length-1]!==" ",Z=D+(Se?" ":"")+S.text+" ";L(Z),z.current=Z.length,M(O=>[...O,C]),ie.current=!1,d(-1);let G=oe.length-1;h&&G>0?(I(O=>O.filter(X=>X!==P)),Ie.current=!0):I(O=>O.filter(X=>X.type==="placeholder"))},[P,oe,h,L,M]),Ge=(0,p.useCallback)(S=>{let C=S.target.value,D=C.length>0&&!S.nativeEvent?.isComposing&&C[0]!==C[0].toUpperCase()?C[0].toUpperCase()+C.slice(1):C;L(D),ie.current=!1,d(-1);let{valid:Se,invalid:Z}=Ke(D,l);if(Z.length>0){M(()=>Se);for(let G of Z)I(O=>[{type:G.suggestionType,text:G.suggestionPlaceholder,required:!0,options:G.options},...O])}if(P&&Z.length===0){let G=Y(D,z.current,te.current),O=re(P.options,G);O&&(M(X=>[...X,{id:crypto.randomUUID(),placeholder:"",type:P.type,text:O.text,kind:O.kind,suggestionType:P.type,suggestionPlaceholder:P.text,options:P.options??[],metadata:O.metadata}]),I(X=>X.filter(et=>et!==P)))}},[l,P,L,M]),ne=$e({completedParams:l,suggestions:A,setCompletedParams:M,setSuggestions:I,setActiveDropdownIndex:d,filterBaseRef:z,pillTappedRef:ie}),Xe=(0,p.useCallback)(S=>{ne.reEditParam(S).apply(L)},[ne,L]),{handleKeyDown:Ze}=Qe({activeDropdownIndex:b,setActiveDropdownIndex:d,filteredOptions:he,selectOption:Me,onSubmitRef:K,text:a,completedParams:l,isDropdownOpen:ye,hasPlaceholder:ke,placeholderText:be,suggestions:A,actionableSuggestions:oe,setActivePill:ne.setActivePill,filterBaseRef:z,columns:s,setText:L,setCompletedParams:M,setSuggestions:I}),Je=(0,p.useCallback)(()=>{L(""),M(()=>[]),I([]),d(-1),z.current=0,te.current=!1,ge.current="",me("",[])},[me,L,M,ge]),Ye=b>=0?`${de}-option-${b}`:void 0;return{completedParams:l,suggestionPills:oe,setActivePill:ne.setActivePill,removeLastParam:ne.removeLastParam,reEditParam:Xe,segments:Ve,suggestions:A,activeIndex:b,isReady:We,isLoading:we,error:He,inputProps:{value:a,placeholder:be||void 0,onChange:Ge,onKeyDown:Ze,role:"combobox","aria-expanded":ye,"aria-activedescendant":Ye,"aria-autocomplete":"list","aria-controls":de},reset:Je,dropdownProps:{suggestions:P?[{...P,options:he}]:[],activeIndex:b,onSelect:Me,onHighlight:d,isOpen:ye,id:de}}}var T=require("react/jsx-runtime"),Be=(0,F.forwardRef)(function({onSubmit:n,onError:t,optionOverrides:o,maskCompletedText:r,placeholder:i,className:s,apiConfig:h,columns:m,eagerSuggestions:c,value:u,completedParams:y,onChange:g,onParamsChange:f},_){let x=(0,F.useRef)(null),v=(0,F.useRef)(()=>{});(0,F.useEffect)(()=>{x.current?.focus()},[]);let{completedParams:w,suggestionPills:A,setActivePill:I,segments:b,inputProps:d,dropdownProps:a,reset:l}=pe({onSubmit:U=>v.current(U),onError:t,optionOverrides:o,maskCompletedText:r,placeholder:i,apiConfig:h,columns:m,eagerSuggestions:c,value:u,completedParams:y,onChange:g,onParamsChange:f});(0,F.useImperativeHandle)(_,()=>({focus:()=>x.current?.focus(),reset:l}),[l]);let K=()=>{x.current?.focus()},k=!!d.value||w.length>0,$=(0,F.useCallback)(()=>{if(!k)return;let{rawQuery:U,completedParams:W}=ee(d.value,w);n({query:d.value.trim(),raw_query:U,completed_params:W}),l()},[k,d.value,w,n,l]);v.current=$;let{onChange:E,placeholder:j,...L}=d,M=!d.value;return(0,T.jsxs)("div",{className:`${Q.container} ${s??""}`,children:[(0,T.jsx)(se,{...a}),(0,T.jsxs)("div",{className:Q.inputWrapper,onClick:K,children:[(0,T.jsxs)("div",{className:Q.editorArea,children:[(0,T.jsxs)("div",{className:Q.sizerContent,"aria-hidden":"true",children:[M&&j?(0,T.jsxs)("span",{className:Q.placeholderText,children:[j," "]}):(0,T.jsxs)("span",{className:Q.sizerText,children:[b.map((U,W)=>(0,T.jsx)("span",{children:U.value},`${W}-${U.type}`)),b.length===0&&"\xA0"]})," ",(0,T.jsx)(Ue,{pills:A,activePillIndex:0,onSelectPill:I})]}),(0,T.jsx)("textarea",{ref:x,className:Q.textarea,rows:1,onChange:E,...L})]}),(0,T.jsx)("button",{type:"button",className:Q.submitButton,disabled:!k,onClick:U=>{U.stopPropagation(),$()},"aria-label":"Submit",children:(0,T.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",role:"img","aria-label":"Submit",children:(0,T.jsx)("path",{d:"M9 14V4M9 4L4 9M9 4L14 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})});0&&(module.exports={AIAutocomplete,AIAutocompleteDropdown,useAIAutocomplete});
215
+ `,document.head.appendChild(e)}var le={list:"PillList-module_list_qvLqO",pill:"PillList-module_pill_osSyz",fadeIn:"PillList-module_fadeIn_Aezob",active:"PillList-module_active_Oll--"};var Pe=require("react/jsx-runtime");function st(e){return e===0?.4:e===1?.3:.15}function Ue({pills:e,activePillIndex:n,onSelectPill:t}){return(0,Pe.jsx)("span",{className:le.list,children:e.map((o,r)=>(0,Pe.jsx)("button",{type:"button",className:`${le.pill} ${r===n?le.active:""}`,style:{opacity:st(r)},onClick:()=>t(r),children:o.text},`${o.type}-${o.text}`))})}var p=require("react");function Y(e,n,t){let o=e.slice(n);if(t||n===0||e[n-1]===" ")return o;let r=o.indexOf(" ");return r===-1?"":o.slice(r+1)}function ce(e,n){if(!e)return[];let t=n.trimStart();if(!t)return e;let o=t.toLowerCase();return e.filter(r=>!r.is_tappable||r.text.toLowerCase().includes(o))}function re(e,n){if(!e)return null;let t=n.trim();if(!t)return null;let o=t.toLowerCase();return e.find(r=>r.is_tappable&&r.text.toLowerCase()===o)??null}function De(e,n){let t=[],o=0;for(let i of n){let s=e.indexOf(i.text,o);s!==-1&&(s>o&&t.push({type:"text",value:e.slice(o,s)}),t.push({type:"completed",value:i.text,param:i}),o=s+i.text.length)}let r=e.slice(o);return r&&t.push({type:"text",value:r}),t}function Ke(e,n){let t=[],o=[],r=0;for(let i of n){let s=e.indexOf(i.text,r);s===-1?o.push(i):(t.push(i),r=s+i.text.length)}return{valid:t,invalid:o}}var R=require("react");var lt="0.1.14",je=!1;function ct(){return crypto.randomUUID()}function ut(e,n){return{placeholder:e.placeholder,type:e.type,...n&&{text:e.text},kind:e.kind}}async function ze(e,n,t){let o=t?.apiConfig,r=o?.apiKey??"";!r&&!je&&(je=!0,console.warn("[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header."));let i=o?.authScheme??"Bearer",s=!t?.maskCompletedText,h=n.find(g=>g.type==="contact"&&g.metadata?.contact_account_count)?.metadata?.contact_account_count,m=typeof h=="number"?h:void 0,c={data:{raw_query:e,completed_params:n.map(g=>ut(g,s)),...m!=null&&{contact_account_count:m}},meta:{request_id:ct(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:lt}},u={"Content-Type":"application/json",...o?.appIdentifier&&{"X-App-Identifier":o.appIdentifier},...o?.headers};r&&(u.Authorization=i==="Basic"?`Basic ${btoa(r)}`:`Bearer ${r}`);let y=await fetch(o?.endpoint??"/ac/suggest",{method:"POST",headers:u,body:JSON.stringify(c),signal:t?.signal});if(!y.ok)throw new Error(`API error: ${y.status} ${y.statusText}`);return y.json()}function ee(e,n){let t=e,o={},r=[];for(let i of n){let s=(o[i.type]??0)+1;o[i.type]=s;let m=`{{${i.type.toUpperCase().replace(/\s+/g,"_")}_${s}}}`,c=t.indexOf(i.text);c!==-1&&(t=t.slice(0,c)+m+t.slice(c+i.text.length)),r.push({...i,placeholder:m})}return{rawQuery:t,completedParams:r}}function Fe(e,n){return n?e.map(t=>{let o=n[t.type];if(!o)return t;let r=o("");if(r.length===0)return t;let i=new Set(r.map(h=>h.text)),s=(t.options??[]).filter(h=>!i.has(h.text));return{...t,options:[...r,...s]}}):e}var pt=100,dt=300,mt=2;function qe({textRef:e,suggestionsRef:n,filterBaseRef:t,filterInProgressRef:o,maskCompletedTextRef:r,apiConfigRef:i,optionOverridesRef:s,onErrorRef:h,setCompletedParams:m,setSuggestions:c,setActiveDropdownIndex:u}){let[y,g]=(0,R.useState)(!1),[b,_]=(0,R.useState)(null),[x,v]=(0,R.useState)(!1),w=(0,R.useRef)(0),A=(0,R.useRef)(null),I=(0,R.useRef)(""),f=(0,R.useCallback)(async(d,a)=>{A.current?.abort();let l=new AbortController;A.current=l;let T=++w.current,k=e.current.length;n.current.some(L=>L.type!=="placeholder")||g(!0),_(null);try{let L=await ze(d,a,{maskCompletedText:r.current,signal:l.signal,apiConfig:i.current});if(T!==w.current)return;let j=Fe(L.data.suggestions??[],s.current);v(L.data.is_ready??!1),I.current=d;let U=L.data.input??[],M=U[U.length-1],D=e.current;if(M?.state==="in_progress"){o.current=!0;let N=D.toLowerCase().lastIndexOf(M.text.toLowerCase());N!==-1?t.current=N:t.current=k}else o.current=!1,t.current=k;let q=j.filter(N=>N.type!=="placeholder")[0];if(q){let N=Y(D,t.current,o.current),B=re(q.options,N);B&&(m(V=>[...V,{id:crypto.randomUUID(),placeholder:"",type:q.type,text:B.text,kind:B.kind,suggestionType:q.type,suggestionPlaceholder:q.text,options:q.options??[],metadata:B.metadata}]),j=j.filter(V=>V!==q))}c(j),g(!1),u(-1)}catch(L){if(T===w.current){let j=L instanceof Error?L:new Error(String(L));_(j),g(!1),h.current?.(j)}}},[e,n,t,o,r,i,s,h,m,c,u]);return(0,R.useEffect)(()=>(f("",[]),()=>{A.current?.abort()}),[f]),{doFetch:f,isLoading:y,error:b,isReady:x,lastRawQueryRef:I}}function Ne({text:e,completedParams:n,doFetch:t,filterBaseRef:o,filterInProgressRef:r,skipNextFetchRef:i,suggestionsRef:s,lastRawQueryRef:h}){let m=(0,R.useRef)(null),c=(0,R.useRef)(null),u=(0,R.useRef)(!0);(0,R.useEffect)(()=>{m.current&&clearTimeout(m.current),c.current&&clearTimeout(c.current);let y=g=>{if(i.current)return i.current=!1,!1;if(!e&&n.length===0)return u.current?(t("",[]),!0):(u.current=!0,!1);let b=Y(e,o.current,r.current),v=s.current.filter(k=>k.type!=="placeholder")[0],A=(v?ce(v.options,b):[]).filter(k=>k.is_tappable),I=v?re(v.options,b)!==null:!1,f=b.trim().length>0;if(A.length>0&&!I&&f)return!1;let{rawQuery:d,completedParams:a}=ee(e,n),l=d.length<h.current.length,T=Math.abs(d.length-h.current.length);return l||T>=g?(t(d,a),!0):!1};return m.current=setTimeout(()=>{y(mt)&&c.current&&clearTimeout(c.current)},pt),c.current=setTimeout(()=>y(1),dt),()=>{m.current&&clearTimeout(m.current),c.current&&clearTimeout(c.current)}},[e,n,t,o,r,i,s,h])}var Ce=require("react");function Qe({activeDropdownIndex:e,setActiveDropdownIndex:n,filteredOptions:t,selectOption:o,onSubmitRef:r,text:i,completedParams:s,isDropdownOpen:h,hasPlaceholder:m,placeholderText:c,suggestions:u,actionableSuggestions:y,setActivePill:g,filterBaseRef:b,columns:_,setText:x,setCompletedParams:v,setSuggestions:w}){let A=(0,Ce.useCallback)(()=>{let f=t.map((a,l)=>a.is_tappable?l:-1).filter(a=>a!==-1),d=Array.from({length:_},()=>[]);for(let a of f)d[a%_].push(a);return d.flat()},[t,_]);return{handleKeyDown:(0,Ce.useCallback)(f=>{let d=A();switch(f.key){case"ArrowDown":{if(f.preventDefault(),d.length===0)return;let a=d.indexOf(e),l=a<d.length-1?a+1:0;n(d[l]);break}case"ArrowUp":{if(f.preventDefault(),d.length===0)return;let a=d.indexOf(e),l=a>0?a-1:d.length-1;n(d[l]);break}case"ArrowRight":{if(e<0){let l=f.target;l.selectionStart!=null&&l.selectionStart===l.value.length&&y.length>1&&(f.preventDefault(),g(1));break}if(e%_<_-1){let l=e+1;l<t.length&&t[l]?.is_tappable&&(f.preventDefault(),n(l))}break}case"ArrowLeft":{if(e<0)break;if(e%_>0){let a=e-1;a>=0&&t[a]?.is_tappable&&(f.preventDefault(),n(a))}break}case"Enter":{if(f.preventDefault(),e>=0&&t[e]?.is_tappable)o(t[e]);else if(r.current){let{rawQuery:a,completedParams:l}=ee(i,s),T={query:i.trim(),raw_query:a,completed_params:l};r.current(T)}break}case"Tab":{if(e>=0&&t[e]?.is_tappable)f.preventDefault(),o(t[e]);else if(h){let a=t.find(l=>l.is_tappable);a&&(f.preventDefault(),o(a))}else if(!i&&m){f.preventDefault();let a=u.find(l=>l.type==="placeholder");a?(x(c),b.current=c.length,v(l=>[...l,{id:crypto.randomUUID(),placeholder:"",type:a.type,text:c,kind:null,suggestionType:a.type,suggestionPlaceholder:a.text,options:a.options??[]}]),w(l=>l.filter(T=>T!==a))):(x(c),b.current=c.length)}break}case"Escape":n(-1);break}},[y,e,_,s,t,b,A,m,h,r,c,o,n,g,v,w,x,u,i]),getTappableIndices:A}}var ue=require("react");function $e({completedParams:e,suggestions:n,setCompletedParams:t,setSuggestions:o,setActiveDropdownIndex:r,filterBaseRef:i,pillTappedRef:s}){let h=(0,ue.useCallback)(u=>{let y=n.filter(x=>x.type!=="placeholder");if(u<0||u>=y.length)return;let g=y[u],b=y.filter((x,v)=>v!==u),_=n.filter(x=>x.type==="placeholder");o([..._,g,...b]),s.current=!0,r(-1)},[n,o,r,s]),m=(0,ue.useCallback)(()=>{if(e.length===0)return;let u=e[e.length-1],y={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};t(g=>g.slice(0,-1)),o(g=>[y,...g]),r(-1)},[e,t,o,r]),c=(0,ue.useCallback)(u=>{let y={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};return{apply:g=>{g(b=>{let _=0;for(let x of e){let v=b.indexOf(x.text,_);if(v!==-1){if(x.id===u.id){let w=b.slice(0,v),A=b.slice(v+u.text.length),I=(w+A).replace(/ {2,}/g," ");return i.current=Math.min(i.current,I.length),I}_=v+x.text.length}}return b}),t(b=>b.filter(_=>_.id!==u.id)),o(b=>[y,...b]),r(-1),s.current=!0}}},[e,t,o,r,i,s]);return{setActivePill:h,removeLastParam:m,reEditParam:c}}var gt=0;function ft(){let e=(0,p.useRef)(null);return e.current===null&&(e.current=`:ac-${++gt}:`),e.current}function pe({onSubmit:e,onError:n,optionOverrides:t,maskCompletedText:o,placeholder:r,apiConfig:i,columns:s=2,eagerSuggestions:h=!0,value:m,completedParams:c,onChange:u,onParamsChange:y}){let g=m!==void 0,b=c!==void 0,[_,x]=(0,p.useState)(""),[v,w]=(0,p.useState)([]),[A,I]=(0,p.useState)([]),[f,d]=(0,p.useState)(-1),a=g?m:_,l=b?c:v,T=(0,p.useRef)(e);T.current=e;let k=(0,p.useRef)(u);k.current=u;let $=(0,p.useRef)(y);$.current=y;let L=(0,p.useRef)(m);L.current=m;let j=(0,p.useRef)(c);j.current=c;let U=(0,p.useCallback)(S=>{if(typeof S=="function")if(g){let C=S(L.current??"");k.current?.(C)}else x(C=>{let H=S(C);return k.current?.(H),H});else g||x(S),k.current?.(S)},[g]),M=(0,p.useCallback)(S=>{if(typeof S=="function")if(b){let C=S(j.current??[]);$.current?.(C)}else w(C=>{let H=S(C);return $.current?.(H),H});else b||w(S),$.current?.(S)},[b]),D=(0,p.useRef)(n);D.current=n;let W=(0,p.useRef)(t);W.current=t;let q=(0,p.useRef)(o);q.current=o;let N=(0,p.useRef)(i);N.current=i;let B=(0,p.useRef)(a);B.current=a;let V=(0,p.useRef)(A);V.current=A;let z=(0,p.useRef)(0),te=(0,p.useRef)(!1),ie=(0,p.useRef)(!1),Ie=(0,p.useRef)(!1),de=ft(),{doFetch:me,isLoading:we,error:He,isReady:We,lastRawQueryRef:ge}=qe({textRef:B,suggestionsRef:V,filterBaseRef:z,filterInProgressRef:te,maskCompletedTextRef:q,apiConfigRef:N,optionOverridesRef:W,onErrorRef:D,setCompletedParams:M,setSuggestions:I,setActiveDropdownIndex:d});Ne({text:a,completedParams:l,doFetch:me,filterBaseRef:z,filterInProgressRef:te,skipNextFetchRef:Ie,suggestionsRef:V,lastRawQueryRef:ge});let Ve=(0,p.useMemo)(()=>De(a,l),[a,l]);z.current=Math.min(z.current,a.length);let fe=Y(a,z.current,te.current),be=(0,p.useMemo)(()=>A.filter(C=>C.type==="placeholder").map(C=>C.text).join(" ")||r||"",[A,r]),oe=(0,p.useMemo)(()=>A.filter(S=>S.type!=="placeholder"),[A]),P=oe[0],Oe=P?t?.[P.type]:void 0,Re=P?Oe?Oe(fe.trim()):P.options??[]:[],he=(0,p.useMemo)(()=>ce(Re,fe),[Re,fe]),ke=be.length>0,ye=!we&&he.length>0&&(!!a||ie.current||!ke),Me=(0,p.useCallback)(S=>{if(!P)return;let C={id:crypto.randomUUID(),placeholder:"",type:P.type,text:S.text,kind:S.kind,suggestionType:P.type,suggestionPlaceholder:P.text,options:P.options??[],metadata:S.metadata},H=z.current,K=B.current.slice(0,H);if(K.length>0&&!K.endsWith(" ")){let O=K.split(/\s+/).pop()??"";O&&S.text.toLowerCase().startsWith(O.toLowerCase())&&(K=K.slice(0,K.length-O.length))}let Se=K.length>0&&K[K.length-1]!==" ",Z=K+(Se?" ":"")+S.text+" ";U(Z),z.current=Z.length,M(O=>[...O,C]),ie.current=!1,d(-1);let G=oe.length-1;h&&G>0?(I(O=>O.filter(X=>X!==P)),Ie.current=!0):I(O=>O.filter(X=>X.type==="placeholder"))},[P,oe,h,U,M]),Ge=(0,p.useCallback)(S=>{let C=S.target.value,K=C.length>0&&!S.nativeEvent?.isComposing&&C[0]!==C[0].toUpperCase()?C[0].toUpperCase()+C.slice(1):C;U(K),ie.current=!1,d(-1);let{valid:Se,invalid:Z}=Ke(K,l);if(Z.length>0){M(()=>Se);for(let G of Z)I(O=>[{type:G.suggestionType,text:G.suggestionPlaceholder,required:!0,options:G.options},...O])}if(P&&Z.length===0){let G=Y(K,z.current,te.current),O=re(P.options,G);O&&(M(X=>[...X,{id:crypto.randomUUID(),placeholder:"",type:P.type,text:O.text,kind:O.kind,suggestionType:P.type,suggestionPlaceholder:P.text,options:P.options??[],metadata:O.metadata}]),I(X=>X.filter(et=>et!==P)))}},[l,P,U,M]),ne=$e({completedParams:l,suggestions:A,setCompletedParams:M,setSuggestions:I,setActiveDropdownIndex:d,filterBaseRef:z,pillTappedRef:ie}),Xe=(0,p.useCallback)(S=>{ne.reEditParam(S).apply(U)},[ne,U]),{handleKeyDown:Ze}=Qe({activeDropdownIndex:f,setActiveDropdownIndex:d,filteredOptions:he,selectOption:Me,onSubmitRef:T,text:a,completedParams:l,isDropdownOpen:ye,hasPlaceholder:ke,placeholderText:be,suggestions:A,actionableSuggestions:oe,setActivePill:ne.setActivePill,filterBaseRef:z,columns:s,setText:U,setCompletedParams:M,setSuggestions:I}),Je=(0,p.useCallback)(()=>{U(""),M(()=>[]),I([]),d(-1),z.current=0,te.current=!1,ge.current="",me("",[])},[me,U,M,ge]),Ye=f>=0?`${de}-option-${f}`:void 0;return{completedParams:l,suggestionPills:oe,setActivePill:ne.setActivePill,removeLastParam:ne.removeLastParam,reEditParam:Xe,segments:Ve,suggestions:A,activeIndex:f,isReady:We,isLoading:we,error:He,inputProps:{value:a,placeholder:be||void 0,onChange:Ge,onKeyDown:Ze,role:"combobox","aria-expanded":ye,"aria-activedescendant":Ye,"aria-autocomplete":"list","aria-controls":de},reset:Je,dropdownProps:{suggestions:P?[{...P,options:he}]:[],activeIndex:f,onSelect:Me,onHighlight:d,isOpen:ye,id:de}}}var E=require("react/jsx-runtime"),Be=(0,F.forwardRef)(function({onSubmit:n,onError:t,optionOverrides:o,maskCompletedText:r,placeholder:i,className:s,apiConfig:h,columns:m,eagerSuggestions:c,value:u,completedParams:y,onChange:g,onParamsChange:b},_){let x=(0,F.useRef)(null),v=(0,F.useRef)(()=>{});(0,F.useEffect)(()=>{x.current?.focus()},[]);let{completedParams:w,suggestionPills:A,setActivePill:I,segments:f,inputProps:d,dropdownProps:a,reset:l}=pe({onSubmit:D=>v.current(D),onError:t,optionOverrides:o,maskCompletedText:r,placeholder:i,apiConfig:h,columns:m,eagerSuggestions:c,value:u,completedParams:y,onChange:g,onParamsChange:b});(0,F.useImperativeHandle)(_,()=>({focus:()=>x.current?.focus(),reset:l}),[l]);let T=()=>{x.current?.focus()},k=!!d.value||w.length>0,$=(0,F.useCallback)(()=>{if(!k)return;let{rawQuery:D,completedParams:W}=ee(d.value,w);n({query:d.value.trim(),raw_query:D,completed_params:W}),l()},[k,d.value,w,n,l]);v.current=$;let{onChange:L,placeholder:j,...U}=d,M=!d.value;return(0,E.jsxs)("div",{className:`${Q.container} ${s??""}`,children:[(0,E.jsx)(se,{...a}),(0,E.jsxs)("div",{className:Q.inputWrapper,onClick:T,children:[(0,E.jsxs)("div",{className:Q.editorArea,children:[(0,E.jsxs)("div",{className:Q.sizerContent,"aria-hidden":"true",children:[M&&j?(0,E.jsxs)("span",{className:Q.placeholderText,children:[j," "]}):(0,E.jsxs)("span",{className:Q.sizerText,children:[f.map((D,W)=>(0,E.jsx)("span",{children:D.value},`${W}-${D.type}`)),f.length===0&&"\xA0"]})," ",(0,E.jsx)(Ue,{pills:A,activePillIndex:0,onSelectPill:I})]}),(0,E.jsx)("textarea",{ref:x,className:Q.textarea,rows:1,onChange:L,...U})]}),(0,E.jsx)("button",{type:"button",className:Q.submitButton,disabled:!k,onClick:D=>{D.stopPropagation(),$()},"aria-label":"Submit",children:(0,E.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",role:"img","aria-label":"Submit",children:(0,E.jsx)("path",{d:"M9 14V4M9 4L4 9M9 4L14 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})});0&&(module.exports={AIAutocomplete,AIAutocompleteDropdown,useAIAutocomplete});
215
216
  //# sourceMappingURL=index.js.map
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","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionItem.tsx","../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 } 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 eagerSuggestions,\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\n useEffect(() => {\n textareaRef.current?.focus();\n }, []);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\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 eagerSuggestions,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\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 className={styles.sizerText}>\n {segments.map((seg, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\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}\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: 21px;\n line-height: 38px;\n}\n\n.AIAutocomplete-module_sizerText_iZIMK {\n color: transparent;\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: 21px;\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 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\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\"};","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, #00002d);\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: 12px 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\"};","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 display: flex;\n align-items: center;\n font-family: \"IBM Plex Sans\", sans-serif;\n font-size: 21px;\n line-height: 30px;\n color: var(--ac-color-text-muted, #c1c4cb);\n white-space: nowrap;\n opacity: 0.35;\n animation: SuggestionItem-module_fadeIn_I8u35 400ms 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_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: 13px;\n margin-left: 6px;\n opacity: 0.5;\n}\n`;\n document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\"};","import 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 className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\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={() => option.is_tappable && onSelect(option)}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n onSelect(option);\n }\n }}\n onMouseEnter={onHighlight}\n >\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </div>\n );\n}\n","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: 21px;\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 eagerSuggestions = true,\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\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 completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: option.text,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n\n const base = filterBaseRef.current;\n let prefix = textRef.current.slice(0, base);\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 setText(newText);\n filterBaseRef.current = newText.length;\n setCompletedParams((prev) => [...prev, completed]);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n const remainingActionable = actionableSuggestions.length - 1;\n if (eagerSuggestions && remainingActionable > 0) {\n // Keep cached suggestions visible and skip the fetch\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n skipNextFetchRef.current = true;\n } else {\n // Clear all suggestions and let the debounced fetch bring fresh ones\n setSuggestions((prev) => prev.filter((s) => s.type === \"placeholder\"));\n }\n },\n [activeSuggestion, actionableSuggestions, eagerSuggestions, 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 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 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 const attemptFetch = (minDiff: number): boolean => {\n if (skipNextFetchRef.current) {\n skipNextFetchRef.current = false;\n return false;\n }\n\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 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 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 e.preventDefault();\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 e.preventDefault();\n if (tappableIndices.length === 0) return;\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 // No dropdown option selected — cycle to the next suggestion pill\n if (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 selectOption(filteredOptions[activeDropdownIndex]);\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 selectOption(filteredOptions[activeDropdownIndex]);\n } else if (isDropdownOpen) {\n const firstTappable = filteredOptions.find((o) => o.is_tappable);\n if (firstTappable) {\n e.preventDefault();\n selectOption(firstTappable);\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 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","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","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","filterBaseRef","columns","setText","setCompletedParams","setSuggestions","getTappableIndices","tappable","o","i","buckets","e","tappableIndices","currentPos","nextPos","prevPos","rightNeighbor","leftNeighbor","rawQuery","finalParams","buildQuery","result","firstTappable","placeholderSuggestion","s","prev","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","eagerSuggestions","controlledValue","controlledParams","onChangeProp","onParamsChange","isTextControlled","isParamsControlled","internalText","setInternalText","internalCompletedParams","setInternalCompletedParams","suggestions","setSuggestions","activeDropdownIndex","setActiveDropdownIndex","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","completed","base","prefix","lastWord","needsSpace","newText","remainingActionable","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","eagerSuggestions","value","controlledParams","onChangeProp","onParamsChange","ref","textareaRef","handleSubmitRef","completedParams","suggestionPills","setActivePill","segments","inputProps","dropdownProps","reset","useAIAutocomplete","result","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","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/SuggestionGrid.module.css.js","css-module:/Users/saharshv/MagicX/ai-autocomplete-react/src/components/SuggestionItem.module.css.js","../src/components/SuggestionItem.tsx","../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 } 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 eagerSuggestions,\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\n useEffect(() => {\n textareaRef.current?.focus();\n }, []);\n\n const {\n completedParams,\n suggestionPills,\n setActivePill,\n segments,\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 eagerSuggestions,\n value,\n completedParams: controlledParams,\n onChange: onChangeProp,\n onParamsChange,\n });\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 className={styles.sizerText}>\n {segments.map((seg, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: segments are positional and don't reorder\n <span key={`${i}-${seg.type}`}>{seg.value}</span>\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}\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_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 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\",\"placeholderText\":\"AIAutocomplete-module_placeholderText_K3ayy\",\"textarea\":\"AIAutocomplete-module_textarea_eyn6A\",\"submitButton\":\"AIAutocomplete-module_submitButton_sl1Mi\"};","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: 12px 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\"};","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 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 animation: SuggestionItem-module_fadeIn_I8u35 400ms 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_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 document.head.appendChild(s);\n}\nexport default {\"item\":\"SuggestionItem-module_item_d4vpD\",\"fadeIn\":\"SuggestionItem-module_fadeIn_I8u35\",\"tappable\":\"SuggestionItem-module_tappable_70KcX\",\"nonTappable\":\"SuggestionItem-module_nonTappable_xSZM-\",\"highlighted\":\"SuggestionItem-module_highlighted_Hb0SU\",\"tag\":\"SuggestionItem-module_tag_e3Fwe\"};","import 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 className = [\n styles.item,\n isHighlighted ? styles.highlighted : \"\",\n option.is_tappable ? styles.tappable : styles.nonTappable,\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={() => option.is_tappable && onSelect(option)}\n onKeyDown={(e) => {\n if (option.is_tappable && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n onSelect(option);\n }\n }}\n onMouseEnter={onHighlight}\n >\n {option.icon ? `${option.icon} ${option.text}` : option.text}\n {option.tag && <span className={styles.tag}>{option.tag}</span>}\n </div>\n );\n}\n","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 eagerSuggestions = true,\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\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 completed: CompletedParamState = {\n id: crypto.randomUUID(),\n placeholder: \"\",\n type: activeSuggestion.type,\n text: option.text,\n kind: option.kind,\n suggestionType: activeSuggestion.type,\n suggestionPlaceholder: activeSuggestion.text,\n options: activeSuggestion.options ?? [],\n metadata: option.metadata,\n };\n\n const base = filterBaseRef.current;\n let prefix = textRef.current.slice(0, base);\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 setText(newText);\n filterBaseRef.current = newText.length;\n setCompletedParams((prev) => [...prev, completed]);\n pillTappedRef.current = false;\n setActiveDropdownIndex(-1);\n const remainingActionable = actionableSuggestions.length - 1;\n if (eagerSuggestions && remainingActionable > 0) {\n // Keep cached suggestions visible and skip the fetch\n setSuggestions((prev) => prev.filter((s) => s !== activeSuggestion));\n skipNextFetchRef.current = true;\n } else {\n // Clear all suggestions and let the debounced fetch bring fresh ones\n setSuggestions((prev) => prev.filter((s) => s.type === \"placeholder\"));\n }\n },\n [activeSuggestion, actionableSuggestions, eagerSuggestions, 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 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 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 const attemptFetch = (minDiff: number): boolean => {\n if (skipNextFetchRef.current) {\n skipNextFetchRef.current = false;\n return false;\n }\n\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 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 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 e.preventDefault();\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 e.preventDefault();\n if (tappableIndices.length === 0) return;\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 selectOption(filteredOptions[activeDropdownIndex]);\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 selectOption(filteredOptions[activeDropdownIndex]);\n } else if (isDropdownOpen) {\n const firstTappable = filteredOptions.find((o) => o.is_tappable);\n if (firstTappable) {\n e.preventDefault();\n selectOption(firstTappable);\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 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","s","SuggestionItem_module_css_default","import_jsx_runtime","SuggestionItem","option","isHighlighted","onSelect","onHighlight","id","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","filterBaseRef","columns","setText","setCompletedParams","setSuggestions","getTappableIndices","tappable","o","i","buckets","e","tappableIndices","currentPos","nextPos","prevPos","target","rightNeighbor","leftNeighbor","rawQuery","finalParams","buildQuery","result","firstTappable","placeholderSuggestion","s","prev","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","eagerSuggestions","controlledValue","controlledParams","onChangeProp","onParamsChange","isTextControlled","isParamsControlled","internalText","setInternalText","internalCompletedParams","setInternalCompletedParams","suggestions","setSuggestions","activeDropdownIndex","setActiveDropdownIndex","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","completed","base","prefix","lastWord","needsSpace","newText","remainingActionable","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","eagerSuggestions","value","controlledParams","onChangeProp","onParamsChange","ref","textareaRef","handleSubmitRef","completedParams","suggestionPills","setActivePill","segments","inputProps","dropdownProps","reset","useAIAutocomplete","result","handleContainerClick","canSubmit","handleSubmit","rawQuery","finalParams","buildQuery","onChange","inputPlaceholder","restProps","isEmpty","AIAutocomplete_module_css_default","AIAutocompleteDropdown","seg","i","PillList","e"]}