@magicx-eng/ai-autocomplete-react 0.1.15 → 0.1.17

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/README.md CHANGED
@@ -12,7 +12,8 @@ A React/TypeScript SDK that provides a guided AI-powered autocomplete experience
12
12
  - **Controlled & uncontrolled** — works out of the box or integrates with external state
13
13
  - **Ref forwarding** — imperative `focus()` and `reset()` via ref
14
14
  - **Accessible** — ARIA combobox pattern with `role="listbox"`, `aria-activedescendant`
15
- - **Lightweight** — zero dependencies beyond React
15
+ - **Animations** — option selection streak animation, text shimmer on newly added params, typewriter reveal effect
16
+ - **Lightweight** — zero dependencies beyond React, styles auto-injected at runtime
16
17
  - **TypeScript first** — full type definitions shipped with the package
17
18
 
18
19
  ## Installation
@@ -132,7 +133,7 @@ The full component. Owns the input, pills, dropdown, and keyboard navigation.
132
133
  | `placeholder?` | `string` | — | Fallback placeholder when the server doesn't return one. |
133
134
  | `className?` | `string` | — | CSS class applied to the container. |
134
135
  | `columns?` | `number` | `2` | Number of columns in the dropdown grid. |
135
- | `eagerSuggestions?` | `boolean` | `true` | When `true`, show cached next suggestions immediately after selecting an option. When `false`, clear the dropdown and wait for the server response before showing the next suggestions. |
136
+ | `typewriterEffect?` | `boolean` | `false` | When `true`, reveal selected option text letter by letter with a shimmer. When `false` (default), show all at once with a shimmer sweep. |
136
137
  | `value?` | `string` | — | Controlled text value. |
137
138
  | `completedParams?` | `CompletedParamState[]` | — | Controlled completed params. |
138
139
  | `onChange?` | `(value: string) => void` | — | Called when text changes (controlled mode). |
@@ -143,9 +144,10 @@ The full component. Owns the input, pills, dropdown, and keyboard navigation.
143
144
 
144
145
  | Field | Type | Description |
145
146
  |---|---|---|
146
- | `endpoint?` | `string` | Full URL for the suggest endpoint (e.g. `"https://api.example.com/ac/suggest"`). Falls back to `MAGICX_API_ENDPOINT` env var, then `"/ac/suggest"`. |
147
- | `apiKey?` | `string` | API key for Authorization header. Falls back to `MAGICX_AI_AUTOCOMPLETE_API_KEY` env var. |
147
+ | `endpoint?` | `string` | Full URL for the suggest endpoint (e.g. `"https://api.example.com/ac/suggest"`). Default: `"/ac/suggest"`. |
148
+ | `apiKey?` | `string` | API key for Authorization header. A dev warning is logged if not provided. |
148
149
  | `authScheme?` | `"Bearer" \| "Basic"` | Auth header scheme. Default: `"Bearer"`. |
150
+ | `appIdentifier?` | `string` | Value for the `X-App-Identifier` header. Only sent when provided. |
149
151
  | `headers?` | `Record<string, string>` | Additional headers merged into every request. |
150
152
 
151
153
  ### `AutocompleteResult`
@@ -173,9 +175,10 @@ Accepts the same props as `<AIAutocomplete />` (except `className` and `ref`), w
173
175
  | `completedParams` | `CompletedParamState[]` | All parameters the user has filled so far. Each entry contains the selected option's `text`, `kind`, `type`, and `metadata`, plus client-side fields like `id` (stable UUID), `options` (cached for re-editing), `suggestionType`, and `suggestionPlaceholder`. Use these to render completed values (e.g. bold text) and to build the final query on submit. |
174
176
  | `suggestionPills` | `Suggestion[]` | Unfilled suggestions that should be rendered as pills (inline chips). Excludes placeholder-type suggestions. The first item is the "active" pill whose options appear in the dropdown. Tapping a pill reorders it to the front via `setActivePill`. |
175
177
  | `segments` | `Segment[]` | The input text split into typed segments for overlay rendering. Each segment is either `{ type: "text", value: string }` for plain text, or `{ type: "completed", value: string, param: CompletedParamState }` for a completed parameter. Use these to render a styled overlay on top of the textarea — e.g. showing completed params in bold while keeping the textarea's actual text transparent. |
178
+ | `newParamId` | `string \| null` | The `id` of the most recently added completed param, or `null`. Use this to apply shimmer animations to the newly added text segment. Cleared automatically after the animation completes. |
176
179
  | `suggestions` | `Suggestion[]` | All suggestions from the server, including placeholder-type suggestions. Most consumers should use `suggestionPills` and `dropdownProps` instead — this is exposed for advanced use cases like custom pill or dropdown rendering. |
177
180
  | `activeIndex` | `number` | Index of the currently keyboard-highlighted option in the dropdown. `-1` when no option is highlighted. Automatically managed by arrow keys. |
178
- | `isLoading` | `boolean` | `true` while a fetch is in flight and no cached suggestions are visible. With `eagerSuggestions={true}` (default), this only triggers on initial mount or after `reset()` the dropdown stays open during background re-fetches. With `eagerSuggestions={false}`, it also becomes `true` after each option selection, closing the dropdown until fresh data arrives. |
181
+ | `isLoading` | `boolean` | `true` while a fetch is in flight and no cached suggestions are visible. Only triggers on initial mount, after `reset()`, or when all cached suggestions are consumed. The dropdown stays open with cached data during background re-fetches. |
179
182
  | `isReady` | `boolean` | `true` when the server's `is_ready` flag indicates the query is complete and ready for execution. Use this to show a visual indicator or enable a submit button. |
180
183
  | `error` | `Error \| null` | The most recent fetch error, or `null` if the last fetch succeeded. Cleared on every new fetch attempt. |
181
184
 
@@ -186,6 +189,7 @@ Accepts the same props as `<AIAutocomplete />` (except `className` and `ref`), w
186
189
  | `setActivePill` | `(index: number) => void` | Reorder pills by moving the pill at `index` to the front, making it the active pill whose options show in the dropdown. |
187
190
  | `removeLastParam` | `() => void` | Remove the most recently completed parameter, restore it as a pill, and re-show its options in the dropdown. Useful for handling backspace on an empty input. |
188
191
  | `reEditParam` | `(param: CompletedParamState) => void` | Remove a specific completed parameter from the input text, restore it as a pill with its cached options, and open the dropdown. Use this when the user taps on a bold (completed) param to change their selection. |
192
+ | `clearNewParamId` | `() => void` | Manually clear `newParamId`. Called automatically after the shimmer/typewriter animation completes. |
189
193
  | `reset` | `() => void` | Clear all text, completed params, and suggestions, then re-fetch initial suggestions from the server. Returns the component to its mount state. |
190
194
 
191
195
  **Spread Props**
@@ -218,7 +222,7 @@ Represents an unfilled parameter slot. Rendered as a pill in Tier 1, or availabl
218
222
  | `type` | `string` | Suggestion type identifier (e.g. `"task"`, `"goal"`, `"contact"`). Used as the key for `optionOverrides`. |
219
223
  | `text` | `string` | Display text for the pill (e.g. `"type"`, `"goal"`). |
220
224
  | `required` | `boolean` | Whether this suggestion must be filled before submission. |
221
- | `options` | `SuggestionOption[]` | Available options the user can select from. |
225
+ | `options?` | `SuggestionOption[]` | Available options the user can select from. May be `undefined` if the server omits it. |
222
226
 
223
227
  ### `SuggestionOption`
224
228
 
@@ -235,7 +239,7 @@ An individual option within a suggestion's dropdown.
235
239
 
236
240
  ## CSS Customization
237
241
 
238
- The component uses CSS Modules with customizable CSS variables. Override them on a parent element:
242
+ Styles are auto-injected at runtime — no CSS import needed. The component uses CSS variables for theming. Override them on a parent element:
239
243
 
240
244
  ```css
241
245
  .my-autocomplete {
@@ -252,11 +256,13 @@ The component uses CSS Modules with customizable CSS variables. Override them on
252
256
 
253
257
  | Key | Behavior |
254
258
  |---|---|
255
- | **Arrow Down/Up** | Navigate options. |
256
- | **Arrow Left/Right** | Jump between columns on the same row. |
259
+ | **Arrow Down** | Open dropdown (if closed and cursor at end) and select first option, or navigate to next option. |
260
+ | **Arrow Up** | Navigate to previous option. Deselects if on the first row. Does nothing if no option is selected. |
261
+ | **Arrow Right** | Jump to next column when an option is highlighted. Cycles to the next suggestion pill when cursor is at the end and no option is selected. |
262
+ | **Arrow Left** | Jump to previous column when an option is highlighted. |
257
263
  | **Tab** | Select the first tappable option (or highlighted one). Accepts placeholder when input is empty. |
258
264
  | **Enter** | Select highlighted option if one is highlighted. Otherwise submits the query. |
259
- | **Escape** | Clear the highlighted option. |
265
+ | **Escape** | Deselect the highlighted option. |
260
266
 
261
267
  ## Option Overrides
262
268
 
package/dist/index.d.mts CHANGED
@@ -60,7 +60,7 @@ interface AIAutocompleteProps {
60
60
  className?: string;
61
61
  apiConfig?: APIConfig;
62
62
  columns?: number;
63
- /** When true (default), reveal selected option text letter by letter. */
63
+ /** When true, reveal selected option text letter by letter. Default: false. */
64
64
  typewriterEffect?: boolean;
65
65
  value?: string;
66
66
  completedParams?: CompletedParamState[];
@@ -80,7 +80,7 @@ interface UseAIAutocompleteOptions {
80
80
  placeholder?: string;
81
81
  apiConfig?: APIConfig;
82
82
  columns?: number;
83
- /** When true (default), reveal selected option text letter by letter. */
83
+ /** When true, reveal selected option text letter by letter. Default: false. */
84
84
  typewriterEffect?: boolean;
85
85
  value?: string;
86
86
  completedParams?: CompletedParamState[];
package/dist/index.d.ts CHANGED
@@ -60,7 +60,7 @@ interface AIAutocompleteProps {
60
60
  className?: string;
61
61
  apiConfig?: APIConfig;
62
62
  columns?: number;
63
- /** When true (default), reveal selected option text letter by letter. */
63
+ /** When true, reveal selected option text letter by letter. Default: false. */
64
64
  typewriterEffect?: boolean;
65
65
  value?: string;
66
66
  completedParams?: CompletedParamState[];
@@ -80,7 +80,7 @@ interface UseAIAutocompleteOptions {
80
80
  placeholder?: string;
81
81
  apiConfig?: APIConfig;
82
82
  columns?: number;
83
- /** When true (default), reveal selected option text letter by letter. */
83
+ /** When true, reveal selected option text letter by letter. Default: false. */
84
84
  typewriterEffect?: boolean;
85
85
  value?: string;
86
86
  completedParams?: CompletedParamState[];
package/dist/index.js CHANGED
@@ -529,5 +529,5 @@
529
529
  opacity: 0;
530
530
  }
531
531
  }
532
- `,document.head.appendChild(e)}var he={list:"PillList-module_list_qvLqO",pill:"PillList-module_pill_osSyz",fadeIn:"PillList-module_fadeIn_Aezob",active:"PillList-module_active_Oll--"};var Oe=require("react/jsx-runtime");function dt(e){return e===0?.4:e===1?.3:.15}function He({pills:e,activePillIndex:r,onSelectPill:t}){return(0,Oe.jsx)("span",{className:he.list,children:e.map((o,n)=>(0,Oe.jsx)("button",{type:"button",className:`${he.pill} ${n===r?he.active:""}`,style:{opacity:dt(n)},onClick:()=>t(n),children:o.text},`${o.type}-${o.text}`))})}var p=require("react");function ae(e,r,t){let o=e.slice(r);if(t||r===0||e[r-1]===" ")return o;let n=o.indexOf(" ");return n===-1?"":o.slice(n+1)}function xe(e,r){if(!e)return[];let t=r.trimStart();if(!t)return e;let o=t.toLowerCase();return e.filter(n=>!n.is_tappable||n.text.toLowerCase().includes(o))}function me(e,r){if(!e)return null;let t=r.trim();if(!t)return null;let o=t.toLowerCase();return e.find(n=>n.is_tappable&&n.text.toLowerCase()===o)??null}function Ne(e,r){let t=[],o=0;for(let a of r){let l=e.indexOf(a.text,o);l!==-1&&(l>o&&t.push({type:"text",value:e.slice(o,l)}),t.push({type:"completed",value:a.text,param:a}),o=l+a.text.length)}let n=e.slice(o);return n&&t.push({type:"text",value:n}),t}function Ve(e,r){let t=[],o=[],n=0;for(let a of r){let l=e.indexOf(a.text,n);l===-1?o.push(a):(t.push(a),n=l+a.text.length)}return{valid:t,invalid:o}}var U=require("react");var mt="0.1.15",je=!1;function gt(){return crypto.randomUUID()}function ft(e,r){return{placeholder:e.placeholder,type:e.type,...r&&{text:e.text},kind:e.kind}}async function Be(e,r,t){let o=t?.apiConfig,n=o?.apiKey??"";!n&&!je&&(je=!0,console.warn("[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header."));let a=o?.authScheme??"Bearer",l=!t?.maskCompletedText,m=r.find(f=>f.type==="contact"&&f.metadata?.contact_account_count)?.metadata?.contact_account_count,d=typeof m=="number"?m:void 0,c={data:{raw_query:e,completed_params:r.map(f=>ft(f,l)),...d!=null&&{contact_account_count:d}},meta:{request_id:gt(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:mt}},u={"Content-Type":"application/json",...o?.appIdentifier&&{"X-App-Identifier":o.appIdentifier},...o?.headers};n&&(u.Authorization=a==="Basic"?`Basic ${btoa(n)}`:`Bearer ${n}`);let g=await fetch(o?.endpoint??"/ac/suggest",{method:"POST",headers:u,body:JSON.stringify(c),signal:t?.signal});if(!g.ok)throw new Error(`API error: ${g.status} ${g.statusText}`);return g.json()}function se(e,r){let t=e,o={},n=[];for(let a of r){let l=(o[a.type]??0)+1;o[a.type]=l;let d=`{{${a.type.toUpperCase().replace(/\s+/g,"_")}_${l}}}`,c=t.indexOf(a.text);c!==-1&&(t=t.slice(0,c)+d+t.slice(c+a.text.length)),n.push({...a,placeholder:d})}return{rawQuery:t,completedParams:n}}function Ke(e,r){return r?e.map(t=>{let o=r[t.type];if(!o)return t;let n=o("");if(n.length===0)return t;let a=new Set(n.map(m=>m.text)),l=(t.options??[]).filter(m=>!a.has(m.text));return{...t,options:[...n,...l]}}):e}var bt=100,ht=300,xt=2;function qe({textRef:e,suggestionsRef:r,filterBaseRef:t,filterInProgressRef:o,maskCompletedTextRef:n,apiConfigRef:a,optionOverridesRef:l,onErrorRef:m,setCompletedParams:d,setSuggestions:c,setActiveDropdownIndex:u}){let[g,f]=(0,U.useState)(!1),[_,z]=(0,U.useState)(null),[w,b]=(0,U.useState)(!1),S=(0,U.useRef)(0),A=(0,U.useRef)(null),x=(0,U.useRef)(""),v=(0,U.useCallback)(async(B,I)=>{A.current?.abort();let P=new AbortController;A.current=P;let i=++S.current,s=e.current.length;r.current.some(L=>L.type!=="placeholder")||f(!0),z(null);try{let L=await Be(B,I,{maskCompletedText:n.current,signal:P.signal,apiConfig:a.current});if(i!==S.current)return;let O=Ke(L.data.suggestions??[],l.current);b(L.data.is_ready??!1),x.current=B;let ee=L.data.input??[],J=ee[ee.length-1],$=e.current;if(J?.state==="in_progress"){o.current=!0;let K=$.toLowerCase().lastIndexOf(J.text.toLowerCase());K!==-1?t.current=K:t.current=s}else o.current=!1,t.current=s;let V=O.filter(K=>K.type!=="placeholder")[0];if(V){let K=ae($,t.current,o.current),X=me(V.options,K);X&&(d(y=>[...y,{id:crypto.randomUUID(),placeholder:"",type:V.type,text:X.text,kind:X.kind,suggestionType:V.type,suggestionPlaceholder:V.text,options:V.options??[],metadata:X.metadata}]),O=O.filter(y=>y!==V))}c(O),f(!1),u(-1)}catch(L){if(i===S.current){let O=L instanceof Error?L:new Error(String(L));z(O),f(!1),m.current?.(O)}}},[e,r,t,o,n,a,l,m,d,c,u]);return(0,U.useEffect)(()=>(v("",[]),()=>{A.current?.abort()}),[v]),{doFetch:v,isLoading:g,error:_,isReady:w,lastRawQueryRef:x}}function Qe({text:e,completedParams:r,doFetch:t,filterBaseRef:o,filterInProgressRef:n,skipNextFetchRef:a,suggestionsRef:l,lastRawQueryRef:m}){let d=(0,U.useRef)(null),c=(0,U.useRef)(null),u=(0,U.useRef)(!0);(0,U.useEffect)(()=>{if(d.current&&clearTimeout(d.current),c.current&&clearTimeout(c.current),a.current){a.current=!1;return}let g=f=>{if(!e&&r.length===0)return u.current?(t("",[]),!0):(u.current=!0,!1);let _=ae(e,o.current,n.current),b=l.current.filter(s=>s.type!=="placeholder")[0],A=(b?xe(b.options,_):[]).filter(s=>s.is_tappable),x=b?me(b.options,_)!==null:!1,v=_.trim().length>0;if(A.length>0&&!x&&v)return!1;let{rawQuery:B,completedParams:I}=se(e,r),P=B.length<m.current.length,i=Math.abs(B.length-m.current.length);return P||i>=f?(t(B,I),!0):!1};return d.current=setTimeout(()=>{g(xt)&&c.current&&clearTimeout(c.current)},bt),c.current=setTimeout(()=>g(1),ht),()=>{d.current&&clearTimeout(d.current),c.current&&clearTimeout(c.current)}},[e,r,t,o,n,a,l,m])}var Te=require("react");function Ge({activeDropdownIndex:e,setActiveDropdownIndex:r,filteredOptions:t,selectOption:o,onSubmitRef:n,text:a,completedParams:l,isDropdownOpen:m,hasPlaceholder:d,placeholderText:c,suggestions:u,actionableSuggestions:g,setActivePill:f,listboxId:_,pillTappedRef:z,filterBaseRef:w,columns:b,setText:S,setCompletedParams:A,setSuggestions:x}){let v=(0,Te.useCallback)(()=>{let I=t.map((i,s)=>i.is_tappable?s:-1).filter(i=>i!==-1),P=Array.from({length:b},()=>[]);for(let i of I)P[i%b].push(i);return P.flat()},[t,b]);return{handleKeyDown:(0,Te.useCallback)(I=>{let P=v();switch(I.key){case"ArrowDown":{let i=I.target;if(!(i.selectionStart!=null&&i.selectionStart===i.value.length)&&e<0)break;if(I.preventDefault(),!m&&g.length>0){z.current=!0;let O=P[0];r(O??0);break}if(P.length===0)return;let C=P.indexOf(e),L=C<P.length-1?C+1:0;r(P[L]);break}case"ArrowUp":{if(P.length===0||e<0)break;if(I.preventDefault(),e<b){r(-1);break}let s=P.indexOf(e),C=s>0?s-1:P.length-1;r(P[C]);break}case"ArrowRight":{if(e<0){let s=I.target;s.selectionStart!=null&&s.selectionStart===s.value.length&&g.length>1&&(I.preventDefault(),f(1));break}if(e%b<b-1){let s=e+1;s<t.length&&t[s]?.is_tappable&&(I.preventDefault(),r(s))}break}case"ArrowLeft":{if(e<0)break;if(e%b>0){let i=e-1;i>=0&&t[i]?.is_tappable&&(I.preventDefault(),r(i))}break}case"Enter":{if(I.preventDefault(),e>=0&&t[e]?.is_tappable){let i=document.getElementById(`${_}-option-${e}`);i?i.click():o(t[e])}else if(n.current){let{rawQuery:i,completedParams:s}=se(a,l),C={query:a.trim(),raw_query:i,completed_params:s};n.current(C)}break}case"Tab":{if(e>=0&&t[e]?.is_tappable){I.preventDefault();let i=document.getElementById(`${_}-option-${e}`);i?i.click():o(t[e])}else if(m){let i=t.findIndex(s=>s.is_tappable);if(i>=0){I.preventDefault();let s=document.getElementById(`${_}-option-${i}`);s?s.click():o(t[i])}}else if(!a&&d){I.preventDefault();let i=u.find(s=>s.type==="placeholder");i?(S(c),w.current=c.length,A(s=>[...s,{id:crypto.randomUUID(),placeholder:"",type:i.type,text:c,kind:null,suggestionType:i.type,suggestionPlaceholder:i.text,options:i.options??[]}]),x(s=>s.filter(C=>C!==i))):(S(c),w.current=c.length)}break}case"Escape":r(-1);break}},[g,e,b,l,t,w,v,d,_,z,m,n,c,o,r,f,A,x,S,u,a]),getTappableIndices:v}}var ye=require("react");function We({completedParams:e,suggestions:r,setCompletedParams:t,setSuggestions:o,setActiveDropdownIndex:n,filterBaseRef:a,pillTappedRef:l}){let m=(0,ye.useCallback)(u=>{let g=r.filter(w=>w.type!=="placeholder");if(u<0||u>=g.length)return;let f=g[u],_=g.filter((w,b)=>b!==u),z=r.filter(w=>w.type==="placeholder");o([...z,f,..._]),l.current=!0,n(-1)},[r,o,n,l]),d=(0,ye.useCallback)(()=>{if(e.length===0)return;let u=e[e.length-1],g={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};t(f=>f.slice(0,-1)),o(f=>[g,...f]),n(-1)},[e,t,o,n]),c=(0,ye.useCallback)(u=>{let g={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};return{apply:f=>{f(_=>{let z=0;for(let w of e){let b=_.indexOf(w.text,z);if(b!==-1){if(w.id===u.id){let S=_.slice(0,b),A=_.slice(b+u.text.length),x=(S+A).replace(/ {2,}/g," ");return a.current=Math.min(a.current,x.length),x}z=b+w.text.length}}return _}),t(_=>_.filter(z=>z.id!==u.id)),o(_=>[g,..._]),n(-1),l.current=!0}}},[e,t,o,n,a,l]);return{setActivePill:m,removeLastParam:d,reEditParam:c}}var yt=0;function _t(){let e=(0,p.useRef)(null);return e.current===null&&(e.current=`:ac-${++yt}:`),e.current}function _e({onSubmit:e,onError:r,optionOverrides:t,maskCompletedText:o,placeholder:n,apiConfig:a,columns:l=2,value:m,completedParams:d,onChange:c,onParamsChange:u}){let g=m!==void 0,f=d!==void 0,[_,z]=(0,p.useState)(""),[w,b]=(0,p.useState)([]),[S,A]=(0,p.useState)([]),[x,v]=(0,p.useState)(-1),[B,I]=(0,p.useState)(null),P=(0,p.useCallback)(()=>I(null),[]),i=g?m:_,s=f?d:w,C=(0,p.useRef)(e);C.current=e;let L=(0,p.useRef)(c);L.current=c;let O=(0,p.useRef)(u);O.current=u;let ee=(0,p.useRef)(m);ee.current=m;let J=(0,p.useRef)(d);J.current=d;let $=(0,p.useCallback)(h=>{if(typeof h=="function")if(g){let R=h(ee.current??"");L.current?.(R)}else z(R=>{let T=h(R);return L.current?.(T),T});else g||z(h),L.current?.(h)},[g]),N=(0,p.useCallback)(h=>{if(typeof h=="function")if(f){let R=h(J.current??[]);O.current?.(R)}else b(R=>{let T=h(R);return O.current?.(T),T});else f||b(h),O.current?.(h)},[f]),V=(0,p.useRef)(r);V.current=r;let K=(0,p.useRef)(t);K.current=t;let X=(0,p.useRef)(o);X.current=o;let y=(0,p.useRef)(a);y.current=a;let H=(0,p.useRef)(i);H.current=i;let re=(0,p.useRef)(S);re.current=S;let M=(0,p.useRef)(0),q=(0,p.useRef)(!1),j=(0,p.useRef)(!1),le=(0,p.useRef)(!1),Z=_t(),{doFetch:ue,isLoading:Ee,error:Xe,isReady:Ze,lastRawQueryRef:Se}=qe({textRef:H,suggestionsRef:re,filterBaseRef:M,filterInProgressRef:q,maskCompletedTextRef:X,apiConfigRef:y,optionOverridesRef:K,onErrorRef:V,setCompletedParams:N,setSuggestions:A,setActiveDropdownIndex:v});Qe({text:i,completedParams:s,doFetch:ue,filterBaseRef:M,filterInProgressRef:q,skipNextFetchRef:le,suggestionsRef:re,lastRawQueryRef:Se});let Ye=(0,p.useMemo)(()=>Ne(i,s),[i,s]);M.current=Math.min(M.current,i.length);let Ae=ae(i,M.current,q.current),ne=(0,p.useMemo)(()=>S.filter(R=>R.type==="placeholder").map(R=>R.text).join(" ")||n||"",[S,n]),ce=(0,p.useMemo)(()=>S.filter(h=>h.type!=="placeholder"),[S]),k=ce[0],ze=k?t?.[k.type]:void 0,Le=k?ze?ze(Ae.trim()):k.options??[]:[],ve=(0,p.useMemo)(()=>xe(Le,Ae),[Le,Ae]),Me=ne.length>0,Ie=!Ee&&ve.length>0&&(!!i||j.current||!Me),Fe=(0,p.useCallback)(h=>{if(!k)return;let R=M.current,T=H.current.slice(0,R),ie=T.length===0&&H.current.length===0;if(ie&&ne&&(T=ne+" "),T.length>0&&!T.endsWith(" ")){let te=T.split(/\s+/).pop()??"";te&&h.text.toLowerCase().startsWith(te.toLowerCase())&&(T=T.slice(0,T.length-te.length))}let we=T.length>0&&T[T.length-1]!==" ",Y=T+(we?" ":"")+h.text+" ",Q=ie&&Y.length>0?Y[0].toUpperCase()+Y.slice(1):Y,G=Q.toLowerCase().lastIndexOf(h.text.toLowerCase()),de=G>=0?Q.slice(G,G+h.text.length):h.text,ge={id:crypto.randomUUID(),placeholder:"",type:k.type,text:de,kind:h.kind,suggestionType:k.type,suggestionPlaceholder:k.text,options:k.options??[],metadata:h.metadata};$(Q),M.current=Q.length,N(te=>[...te,ge]),I(ge.id),j.current=!1,v(-1),ce.length-1>0&&(le.current=!0),setTimeout(()=>{A(te=>te.filter(it=>it!==k))},400)},[k,ce,ne,$,N]),et=(0,p.useCallback)(h=>{let R=h.target.value,ie=R.length>0&&!h.nativeEvent?.isComposing&&R[0]!==R[0].toUpperCase()?R[0].toUpperCase()+R.slice(1):R;$(ie),j.current=!1,v(-1);let{valid:we,invalid:Y}=Ve(ie,s);if(Y.length>0){N(()=>we);for(let Q of Y)A(G=>[{type:Q.suggestionType,text:Q.suggestionPlaceholder,required:!0,options:Q.options},...G])}if(k&&Y.length===0){let Q=ae(ie,M.current,q.current),G=me(k.options,Q);G&&(N(de=>[...de,{id:crypto.randomUUID(),placeholder:"",type:k.type,text:G.text,kind:G.kind,suggestionType:k.type,suggestionPlaceholder:k.text,options:k.options??[],metadata:G.metadata}]),A(de=>de.filter(ge=>ge!==k)))}},[s,k,$,N]),pe=We({completedParams:s,suggestions:S,setCompletedParams:N,setSuggestions:A,setActiveDropdownIndex:v,filterBaseRef:M,pillTappedRef:j}),tt=(0,p.useCallback)(h=>{pe.reEditParam(h).apply($)},[pe,$]),{handleKeyDown:ot}=Ge({activeDropdownIndex:x,setActiveDropdownIndex:v,filteredOptions:ve,selectOption:Fe,onSubmitRef:C,text:i,completedParams:s,isDropdownOpen:Ie,hasPlaceholder:Me,placeholderText:ne,suggestions:S,actionableSuggestions:ce,setActivePill:pe.setActivePill,listboxId:Z,pillTappedRef:j,filterBaseRef:M,columns:l,setText:$,setCompletedParams:N,setSuggestions:A}),rt=(0,p.useCallback)(()=>{$(""),N(()=>[]),A([]),v(-1),M.current=0,q.current=!1,Se.current="",ue("",[])},[ue,$,N,Se]),nt=x>=0?`${Z}-option-${x}`:void 0;return{completedParams:s,suggestionPills:ce,setActivePill:pe.setActivePill,removeLastParam:pe.removeLastParam,reEditParam:tt,segments:Ye,newParamId:B,clearNewParamId:P,suggestions:S,activeIndex:x,isReady:Ze,isLoading:Ee,error:Xe,inputProps:{value:i,placeholder:ne||void 0,onChange:et,onKeyDown:ot,role:"combobox","aria-expanded":Ie,"aria-activedescendant":nt,"aria-autocomplete":"list","aria-controls":Z},reset:rt,dropdownProps:{suggestions:k?[{...k,options:ve}]:[],activeIndex:x,onSelect:Fe,onHighlight:v,isOpen:Ie,id:Z}}}var E=require("react/jsx-runtime"),Je=(0,D.forwardRef)(function({onSubmit:r,onError:t,optionOverrides:o,maskCompletedText:n,placeholder:a,className:l,apiConfig:m,columns:d,typewriterEffect:c=!0,value:u,completedParams:g,onChange:f,onParamsChange:_},z){let w=(0,D.useRef)(null),b=(0,D.useRef)(()=>{}),[S,A]=(0,D.useState)(0),x=(0,D.useRef)(void 0);(0,D.useEffect)(()=>(w.current?.focus(),()=>{x.current&&cancelAnimationFrame(x.current)}),[]);let{completedParams:v,suggestionPills:B,setActivePill:I,segments:P,newParamId:i,clearNewParamId:s,inputProps:C,dropdownProps:L,reset:O}=_e({onSubmit:y=>b.current(y),onError:t,optionOverrides:o,maskCompletedText:n,placeholder:a,apiConfig:m,columns:d,value:u,completedParams:g,onChange:f,onParamsChange:_});(0,D.useEffect)(()=>{if(x.current&&cancelAnimationFrame(x.current),!i){A(0);return}let y=v.find(j=>j.id===i);if(!y)return;let H=y.text.length;if(!c){A(H);let j=window.setTimeout(()=>s(),650);return()=>window.clearTimeout(j)}A(0);let re=performance.now(),M=300,q=()=>{let j=performance.now()-re,le=Math.min(j/M,1),Z=Math.ceil(le*H);A(Z),Z<H?x.current=requestAnimationFrame(q):x.current=requestAnimationFrame(()=>{s()})};return x.current=requestAnimationFrame(q),()=>{x.current&&cancelAnimationFrame(x.current)}},[i,v,s,c]),(0,D.useImperativeHandle)(z,()=>({focus:()=>w.current?.focus(),reset:O}),[O]);let ee=()=>{w.current?.focus()},J=!!C.value||v.length>0,$=(0,D.useCallback)(()=>{if(!J)return;let{rawQuery:y,completedParams:H}=se(C.value,v);r({query:C.value.trim(),raw_query:y,completed_params:H}),O()},[J,C.value,v,r,O]);b.current=$;let{onChange:N,placeholder:V,...K}=C,X=!C.value;return(0,E.jsxs)("div",{className:`${F.container} ${l??""}`,children:[(0,E.jsx)(be,{...L}),(0,E.jsxs)("div",{className:F.inputWrapper,onClick:ee,children:[(0,E.jsxs)("div",{className:F.editorArea,children:[(0,E.jsxs)("div",{className:F.sizerContent,"aria-hidden":"true",children:[X&&V?(0,E.jsxs)("span",{className:F.placeholderText,children:[V," "]}):(0,E.jsxs)("span",{className:`${F.sizerText} ${i?F.sizerTextVisible:""}`,children:[P.map((y,H)=>{if(y.type==="completed"&&y.param.id===i){if(!c){let ue=`${F.shimmerRevealed} ${F.shimmerSweep}`;return(0,E.jsx)("span",{className:ue,children:y.value},`${H}-${y.type}`)}let M=y.value.length,q=y.value.slice(0,S),j=y.value.slice(S),Z=`${100-(M>0?S/M:0)*100}% 0`;return(0,E.jsxs)("span",{className:F.shimmer,children:[(0,E.jsx)("span",{className:F.shimmerRevealed,style:{backgroundPosition:Z},children:q}),(0,E.jsx)("span",{className:F.shimmerHidden,children:j})]},`${H}-${y.type}`)}return(0,E.jsx)("span",{children:y.value},`${H}-${y.type}`)}),P.length===0&&"\xA0"]})," ",(0,E.jsx)(He,{pills:B,activePillIndex:0,onSelectPill:I})]}),(0,E.jsx)("textarea",{ref:w,className:`${F.textarea} ${i?F.textareaHidden:""}`,rows:1,onChange:N,...K})]}),(0,E.jsx)("button",{type:"button",className:F.submitButton,disabled:!J,onClick:y=>{y.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});
532
+ `,document.head.appendChild(e)}var he={list:"PillList-module_list_qvLqO",pill:"PillList-module_pill_osSyz",fadeIn:"PillList-module_fadeIn_Aezob",active:"PillList-module_active_Oll--"};var Oe=require("react/jsx-runtime");function dt(e){return e===0?.4:e===1?.3:.15}function He({pills:e,activePillIndex:r,onSelectPill:t}){return(0,Oe.jsx)("span",{className:he.list,children:e.map((o,n)=>(0,Oe.jsx)("button",{type:"button",className:`${he.pill} ${n===r?he.active:""}`,style:{opacity:dt(n)},onClick:()=>t(n),children:o.text},`${o.type}-${o.text}`))})}var p=require("react");function ae(e,r,t){let o=e.slice(r);if(t||r===0||e[r-1]===" ")return o;let n=o.indexOf(" ");return n===-1?"":o.slice(n+1)}function xe(e,r){if(!e)return[];let t=r.trimStart();if(!t)return e;let o=t.toLowerCase();return e.filter(n=>!n.is_tappable||n.text.toLowerCase().includes(o))}function me(e,r){if(!e)return null;let t=r.trim();if(!t)return null;let o=t.toLowerCase();return e.find(n=>n.is_tappable&&n.text.toLowerCase()===o)??null}function Ne(e,r){let t=[],o=0;for(let a of r){let l=e.indexOf(a.text,o);l!==-1&&(l>o&&t.push({type:"text",value:e.slice(o,l)}),t.push({type:"completed",value:a.text,param:a}),o=l+a.text.length)}let n=e.slice(o);return n&&t.push({type:"text",value:n}),t}function Ve(e,r){let t=[],o=[],n=0;for(let a of r){let l=e.indexOf(a.text,n);l===-1?o.push(a):(t.push(a),n=l+a.text.length)}return{valid:t,invalid:o}}var U=require("react");var mt="0.1.17",je=!1;function gt(){return crypto.randomUUID()}function ft(e,r){return{placeholder:e.placeholder,type:e.type,...r&&{text:e.text},kind:e.kind}}async function Be(e,r,t){let o=t?.apiConfig,n=o?.apiKey??"";!n&&!je&&(je=!0,console.warn("[AIAutocomplete] No apiKey in apiConfig. Requests will be sent without an Authorization header."));let a=o?.authScheme??"Bearer",l=!t?.maskCompletedText,m=r.find(f=>f.type==="contact"&&f.metadata?.contact_account_count)?.metadata?.contact_account_count,d=typeof m=="number"?m:void 0,c={data:{raw_query:e,completed_params:r.map(f=>ft(f,l)),...d!=null&&{contact_account_count:d}},meta:{request_id:gt(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:mt}},u={"Content-Type":"application/json",...o?.appIdentifier&&{"X-App-Identifier":o.appIdentifier},...o?.headers};n&&(u.Authorization=a==="Basic"?`Basic ${btoa(n)}`:`Bearer ${n}`);let g=await fetch(o?.endpoint??"/ac/suggest",{method:"POST",headers:u,body:JSON.stringify(c),signal:t?.signal});if(!g.ok)throw new Error(`API error: ${g.status} ${g.statusText}`);return g.json()}function se(e,r){let t=e,o={},n=[];for(let a of r){let l=(o[a.type]??0)+1;o[a.type]=l;let d=`{{${a.type.toUpperCase().replace(/\s+/g,"_")}_${l}}}`,c=t.indexOf(a.text);c!==-1&&(t=t.slice(0,c)+d+t.slice(c+a.text.length)),n.push({...a,placeholder:d})}return{rawQuery:t,completedParams:n}}function Ke(e,r){return r?e.map(t=>{let o=r[t.type];if(!o)return t;let n=o("");if(n.length===0)return t;let a=new Set(n.map(m=>m.text)),l=(t.options??[]).filter(m=>!a.has(m.text));return{...t,options:[...n,...l]}}):e}var bt=100,ht=300,xt=2;function qe({textRef:e,suggestionsRef:r,filterBaseRef:t,filterInProgressRef:o,maskCompletedTextRef:n,apiConfigRef:a,optionOverridesRef:l,onErrorRef:m,setCompletedParams:d,setSuggestions:c,setActiveDropdownIndex:u}){let[g,f]=(0,U.useState)(!1),[_,z]=(0,U.useState)(null),[w,b]=(0,U.useState)(!1),S=(0,U.useRef)(0),A=(0,U.useRef)(null),x=(0,U.useRef)(""),v=(0,U.useCallback)(async(B,I)=>{A.current?.abort();let P=new AbortController;A.current=P;let i=++S.current,s=e.current.length;r.current.some(L=>L.type!=="placeholder")||f(!0),z(null);try{let L=await Be(B,I,{maskCompletedText:n.current,signal:P.signal,apiConfig:a.current});if(i!==S.current)return;let O=Ke(L.data.suggestions??[],l.current);b(L.data.is_ready??!1),x.current=B;let ee=L.data.input??[],J=ee[ee.length-1],$=e.current;if(J?.state==="in_progress"){o.current=!0;let K=$.toLowerCase().lastIndexOf(J.text.toLowerCase());K!==-1?t.current=K:t.current=s}else o.current=!1,t.current=s;let V=O.filter(K=>K.type!=="placeholder")[0];if(V){let K=ae($,t.current,o.current),X=me(V.options,K);X&&(d(y=>[...y,{id:crypto.randomUUID(),placeholder:"",type:V.type,text:X.text,kind:X.kind,suggestionType:V.type,suggestionPlaceholder:V.text,options:V.options??[],metadata:X.metadata}]),O=O.filter(y=>y!==V))}c(O),f(!1),u(-1)}catch(L){if(i===S.current){let O=L instanceof Error?L:new Error(String(L));z(O),f(!1),m.current?.(O)}}},[e,r,t,o,n,a,l,m,d,c,u]);return(0,U.useEffect)(()=>(v("",[]),()=>{A.current?.abort()}),[v]),{doFetch:v,isLoading:g,error:_,isReady:w,lastRawQueryRef:x}}function Qe({text:e,completedParams:r,doFetch:t,filterBaseRef:o,filterInProgressRef:n,skipNextFetchRef:a,suggestionsRef:l,lastRawQueryRef:m}){let d=(0,U.useRef)(null),c=(0,U.useRef)(null),u=(0,U.useRef)(!0);(0,U.useEffect)(()=>{if(d.current&&clearTimeout(d.current),c.current&&clearTimeout(c.current),a.current){a.current=!1;return}let g=f=>{if(!e&&r.length===0)return u.current?(t("",[]),!0):(u.current=!0,!1);let _=ae(e,o.current,n.current),b=l.current.filter(s=>s.type!=="placeholder")[0],A=(b?xe(b.options,_):[]).filter(s=>s.is_tappable),x=b?me(b.options,_)!==null:!1,v=_.trim().length>0;if(A.length>0&&!x&&v)return!1;let{rawQuery:B,completedParams:I}=se(e,r),P=B.length<m.current.length,i=Math.abs(B.length-m.current.length);return P||i>=f?(t(B,I),!0):!1};return d.current=setTimeout(()=>{g(xt)&&c.current&&clearTimeout(c.current)},bt),c.current=setTimeout(()=>g(1),ht),()=>{d.current&&clearTimeout(d.current),c.current&&clearTimeout(c.current)}},[e,r,t,o,n,a,l,m])}var Te=require("react");function Ge({activeDropdownIndex:e,setActiveDropdownIndex:r,filteredOptions:t,selectOption:o,onSubmitRef:n,text:a,completedParams:l,isDropdownOpen:m,hasPlaceholder:d,placeholderText:c,suggestions:u,actionableSuggestions:g,setActivePill:f,listboxId:_,pillTappedRef:z,filterBaseRef:w,columns:b,setText:S,setCompletedParams:A,setSuggestions:x}){let v=(0,Te.useCallback)(()=>{let I=t.map((i,s)=>i.is_tappable?s:-1).filter(i=>i!==-1),P=Array.from({length:b},()=>[]);for(let i of I)P[i%b].push(i);return P.flat()},[t,b]);return{handleKeyDown:(0,Te.useCallback)(I=>{let P=v();switch(I.key){case"ArrowDown":{let i=I.target;if(!(i.selectionStart!=null&&i.selectionStart===i.value.length)&&e<0)break;if(I.preventDefault(),!m&&g.length>0){z.current=!0;let O=P[0];r(O??0);break}if(P.length===0)return;let C=P.indexOf(e),L=C<P.length-1?C+1:0;r(P[L]);break}case"ArrowUp":{if(P.length===0||e<0)break;if(I.preventDefault(),e<b){r(-1);break}let s=P.indexOf(e),C=s>0?s-1:P.length-1;r(P[C]);break}case"ArrowRight":{if(e<0){let s=I.target;s.selectionStart!=null&&s.selectionStart===s.value.length&&g.length>1&&(I.preventDefault(),f(1));break}if(e%b<b-1){let s=e+1;s<t.length&&t[s]?.is_tappable&&(I.preventDefault(),r(s))}break}case"ArrowLeft":{if(e<0)break;if(e%b>0){let i=e-1;i>=0&&t[i]?.is_tappable&&(I.preventDefault(),r(i))}break}case"Enter":{if(I.preventDefault(),e>=0&&t[e]?.is_tappable){let i=document.getElementById(`${_}-option-${e}`);i?i.click():o(t[e])}else if(n.current){let{rawQuery:i,completedParams:s}=se(a,l),C={query:a.trim(),raw_query:i,completed_params:s};n.current(C)}break}case"Tab":{if(e>=0&&t[e]?.is_tappable){I.preventDefault();let i=document.getElementById(`${_}-option-${e}`);i?i.click():o(t[e])}else if(m){let i=t.findIndex(s=>s.is_tappable);if(i>=0){I.preventDefault();let s=document.getElementById(`${_}-option-${i}`);s?s.click():o(t[i])}}else if(!a&&d){I.preventDefault();let i=u.find(s=>s.type==="placeholder");i?(S(c),w.current=c.length,A(s=>[...s,{id:crypto.randomUUID(),placeholder:"",type:i.type,text:c,kind:null,suggestionType:i.type,suggestionPlaceholder:i.text,options:i.options??[]}]),x(s=>s.filter(C=>C!==i))):(S(c),w.current=c.length)}break}case"Escape":r(-1);break}},[g,e,b,l,t,w,v,d,_,z,m,n,c,o,r,f,A,x,S,u,a]),getTappableIndices:v}}var ye=require("react");function We({completedParams:e,suggestions:r,setCompletedParams:t,setSuggestions:o,setActiveDropdownIndex:n,filterBaseRef:a,pillTappedRef:l}){let m=(0,ye.useCallback)(u=>{let g=r.filter(w=>w.type!=="placeholder");if(u<0||u>=g.length)return;let f=g[u],_=g.filter((w,b)=>b!==u),z=r.filter(w=>w.type==="placeholder");o([...z,f,..._]),l.current=!0,n(-1)},[r,o,n,l]),d=(0,ye.useCallback)(()=>{if(e.length===0)return;let u=e[e.length-1],g={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};t(f=>f.slice(0,-1)),o(f=>[g,...f]),n(-1)},[e,t,o,n]),c=(0,ye.useCallback)(u=>{let g={type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options};return{apply:f=>{f(_=>{let z=0;for(let w of e){let b=_.indexOf(w.text,z);if(b!==-1){if(w.id===u.id){let S=_.slice(0,b),A=_.slice(b+u.text.length),x=(S+A).replace(/ {2,}/g," ");return a.current=Math.min(a.current,x.length),x}z=b+w.text.length}}return _}),t(_=>_.filter(z=>z.id!==u.id)),o(_=>[g,..._]),n(-1),l.current=!0}}},[e,t,o,n,a,l]);return{setActivePill:m,removeLastParam:d,reEditParam:c}}var yt=0;function _t(){let e=(0,p.useRef)(null);return e.current===null&&(e.current=`:ac-${++yt}:`),e.current}function _e({onSubmit:e,onError:r,optionOverrides:t,maskCompletedText:o,placeholder:n,apiConfig:a,columns:l=2,value:m,completedParams:d,onChange:c,onParamsChange:u}){let g=m!==void 0,f=d!==void 0,[_,z]=(0,p.useState)(""),[w,b]=(0,p.useState)([]),[S,A]=(0,p.useState)([]),[x,v]=(0,p.useState)(-1),[B,I]=(0,p.useState)(null),P=(0,p.useCallback)(()=>I(null),[]),i=g?m:_,s=f?d:w,C=(0,p.useRef)(e);C.current=e;let L=(0,p.useRef)(c);L.current=c;let O=(0,p.useRef)(u);O.current=u;let ee=(0,p.useRef)(m);ee.current=m;let J=(0,p.useRef)(d);J.current=d;let $=(0,p.useCallback)(h=>{if(typeof h=="function")if(g){let R=h(ee.current??"");L.current?.(R)}else z(R=>{let T=h(R);return L.current?.(T),T});else g||z(h),L.current?.(h)},[g]),N=(0,p.useCallback)(h=>{if(typeof h=="function")if(f){let R=h(J.current??[]);O.current?.(R)}else b(R=>{let T=h(R);return O.current?.(T),T});else f||b(h),O.current?.(h)},[f]),V=(0,p.useRef)(r);V.current=r;let K=(0,p.useRef)(t);K.current=t;let X=(0,p.useRef)(o);X.current=o;let y=(0,p.useRef)(a);y.current=a;let H=(0,p.useRef)(i);H.current=i;let re=(0,p.useRef)(S);re.current=S;let M=(0,p.useRef)(0),q=(0,p.useRef)(!1),j=(0,p.useRef)(!1),le=(0,p.useRef)(!1),Z=_t(),{doFetch:ue,isLoading:Ee,error:Xe,isReady:Ze,lastRawQueryRef:Se}=qe({textRef:H,suggestionsRef:re,filterBaseRef:M,filterInProgressRef:q,maskCompletedTextRef:X,apiConfigRef:y,optionOverridesRef:K,onErrorRef:V,setCompletedParams:N,setSuggestions:A,setActiveDropdownIndex:v});Qe({text:i,completedParams:s,doFetch:ue,filterBaseRef:M,filterInProgressRef:q,skipNextFetchRef:le,suggestionsRef:re,lastRawQueryRef:Se});let Ye=(0,p.useMemo)(()=>Ne(i,s),[i,s]);M.current=Math.min(M.current,i.length);let Ae=ae(i,M.current,q.current),ne=(0,p.useMemo)(()=>S.filter(R=>R.type==="placeholder").map(R=>R.text).join(" ")||n||"",[S,n]),ce=(0,p.useMemo)(()=>S.filter(h=>h.type!=="placeholder"),[S]),k=ce[0],ze=k?t?.[k.type]:void 0,Le=k?ze?ze(Ae.trim()):k.options??[]:[],ve=(0,p.useMemo)(()=>xe(Le,Ae),[Le,Ae]),Me=ne.length>0,Ie=!Ee&&ve.length>0&&(!!i||j.current||!Me),Fe=(0,p.useCallback)(h=>{if(!k)return;let R=M.current,T=H.current.slice(0,R),ie=T.length===0&&H.current.length===0;if(ie&&ne&&(T=ne+" "),T.length>0&&!T.endsWith(" ")){let te=T.split(/\s+/).pop()??"";te&&h.text.toLowerCase().startsWith(te.toLowerCase())&&(T=T.slice(0,T.length-te.length))}let we=T.length>0&&T[T.length-1]!==" ",Y=T+(we?" ":"")+h.text+" ",Q=ie&&Y.length>0?Y[0].toUpperCase()+Y.slice(1):Y,G=Q.toLowerCase().lastIndexOf(h.text.toLowerCase()),de=G>=0?Q.slice(G,G+h.text.length):h.text,ge={id:crypto.randomUUID(),placeholder:"",type:k.type,text:de,kind:h.kind,suggestionType:k.type,suggestionPlaceholder:k.text,options:k.options??[],metadata:h.metadata};$(Q),M.current=Q.length,N(te=>[...te,ge]),I(ge.id),j.current=!1,v(-1),ce.length-1>0&&(le.current=!0),setTimeout(()=>{A(te=>te.filter(it=>it!==k))},400)},[k,ce,ne,$,N]),et=(0,p.useCallback)(h=>{let R=h.target.value,ie=R.length>0&&!h.nativeEvent?.isComposing&&R[0]!==R[0].toUpperCase()?R[0].toUpperCase()+R.slice(1):R;$(ie),j.current=!1,v(-1);let{valid:we,invalid:Y}=Ve(ie,s);if(Y.length>0){N(()=>we);for(let Q of Y)A(G=>[{type:Q.suggestionType,text:Q.suggestionPlaceholder,required:!0,options:Q.options},...G])}if(k&&Y.length===0){let Q=ae(ie,M.current,q.current),G=me(k.options,Q);G&&(N(de=>[...de,{id:crypto.randomUUID(),placeholder:"",type:k.type,text:G.text,kind:G.kind,suggestionType:k.type,suggestionPlaceholder:k.text,options:k.options??[],metadata:G.metadata}]),A(de=>de.filter(ge=>ge!==k)))}},[s,k,$,N]),pe=We({completedParams:s,suggestions:S,setCompletedParams:N,setSuggestions:A,setActiveDropdownIndex:v,filterBaseRef:M,pillTappedRef:j}),tt=(0,p.useCallback)(h=>{pe.reEditParam(h).apply($)},[pe,$]),{handleKeyDown:ot}=Ge({activeDropdownIndex:x,setActiveDropdownIndex:v,filteredOptions:ve,selectOption:Fe,onSubmitRef:C,text:i,completedParams:s,isDropdownOpen:Ie,hasPlaceholder:Me,placeholderText:ne,suggestions:S,actionableSuggestions:ce,setActivePill:pe.setActivePill,listboxId:Z,pillTappedRef:j,filterBaseRef:M,columns:l,setText:$,setCompletedParams:N,setSuggestions:A}),rt=(0,p.useCallback)(()=>{$(""),N(()=>[]),A([]),v(-1),M.current=0,q.current=!1,Se.current="",ue("",[])},[ue,$,N,Se]),nt=x>=0?`${Z}-option-${x}`:void 0;return{completedParams:s,suggestionPills:ce,setActivePill:pe.setActivePill,removeLastParam:pe.removeLastParam,reEditParam:tt,segments:Ye,newParamId:B,clearNewParamId:P,suggestions:S,activeIndex:x,isReady:Ze,isLoading:Ee,error:Xe,inputProps:{value:i,placeholder:ne||void 0,onChange:et,onKeyDown:ot,role:"combobox","aria-expanded":Ie,"aria-activedescendant":nt,"aria-autocomplete":"list","aria-controls":Z},reset:rt,dropdownProps:{suggestions:k?[{...k,options:ve}]:[],activeIndex:x,onSelect:Fe,onHighlight:v,isOpen:Ie,id:Z}}}var E=require("react/jsx-runtime"),Je=(0,D.forwardRef)(function({onSubmit:r,onError:t,optionOverrides:o,maskCompletedText:n,placeholder:a,className:l,apiConfig:m,columns:d,typewriterEffect:c=!1,value:u,completedParams:g,onChange:f,onParamsChange:_},z){let w=(0,D.useRef)(null),b=(0,D.useRef)(()=>{}),[S,A]=(0,D.useState)(0),x=(0,D.useRef)(void 0);(0,D.useEffect)(()=>(w.current?.focus(),()=>{x.current&&cancelAnimationFrame(x.current)}),[]);let{completedParams:v,suggestionPills:B,setActivePill:I,segments:P,newParamId:i,clearNewParamId:s,inputProps:C,dropdownProps:L,reset:O}=_e({onSubmit:y=>b.current(y),onError:t,optionOverrides:o,maskCompletedText:n,placeholder:a,apiConfig:m,columns:d,value:u,completedParams:g,onChange:f,onParamsChange:_});(0,D.useEffect)(()=>{if(x.current&&cancelAnimationFrame(x.current),!i){A(0);return}let y=v.find(j=>j.id===i);if(!y)return;let H=y.text.length;if(!c){A(H);let j=window.setTimeout(()=>s(),650);return()=>window.clearTimeout(j)}A(0);let re=performance.now(),M=300,q=()=>{let j=performance.now()-re,le=Math.min(j/M,1),Z=Math.ceil(le*H);A(Z),Z<H?x.current=requestAnimationFrame(q):x.current=requestAnimationFrame(()=>{s()})};return x.current=requestAnimationFrame(q),()=>{x.current&&cancelAnimationFrame(x.current)}},[i,v,s,c]),(0,D.useImperativeHandle)(z,()=>({focus:()=>w.current?.focus(),reset:O}),[O]);let ee=()=>{w.current?.focus()},J=!!C.value||v.length>0,$=(0,D.useCallback)(()=>{if(!J)return;let{rawQuery:y,completedParams:H}=se(C.value,v);r({query:C.value.trim(),raw_query:y,completed_params:H}),O()},[J,C.value,v,r,O]);b.current=$;let{onChange:N,placeholder:V,...K}=C,X=!C.value;return(0,E.jsxs)("div",{className:`${F.container} ${l??""}`,children:[(0,E.jsx)(be,{...L}),(0,E.jsxs)("div",{className:F.inputWrapper,onClick:ee,children:[(0,E.jsxs)("div",{className:F.editorArea,children:[(0,E.jsxs)("div",{className:F.sizerContent,"aria-hidden":"true",children:[X&&V?(0,E.jsxs)("span",{className:F.placeholderText,children:[V," "]}):(0,E.jsxs)("span",{className:`${F.sizerText} ${i?F.sizerTextVisible:""}`,children:[P.map((y,H)=>{if(y.type==="completed"&&y.param.id===i){if(!c){let ue=`${F.shimmerRevealed} ${F.shimmerSweep}`;return(0,E.jsx)("span",{className:ue,children:y.value},`${H}-${y.type}`)}let M=y.value.length,q=y.value.slice(0,S),j=y.value.slice(S),Z=`${100-(M>0?S/M:0)*100}% 0`;return(0,E.jsxs)("span",{className:F.shimmer,children:[(0,E.jsx)("span",{className:F.shimmerRevealed,style:{backgroundPosition:Z},children:q}),(0,E.jsx)("span",{className:F.shimmerHidden,children:j})]},`${H}-${y.type}`)}return(0,E.jsx)("span",{children:y.value},`${H}-${y.type}`)}),P.length===0&&"\xA0"]})," ",(0,E.jsx)(He,{pills:B,activePillIndex:0,onSelectPill:I})]}),(0,E.jsx)("textarea",{ref:w,className:`${F.textarea} ${i?F.textareaHidden:""}`,rows:1,onChange:N,...K})]}),(0,E.jsx)("button",{type:"button",className:F.submitButton,disabled:!J,onClick:y=>{y.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});
533
533
  //# sourceMappingURL=index.js.map