@magicx-eng/ai-autocomplete-react 0.1.3 → 0.1.4

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
@@ -9,6 +9,8 @@ A React/TypeScript SDK that provides a guided AI-powered autocomplete experience
9
9
  - **Keyboard navigation** — arrow keys, enter to submit, tab to autocomplete
10
10
  - **Client-side filtering** — instant substring filtering on every keystroke
11
11
  - **Option overrides** — inject or dynamically generate client-side options per suggestion type
12
+ - **Controlled & uncontrolled** — works out of the box or integrates with external state
13
+ - **Ref forwarding** — imperative `focus()` and `reset()` via ref
12
14
  - **Accessible** — ARIA combobox pattern with `role="listbox"`, `aria-activedescendant`
13
15
  - **Lightweight** — zero dependencies beyond React
14
16
  - **TypeScript first** — full type definitions shipped with the package
@@ -39,6 +41,7 @@ import { AIAutocomplete } from "@magicx-eng/ai-autocomplete-react";
39
41
  function App() {
40
42
  return (
41
43
  <AIAutocomplete
44
+ apiConfig={{ apiKey: "your_api_key" }}
42
45
  onSubmit={(result) => {
43
46
  console.log(result.query); // "Create a email"
44
47
  console.log(result.raw_query); // "Create a {{TASK_1}}"
@@ -69,7 +72,8 @@ function App() {
69
72
  error,
70
73
  reset,
71
74
  } = useAIAutocomplete({
72
- onSubmit: () => handleMySubmit(),
75
+ onSubmit: (result) => handleMySubmit(result),
76
+ apiConfig: { apiKey: "your_api_key" },
73
77
  });
74
78
 
75
79
  return (
@@ -81,6 +85,38 @@ function App() {
81
85
  }
82
86
  ```
83
87
 
88
+ ### Controlled Mode
89
+
90
+ Pass `value` and `onChange` to control the text externally:
91
+
92
+ ```tsx
93
+ const [text, setText] = useState("");
94
+ const [params, setParams] = useState([]);
95
+
96
+ <AIAutocomplete
97
+ value={text}
98
+ onChange={setText}
99
+ completedParams={params}
100
+ onParamsChange={setParams}
101
+ onSubmit={(result) => console.log(result)}
102
+ />
103
+ ```
104
+
105
+ ### Imperative Handle
106
+
107
+ Use a ref to focus or reset programmatically:
108
+
109
+ ```tsx
110
+ import { useRef } from "react";
111
+ import { AIAutocomplete, type AIAutocompleteHandle } from "@magicx-eng/ai-autocomplete-react";
112
+
113
+ const ref = useRef<AIAutocompleteHandle>(null);
114
+ // ref.current?.focus()
115
+ // ref.current?.reset()
116
+
117
+ <AIAutocomplete ref={ref} onSubmit={handleSubmit} />
118
+ ```
119
+
84
120
  ## API Reference
85
121
 
86
122
  ### `<AIAutocomplete />`
@@ -89,10 +125,26 @@ The full component. Owns the input, pills, dropdown, and keyboard navigation.
89
125
 
90
126
  | Prop | Type | Default | Description |
91
127
  |---|---|---|---|
92
- | `onSubmit` | `(result: AutocompleteResult) => void` | **required** | Called when the user submits via Enter or the submit button. |
93
- | `optionOverrides?` | `Record<string, (query: string) => SuggestionOption[]>` | — | Override options per suggestion type. Receives the current filter query. For static options, ignore the query: `() => myOptions`. |
94
- | `placeholder?` | `string` | — | Fallback placeholder shown when the server doesn't return one. |
95
- | `className?` | `string` | — | CSS class applied to the container element. |
128
+ | `onSubmit` | `(result: AutocompleteResult) => void` | **required** | Called on Enter or submit button. |
129
+ | `onError?` | `(error: Error) => void` | — | Called when a fetch fails. |
130
+ | `apiConfig?` | `APIConfig` | — | Runtime API configuration (see below). |
131
+ | `optionOverrides?` | `Record<string, (query: string) => SuggestionOption[]>` | — | Override options per suggestion type. |
132
+ | `placeholder?` | `string` | — | Fallback placeholder when the server doesn't return one. |
133
+ | `className?` | `string` | — | CSS class applied to the container. |
134
+ | `columns?` | `number` | `2` | Number of columns in the dropdown grid. |
135
+ | `value?` | `string` | — | Controlled text value. |
136
+ | `completedParams?` | `CompletedParamState[]` | — | Controlled completed params. |
137
+ | `onChange?` | `(value: string) => void` | — | Called when text changes (controlled mode). |
138
+ | `onParamsChange?` | `(params: CompletedParamState[]) => void` | — | Called when params change (controlled mode). |
139
+ | `ref?` | `Ref<AIAutocompleteHandle>` | — | Imperative handle with `focus()` and `reset()`. |
140
+
141
+ ### `APIConfig`
142
+
143
+ | Field | Type | Description |
144
+ |---|---|---|
145
+ | `apiKey?` | `string` | API key for Authorization header. Falls back to `MAGICX_AI_AUTOCOMPLETE_API_KEY` env var. |
146
+ | `authScheme?` | `"Bearer" \| "Basic"` | Auth header scheme. Default: `"Bearer"`. |
147
+ | `headers?` | `Record<string, string>` | Additional headers merged into every request. |
96
148
 
97
149
  ### `AutocompleteResult`
98
150
 
@@ -104,39 +156,11 @@ The object passed to `onSubmit`:
104
156
  | `raw_query` | `string` | Text with placeholder tokens (e.g. `"Create a {{TASK_1}}"`). |
105
157
  | `completed_params` | `CompletedParam[]` | Array of filled parameter values. |
106
158
 
107
- ### `CompletedParam`
108
-
109
- | Field | Type | Description |
110
- |---|---|---|
111
- | `placeholder` | `string` | The placeholder token (e.g. `"{{TASK_1}}"`). |
112
- | `type` | `string` | Suggestion type (e.g. `"task"`, `"goal"`). |
113
- | `text?` | `string` | The selected option text. |
114
- | `kind` | `string \| null` | Category of the option, or `null`. |
115
-
116
- ### `<AIAutocompleteDropdown />`
117
-
118
- The dropdown component. Used in Tier 2 for headless integration.
119
-
120
- | Prop | Type | Description |
121
- |---|---|---|
122
- | `suggestions` | `Suggestion[]` | Suggestions to display (from `dropdownProps`). |
123
- | `activeIndex` | `number` | Currently highlighted option index. |
124
- | `onSelect` | `(option: SuggestionOption) => void` | Called when an option is selected. |
125
- | `isOpen` | `boolean` | Whether the dropdown is visible. |
126
- | `id` | `string` | Listbox ID for ARIA. |
127
- | `className?` | `string` | CSS class applied to the dropdown. |
128
-
129
159
  ### `useAIAutocomplete(options)`
130
160
 
131
161
  The core hook. Manages state, API calls, filtering, pills, and keyboard navigation.
132
162
 
133
- #### Options
134
-
135
- | Field | Type | Default | Description |
136
- |---|---|---|---|
137
- | `onSubmit?` | `() => void` | — | Called when Enter is pressed with no option highlighted. |
138
- | `optionOverrides?` | `OptionOverrides` | — | Override options per suggestion type (same as component prop). |
139
- | `placeholder?` | `string` | — | Fallback placeholder. |
163
+ Accepts the same props as `<AIAutocomplete />` (except `className` and `ref`), with `onSubmit` receiving an `AutocompleteResult`.
140
164
 
141
165
  #### Return Value
142
166
 
@@ -144,38 +168,37 @@ The core hook. Manages state, API calls, filtering, pills, and keyboard navigati
144
168
  |---|---|---|
145
169
  | `completedParams` | `CompletedParamState[]` | All filled parameters with client-side state. |
146
170
  | `suggestionPills` | `Suggestion[]` | Unfilled suggestion pills (excludes placeholders). |
147
- | `activePillIndex` | `number` | Index of the active pill (always `0`). |
148
171
  | `setActivePill` | `(index: number) => void` | Reorder pills by moving one to the front. |
149
- | `removeLastParam` | `() => void` | Remove the last completed parameter and restore its suggestion. |
150
- | `reEditParam` | `(param: CompletedParamState) => void` | Remove a specific completed parameter, restore its suggestion, and remove its text from the input. |
172
+ | `removeLastParam` | `() => void` | Remove the last completed parameter and restore its pill. |
173
+ | `reEditParam` | `(param: CompletedParamState) => void` | Remove a completed parameter and restore its pill. |
151
174
  | `reset` | `() => void` | Clear all state and re-fetch initial suggestions. |
152
- | `segments` | `Segment[]` | Text segments for overlay rendering — `"text"` or `"completed"` with the associated param. |
175
+ | `segments` | `Segment[]` | Text segments for overlay rendering. |
153
176
  | `suggestions` | `Suggestion[]` | All suggestions including placeholders. |
154
- | `activeIndex` | `number` | Currently highlighted dropdown option index (`-1` when none). |
177
+ | `activeIndex` | `number` | Currently highlighted option index (`-1` when none). |
155
178
  | `isLoading` | `boolean` | Whether a fetch is in progress. |
179
+ | `isReady` | `boolean` | Whether the server considers the query complete. |
156
180
  | `error` | `Error \| null` | Last fetch error, or `null`. |
157
- | `inputProps` | `object` | Spread onto a `<textarea>` — includes `value`, `placeholder`, `onChange`, `onKeyDown`, and ARIA attributes. |
181
+ | `inputProps` | `object` | Spread onto a `<textarea>` — value, placeholder, onChange, onKeyDown, ARIA. |
158
182
  | `dropdownProps` | `AIAutocompleteDropdownProps` | Spread onto `<AIAutocompleteDropdown />`. |
159
183
 
160
- ### `SuggestionOption`
184
+ ### `<AIAutocompleteDropdown />`
161
185
 
162
- | Field | Type | Description |
163
- |---|---|---|
164
- | `text` | `string` | Display text for the option. |
165
- | `icon?` | `string` | Icon shown before the text (e.g. emoji). |
166
- | `tag?` | `string` | Tag shown after the text in smaller, muted style. |
167
- | `is_tappable` | `boolean` | Whether the option can be selected. Non-tappable options are always-visible hints. |
168
- | `kind` | `string \| null` | Category of the option. |
169
- | `metadata?` | `Record<string, unknown>` | Arbitrary metadata passed through with the selection. |
186
+ The dropdown component for Tier 2 headless integration. Spread `dropdownProps` from the hook.
170
187
 
171
- ### `Suggestion`
188
+ ## CSS Customization
172
189
 
173
- | Field | Type | Description |
174
- |---|---|---|
175
- | `type` | `string` | Suggestion type identifier. |
176
- | `text` | `string` | Display text for the pill. |
177
- | `required` | `boolean` | Whether this suggestion must be filled. |
178
- | `options` | `SuggestionOption[]` | Available options for this suggestion. |
190
+ The component uses CSS Modules with customizable CSS variables. Override them on a parent element:
191
+
192
+ ```css
193
+ .my-autocomplete {
194
+ --ac-color-border-default: #ccc;
195
+ --ac-color-text-default: #333;
196
+ --ac-color-text-muted: #999;
197
+ --ac-color-bg-default: #fff;
198
+ --ac-color-background-default: #fff;
199
+ --ac-color-background-supportive: #f0f0f0;
200
+ }
201
+ ```
179
202
 
180
203
  ## Keyboard Behavior
181
204
 
@@ -189,35 +212,24 @@ The core hook. Manages state, API calls, filtering, pills, and keyboard navigati
189
212
 
190
213
  ## Option Overrides
191
214
 
192
- Use `optionOverrides` to inject client-side options per suggestion type. The function receives the current filter query:
215
+ Use `optionOverrides` to inject client-side options per suggestion type:
193
216
 
194
217
  ```tsx
195
- // Static options (ignore query)
196
218
  const overrides = {
219
+ // Static options
197
220
  account: () => [
198
221
  { text: "Savings", is_tappable: true, kind: null },
199
222
  { text: "Checking", is_tappable: true, kind: null },
200
223
  ],
201
- };
202
-
203
- // Dynamic options (use query)
204
- const overrides = {
224
+ // Dynamic options based on filter query
205
225
  value: (query) => {
206
226
  const digits = query.replace(/\D/g, "");
207
227
  if (!digits) return [{ text: "$100", is_tappable: true, kind: null }];
208
- return [
209
- { text: `$${digits}`, is_tappable: true, kind: null },
210
- { text: `$${digits}0`, is_tappable: true, kind: null },
211
- ];
228
+ return [{ text: `$${digits}`, is_tappable: true, kind: null }];
212
229
  },
213
230
  };
214
231
 
215
- // Non-tappable hints (always shown, not filterable)
216
- const overrides = {
217
- value: () => [
218
- { text: "Enter an amount", is_tappable: false, kind: null },
219
- ],
220
- };
232
+ <AIAutocomplete optionOverrides={overrides} onSubmit={handleSubmit} />
221
233
  ```
222
234
 
223
235
  Override options are prepended to server options (deduplicated by `text`). When a filter query is active and an override function exists, it replaces the default client-side filtering entirely.
package/dist/index.css CHANGED
@@ -1,2 +1,2 @@
1
- .container{position:relative;font-family:IBM Plex Sans,sans-serif}.checkmark{position:absolute;bottom:-130px;left:50%;transform:translate(-50%) translateY(8px) scale(.8);opacity:0;pointer-events:none;z-index:10;animation:none}.checkmarkVisible{animation:checkmarkFadeInOut 3s ease forwards}@keyframes checkmarkFadeInOut{0%{opacity:0;transform:translate(-50%) translateY(8px) scale(.8)}10%{opacity:1;transform:translate(-50%) translateY(0) scale(1)}80%{opacity:1;transform:translate(-50%) translateY(0) scale(1)}to{opacity:0;transform:translate(-50%) translateY(-8px) scale(.8)}}.checkmarkPath{stroke-dasharray:30;stroke-dashoffset:30}.checkmarkVisible .checkmarkPath{animation:drawCheck .4s ease forwards .1s}@keyframes drawCheck{to{stroke-dashoffset:0}}.inputWrapper{min-height:60px;padding:24px;border:1px solid var(--color-border-default, #9ea5b2);border-radius:23px;background:transparent;overflow:hidden;display:flex;align-items:center;gap:12px}.editorArea{position:relative;flex:1;min-width:0}.sizerContent{position:relative;z-index:1;pointer-events:none;min-height:60px;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:21px;line-height:38px}.sizerText{color:transparent}.placeholderText{color:var(--color-text-muted, #c1c4cb);opacity:.7}.textarea{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;border:none;background:transparent;color:var(--color-text-default, #fff);caret-color:var(--color-text-default, #fff);font-family:inherit;font-size:21px;line-height:38px;white-space:pre-wrap;word-break:break-word;outline:none;resize:none;overflow:hidden}.textarea::placeholder{color:var(--color-text-muted, #c1c4cb)}.submitButton{flex-shrink:0;width:36px;height:36px;border-radius:50%;border:none;background:var(--color-text-default, #fff);color:var(--color-bg-default, #000);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:opacity .2s ease}.submitButton:hover{opacity:.85}.dropdown{position:absolute;left:0;right:0;top:100%;margin-top:6px;background:var(--color-background-default, #00002d);border-radius:23px;overflow:hidden;z-index:10;animation:fadeIn .2s ease forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px 18px;padding:18px 24px;max-height:192px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.grid::-webkit-scrollbar{width:6px}.grid::-webkit-scrollbar-track{background:transparent}.grid::-webkit-scrollbar-thumb{background:#ffffff4d;border-radius:3px}.item{display:flex;align-items:center;font-family:IBM Plex Sans,sans-serif;font-size:21px;line-height:30px;color:var(--color-text-muted, #c1c4cb);white-space:nowrap;opacity:.35;animation:fadeIn .2s ease forwards}.tappable{cursor:pointer}.tappable:hover{color:var(--color-text-default, #fff)}.nonTappable{cursor:default;opacity:.3}.highlighted{color:var(--color-text-default, #fff);opacity:.5}.tag{font-size:13px;margin-left:6px;opacity:.5}.list{position:relative;z-index:1;pointer-events:auto;display:inline-flex;gap:5px;align-items:center;vertical-align:middle;transform:translateY(-3px)}.pill{display:inline-flex;align-items:center;justify-content:center;height:36px;padding:7px 9px;border:none;border-radius:6px;background:var(--color-background-supportive, #313255);color:var(--color-text-muted, #c1c4cb);font-family:IBM Plex Sans,sans-serif;font-size:21px;line-height:30px;cursor:pointer;white-space:nowrap;animation:fadeIn .2s ease forwards}.pill:hover{filter:brightness(1.2)}.active{outline:1px solid #5a5b8a}@keyframes fadeIn{0%{opacity:0}}
1
+ .container{position:relative;font-family:IBM Plex Sans,sans-serif}.checkmark{position:absolute;bottom:-130px;left:50%;transform:translate(-50%) translateY(8px) scale(.8);opacity:0;pointer-events:none;z-index:10;animation:none}.checkmarkVisible{animation:checkmarkFadeInOut 3s ease forwards}@keyframes checkmarkFadeInOut{0%{opacity:0;transform:translate(-50%) translateY(8px) scale(.8)}10%{opacity:1;transform:translate(-50%) translateY(0) scale(1)}80%{opacity:1;transform:translate(-50%) translateY(0) scale(1)}to{opacity:0;transform:translate(-50%) translateY(-8px) scale(.8)}}.checkmarkPath{stroke-dasharray:30;stroke-dashoffset:30}.checkmarkVisible .checkmarkPath{animation:drawCheck .4s ease forwards .1s}@keyframes drawCheck{to{stroke-dashoffset:0}}.inputWrapper{min-height:60px;padding:24px;border:1px solid var(--ac-color-border-default, #9ea5b2);border-radius:23px;background:transparent;overflow:hidden;display:flex;align-items:center;gap:12px}.editorArea{position:relative;flex:1;min-width:0}.sizerContent{position:relative;z-index:1;pointer-events:none;min-height:60px;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:21px;line-height:38px}.sizerText{color:transparent}.placeholderText{color:var(--ac-color-text-muted, #c1c4cb);opacity:.7}.textarea{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;border:none;background:transparent;color:var(--ac-color-text-default, #fff);caret-color:var(--ac-color-text-default, #fff);font-family:inherit;font-size:21px;line-height:38px;white-space:pre-wrap;word-break:break-word;outline:none;resize:none;overflow:hidden}.textarea::placeholder{color:var(--ac-color-text-muted, #c1c4cb)}.submitButton{flex-shrink:0;width:36px;height:36px;border-radius:50%;border:none;background:var(--ac-color-text-default, #fff);color:var(--ac-color-bg-default, #000);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:opacity .2s ease}.submitButton:hover{opacity:.85}.dropdown{position:absolute;left:0;right:0;top:100%;margin-top:6px;background:var(--ac-color-background-default, #00002d);border-radius:23px;overflow:hidden;z-index:10;opacity:0;pointer-events:none;transition:opacity .4s cubic-bezier(.4,0,.2,1)}.visible{opacity:1;pointer-events:auto}.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px 18px;padding:18px 24px;max-height:192px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}.grid::-webkit-scrollbar{width:6px}.grid::-webkit-scrollbar-track{background:transparent}.grid::-webkit-scrollbar-thumb{background:#ffffff4d;border-radius:3px}.item{display:flex;align-items:center;font-family:IBM Plex Sans,sans-serif;font-size:21px;line-height:30px;color:var(--ac-color-text-muted, #c1c4cb);white-space:nowrap;opacity:.35;animation:fadeIn .4s cubic-bezier(.4,0,.2,1) forwards}.tappable{cursor:pointer}.tappable:hover{color:var(--ac-color-text-default, #fff)}.nonTappable{cursor:default;opacity:.3}.highlighted{color:var(--ac-color-text-default, #fff);opacity:.5}.tag{font-size:13px;margin-left:6px;opacity:.5}.list{position:relative;z-index:1;pointer-events:auto;display:inline-flex;gap:5px;align-items:center;vertical-align:middle;transform:translateY(-3px)}.pill{display:inline-flex;align-items:center;justify-content:center;height:36px;padding:7px 9px;border:none;border-radius:6px;background:var(--ac-color-background-supportive, #313255);color:var(--ac-color-text-muted, #c1c4cb);font-family:IBM Plex Sans,sans-serif;font-size:21px;line-height:30px;cursor:pointer;white-space:nowrap;animation:fadeIn .4s cubic-bezier(.4,0,.2,1) forwards}.pill:hover{filter:brightness(1.2)}.active{outline:1px solid #5a5b8a}@keyframes fadeIn{0%{opacity:0}}
2
2
  /*# sourceMappingURL=index.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AIAutocomplete.module.css","../src/AIAutocompleteDropdown.module.css","../src/components/SuggestionGrid.module.css","../src/components/SuggestionItem.module.css","../src/components/PillList.module.css"],"sourcesContent":[".container {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.checkmark {\n position: absolute;\n bottom: -130px;\n left: 50%;\n transform: translateX(-50%) translateY(8px) scale(0.8);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n animation: none;\n}\n\n.checkmarkVisible {\n animation: checkmarkFadeInOut 3s ease forwards;\n}\n\n@keyframes checkmarkFadeInOut {\n 0% {\n opacity: 0;\n transform: translateX(-50%) translateY(8px) scale(0.8);\n }\n 10% {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n 80% {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n 100% {\n opacity: 0;\n transform: translateX(-50%) translateY(-8px) scale(0.8);\n }\n}\n\n.checkmarkPath {\n stroke-dasharray: 30;\n stroke-dashoffset: 30;\n}\n\n.checkmarkVisible .checkmarkPath {\n animation: drawCheck 0.4s ease forwards 0.1s;\n}\n\n@keyframes drawCheck {\n to {\n stroke-dashoffset: 0;\n }\n}\n\n.inputWrapper {\n min-height: 60px;\n padding: 24px;\n border: 1px solid var(--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.editorArea {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.sizerContent {\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.sizerText {\n color: transparent;\n}\n\n.placeholderText {\n color: var(--color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.textarea {\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(--color-text-default, #fff);\n caret-color: var(--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.textarea::placeholder {\n color: var(--color-text-muted, #c1c4cb);\n}\n\n.submitButton {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: var(--color-text-default, #fff);\n color: var(--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.submitButton:hover {\n opacity: 0.85;\n}\n",".dropdown {\n position: absolute;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 6px;\n background: var(--color-background-default, #00002d);\n border-radius: 23px;\n overflow: hidden;\n z-index: 10;\n animation: fadeIn 200ms ease forwards;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n",".grid {\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.grid::-webkit-scrollbar {\n width: 6px;\n}\n\n.grid::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.grid::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n",".item {\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(--color-text-muted, #c1c4cb);\n white-space: nowrap;\n opacity: 0.35;\n animation: fadeIn 200ms ease forwards;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n}\n\n.tappable {\n cursor: pointer;\n}\n\n.tappable:hover {\n color: var(--color-text-default, #fff);\n}\n\n.nonTappable {\n cursor: default;\n opacity: 0.3;\n}\n\n.highlighted {\n color: var(--color-text-default, #fff);\n opacity: 0.5;\n}\n\n.tag {\n font-size: 13px;\n margin-left: 6px;\n opacity: 0.5;\n}\n",".list {\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.pill {\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(--color-background-supportive, #313255);\n color: var(--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: fadeIn 200ms ease forwards;\n}\n\n.pill:hover {\n filter: brightness(1.2);\n}\n\n.active {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/AIAutocomplete.module.css","../src/AIAutocompleteDropdown.module.css","../src/components/SuggestionGrid.module.css","../src/components/SuggestionItem.module.css","../src/components/PillList.module.css"],"sourcesContent":[".container {\n position: relative;\n font-family: \"IBM Plex Sans\", sans-serif;\n}\n\n.checkmark {\n position: absolute;\n bottom: -130px;\n left: 50%;\n transform: translateX(-50%) translateY(8px) scale(0.8);\n opacity: 0;\n pointer-events: none;\n z-index: 10;\n animation: none;\n}\n\n.checkmarkVisible {\n animation: checkmarkFadeInOut 3s ease forwards;\n}\n\n@keyframes checkmarkFadeInOut {\n 0% {\n opacity: 0;\n transform: translateX(-50%) translateY(8px) scale(0.8);\n }\n 10% {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n 80% {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n 100% {\n opacity: 0;\n transform: translateX(-50%) translateY(-8px) scale(0.8);\n }\n}\n\n.checkmarkPath {\n stroke-dasharray: 30;\n stroke-dashoffset: 30;\n}\n\n.checkmarkVisible .checkmarkPath {\n animation: drawCheck 0.4s ease forwards 0.1s;\n}\n\n@keyframes drawCheck {\n to {\n stroke-dashoffset: 0;\n }\n}\n\n.inputWrapper {\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.editorArea {\n position: relative;\n flex: 1;\n min-width: 0;\n}\n\n.sizerContent {\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.sizerText {\n color: transparent;\n}\n\n.placeholderText {\n color: var(--ac-color-text-muted, #c1c4cb);\n opacity: 0.7;\n}\n\n.textarea {\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.textarea::placeholder {\n color: var(--ac-color-text-muted, #c1c4cb);\n}\n\n.submitButton {\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.submitButton:hover {\n opacity: 0.85;\n}\n",".dropdown {\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.visible {\n opacity: 1;\n pointer-events: auto;\n}\n",".grid {\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.grid::-webkit-scrollbar {\n width: 6px;\n}\n\n.grid::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.grid::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 3px;\n}\n",".item {\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: fadeIn 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n}\n\n.tappable {\n cursor: pointer;\n}\n\n.tappable:hover {\n color: var(--ac-color-text-default, #fff);\n}\n\n.nonTappable {\n cursor: default;\n opacity: 0.3;\n}\n\n.highlighted {\n color: var(--ac-color-text-default, #fff);\n opacity: 0.5;\n}\n\n.tag {\n font-size: 13px;\n margin-left: 6px;\n opacity: 0.5;\n}\n",".list {\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.pill {\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: fadeIn 400ms cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n.pill:hover {\n filter: brightness(1.2);\n}\n\n.active {\n outline: 1px solid #5a5b8a;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n}\n"],"mappings":"AAAA,CAAC,UACC,SAAU,SACV,YAAa,aAAe,CAAE,UAChC,CAEA,CAAC,UACC,SAAU,SACV,OAAQ,OACR,KAAM,IACN,UAAW,UAAW,MAAM,WAAW,KAAK,MAAM,IAClD,QAAS,EACT,eAAgB,KAChB,QAAS,GACT,UAAW,IACb,CAEA,CAAC,iBACC,UAAW,mBAAmB,GAAG,KAAK,QACxC,CAEA,WAHa,mBAIX,GACE,QAAS,EACT,UAAW,UAAW,MAAM,WAAW,KAAK,MAAM,GACpD,CACA,IACE,QAAS,EACT,UAAW,UAAW,MAAM,WAAW,GAAG,MAAM,EAClD,CACA,IACE,QAAS,EACT,UAAW,UAAW,MAAM,WAAW,GAAG,MAAM,EAClD,CACA,GACE,QAAS,EACT,UAAW,UAAW,MAAM,WAAW,MAAM,MAAM,GACrD,CACF,CAEA,CAAC,cACC,iBAAkB,GAClB,kBAAmB,EACrB,CAEA,CA5BC,iBA4BiB,CALjB,cAMC,UAAW,UAAU,IAAK,KAAK,SAAS,GAC1C,CAEA,WAHa,UAIX,GACE,kBAAmB,CACrB,CACF,CAEA,CAAC,aACC,WAAY,KAvDd,QAwDW,KACT,OAAQ,IAAI,MAAM,IAAI,yBAAyB,EAAE,SAzDnD,cA0DiB,KACf,WAAY,YACZ,SAAU,OACV,QAAS,KACT,YAAa,OACb,IAAK,IACP,CAEA,CAAC,WACC,SAAU,SACV,KAAM,EACN,UAAW,CACb,CAEA,CAAC,aACC,SAAU,SACV,QAAS,EACT,eAAgB,KAChB,WAAY,KACZ,YAAa,SACb,WAAY,WACZ,YAAa,QACb,UAAW,KACX,YAAa,IACf,CAEA,CAAC,UACC,MAAO,WACT,CAEA,CAAC,gBACC,MAAO,IAAI,qBAAqB,EAAE,SAClC,QAAS,EACX,CAEA,CAAC,SACC,SAAU,SACV,IAAK,EACL,KAAM,EACN,MAAO,KACP,OAAQ,KAlGV,QAmGW,EACT,OAAQ,KACR,WAAY,YACZ,MAAO,IAAI,uBAAuB,EAAE,MACpC,YAAa,IAAI,uBAAuB,EAAE,MAC1C,YAAa,QACb,UAAW,KACX,YAAa,KACb,YAAa,SACb,WAAY,WACZ,QAAS,KACT,OAAQ,KACR,SAAU,MACZ,CAEA,CArBC,QAqBQ,cACP,MAAO,IAAI,qBAAqB,EAAE,QACpC,CAEA,CAAC,aACC,YAAa,EACb,MAAO,KACP,OAAQ,KAzHV,cA0HiB,IACf,OAAQ,KACR,WAAY,IAAI,uBAAuB,EAAE,MACzC,MAAO,IAAI,qBAAqB,EAAE,MAClC,OAAQ,QACR,QAAS,KACT,YAAa,OACb,gBAAiB,OAjInB,QAkIW,EACT,WAAY,QAAQ,IAAK,IAC3B,CAEA,CAhBC,YAgBY,OACX,QAAS,GACX,CCxIA,CAAC,SACC,SAAU,SACV,KAAM,EACN,MAAO,EACP,IAAK,KACL,WAAY,IACZ,WAAY,IAAI,6BAA6B,EAAE,SANjD,cAOiB,KACf,SAAU,OACV,QAAS,GACT,QAAS,EACT,eAAgB,KAChB,WAAY,QAAQ,IAAM,aAAa,EAAG,CAAE,CAAC,CAAE,EAAG,CAAE,EACtD,CAEA,CAAC,QACC,QAAS,EACT,eAAgB,IAClB,CClBA,CAAC,KACC,QAAS,KACT,sBAAuB,IAAI,IAC3B,IAAK,KAAK,KAHZ,QAIW,KAAK,KACd,WAAY,MACZ,WAAY,KACZ,gBAAiB,KACjB,gBAAiB,KAAK,GAAG,CAAE,GAAG,CAAE,GAAG,CAAE,IAAK,WAC5C,CAEA,CAXC,IAWI,oBACH,MAAO,GACT,CAEA,CAfC,IAeI,0BACH,WAAY,WACd,CAEA,CAnBC,IAmBI,0BACH,WAAY,UApBd,cAqBiB,GACjB,CCtBA,CAAC,KACC,QAAS,KACT,YAAa,OACb,YAAa,aAAe,CAAE,WAC9B,UAAW,KACX,YAAa,KACb,MAAO,IAAI,qBAAqB,EAAE,SAClC,YAAa,OACb,QAAS,IACT,UAAW,OAAO,IAAM,aAAa,EAAG,CAAE,CAAC,CAAE,EAAG,CAAE,GAAG,QACvD,CAQA,CAAC,SACC,OAAQ,OACV,CAEA,CAJC,QAIQ,OACP,MAAO,IAAI,uBAAuB,EAAE,KACtC,CAEA,CAAC,YACC,OAAQ,QACR,QAAS,EACX,CAEA,CAAC,YACC,MAAO,IAAI,uBAAuB,EAAE,MACpC,QAAS,EACX,CAEA,CAAC,IACC,UAAW,KACX,YAAa,IACb,QAAS,EACX,CCxCA,CAAC,KACC,SAAU,SACV,QAAS,EACT,eAAgB,KAChB,QAAS,YACT,IAAK,IACL,YAAa,OACb,eAAgB,OAChB,UAAW,WAAW,KACxB,CAEA,CAAC,KACC,QAAS,YACT,YAAa,OACb,gBAAiB,OACjB,OAAQ,KAfV,QAgBW,IAAI,IACb,OAAQ,KAjBV,cAkBiB,IACf,WAAY,IAAI,gCAAgC,EAAE,SAClD,MAAO,IAAI,qBAAqB,EAAE,SAClC,YAAa,aAAe,CAAE,WAC9B,UAAW,KACX,YAAa,KACb,OAAQ,QACR,YAAa,OACb,UAAW,OAAO,IAAM,aAAa,EAAG,CAAE,CAAC,CAAE,EAAG,CAAE,GAAG,QACvD,CAEA,CAlBC,IAkBI,OACH,OAAQ,WAAW,IACrB,CAEA,CAAC,OACC,QAAS,IAAI,MAAM,OACrB,CAEA,WAXa,OAYX,GACE,QAAS,CACX,CACF","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as react from 'react';
2
2
  import { ChangeEvent, KeyboardEvent } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
 
4
5
  type TaskKind = "automation" | "email" | "insight";
5
6
  interface CompletedParam {
@@ -22,37 +23,8 @@ interface Suggestion {
22
23
  required: boolean;
23
24
  options: SuggestionOption[];
24
25
  }
25
- interface InputItem {
26
- type: string;
27
- text: string;
28
- state: "completed" | "in_progress";
29
- }
30
- interface AutocompleteRequest {
31
- data: {
32
- raw_query: string;
33
- completed_params: CompletedParam[];
34
- contact_account_count?: number;
35
- };
36
- meta: {
37
- request_id: string;
38
- request_at: string;
39
- language: string;
40
- client_version: string;
41
- };
42
- }
43
- interface AutocompleteResponse {
44
- data: {
45
- raw_query: string;
46
- input: InputItem[];
47
- suggestions: Suggestion[];
48
- is_ready?: boolean;
49
- };
50
- meta: {
51
- request_id: string;
52
- request_at: string;
53
- };
54
- }
55
26
  interface CompletedParamState extends CompletedParam {
27
+ id: string;
56
28
  text: string;
57
29
  suggestionType: string;
58
30
  suggestionPlaceholder: string;
@@ -67,13 +39,29 @@ type Segment = {
67
39
  value: string;
68
40
  param: CompletedParamState;
69
41
  };
42
+ interface AIAutocompleteHandle {
43
+ focus: () => void;
44
+ reset: () => void;
45
+ }
46
+ interface APIConfig {
47
+ apiKey?: string;
48
+ authScheme?: "Bearer" | "Basic";
49
+ headers?: Record<string, string>;
50
+ }
70
51
  type OptionOverrides = Record<string, (query: string) => SuggestionOption[]>;
71
52
  interface AIAutocompleteProps {
72
53
  onSubmit: (result: AutocompleteResult) => void;
54
+ onError?: (error: Error) => void;
73
55
  optionOverrides?: OptionOverrides;
74
56
  maskCompletedText?: boolean;
75
57
  placeholder?: string;
76
58
  className?: string;
59
+ apiConfig?: APIConfig;
60
+ columns?: number;
61
+ value?: string;
62
+ completedParams?: CompletedParamState[];
63
+ onChange?: (value: string) => void;
64
+ onParamsChange?: (params: CompletedParamState[]) => void;
77
65
  }
78
66
  interface AutocompleteResult {
79
67
  query: string;
@@ -81,15 +69,21 @@ interface AutocompleteResult {
81
69
  completed_params: CompletedParam[];
82
70
  }
83
71
  interface UseAIAutocompleteOptions {
84
- onSubmit?: () => void;
72
+ onSubmit?: (result: AutocompleteResult) => void;
73
+ onError?: (error: Error) => void;
85
74
  optionOverrides?: OptionOverrides;
86
75
  maskCompletedText?: boolean;
87
76
  placeholder?: string;
77
+ apiConfig?: APIConfig;
78
+ columns?: number;
79
+ value?: string;
80
+ completedParams?: CompletedParamState[];
81
+ onChange?: (value: string) => void;
82
+ onParamsChange?: (params: CompletedParamState[]) => void;
88
83
  }
89
84
  interface UseAIAutocompleteReturn {
90
85
  completedParams: CompletedParamState[];
91
86
  suggestionPills: Suggestion[];
92
- activePillIndex: number;
93
87
  setActivePill: (index: number) => void;
94
88
  removeLastParam: () => void;
95
89
  reEditParam: (param: CompletedParamState) => void;
@@ -117,15 +111,16 @@ interface AIAutocompleteDropdownProps {
117
111
  suggestions: Suggestion[];
118
112
  activeIndex: number;
119
113
  onSelect: (option: SuggestionOption) => void;
114
+ onHighlight: (index: number) => void;
120
115
  isOpen: boolean;
121
116
  id: string;
122
117
  className?: string;
123
118
  }
124
119
 
125
- declare function AIAutocomplete({ onSubmit, optionOverrides, maskCompletedText, placeholder, className, }: AIAutocompleteProps): react_jsx_runtime.JSX.Element;
120
+ declare const AIAutocomplete: react.ForwardRefExoticComponent<AIAutocompleteProps & react.RefAttributes<AIAutocompleteHandle>>;
126
121
 
127
- declare function AIAutocompleteDropdown({ suggestions, activeIndex, onSelect, isOpen, id, className, }: AIAutocompleteDropdownProps): react_jsx_runtime.JSX.Element | null;
122
+ declare function AIAutocompleteDropdown({ suggestions, activeIndex, onSelect, onHighlight, isOpen, id, className, }: AIAutocompleteDropdownProps): react_jsx_runtime.JSX.Element;
128
123
 
129
- declare function useAIAutocomplete({ onSubmit, optionOverrides, maskCompletedText, placeholder: customPlaceholder, }: UseAIAutocompleteOptions): UseAIAutocompleteReturn;
124
+ declare function useAIAutocomplete({ onSubmit, onError, optionOverrides, maskCompletedText, placeholder: customPlaceholder, apiConfig, columns, value: controlledValue, completedParams: controlledParams, onChange: onChangeProp, onParamsChange, }: UseAIAutocompleteOptions): UseAIAutocompleteReturn;
130
125
 
131
- export { AIAutocomplete, AIAutocompleteDropdown, type AIAutocompleteDropdownProps, type AIAutocompleteProps, type AutocompleteRequest, type AutocompleteResponse, type AutocompleteResult, type CompletedParam, type CompletedParamState, type InputItem, type OptionOverrides, type Segment, type Suggestion, type SuggestionOption, type TaskKind, type UseAIAutocompleteOptions, type UseAIAutocompleteReturn, useAIAutocomplete };
126
+ export { AIAutocomplete, AIAutocompleteDropdown, type AIAutocompleteDropdownProps, type AIAutocompleteHandle, type AIAutocompleteProps, type APIConfig, type AutocompleteResult, type CompletedParam, type CompletedParamState, type OptionOverrides, type Segment, type Suggestion, type SuggestionOption, type TaskKind, type UseAIAutocompleteOptions, type UseAIAutocompleteReturn, useAIAutocomplete };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as react from 'react';
2
2
  import { ChangeEvent, KeyboardEvent } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
4
 
4
5
  type TaskKind = "automation" | "email" | "insight";
5
6
  interface CompletedParam {
@@ -22,37 +23,8 @@ interface Suggestion {
22
23
  required: boolean;
23
24
  options: SuggestionOption[];
24
25
  }
25
- interface InputItem {
26
- type: string;
27
- text: string;
28
- state: "completed" | "in_progress";
29
- }
30
- interface AutocompleteRequest {
31
- data: {
32
- raw_query: string;
33
- completed_params: CompletedParam[];
34
- contact_account_count?: number;
35
- };
36
- meta: {
37
- request_id: string;
38
- request_at: string;
39
- language: string;
40
- client_version: string;
41
- };
42
- }
43
- interface AutocompleteResponse {
44
- data: {
45
- raw_query: string;
46
- input: InputItem[];
47
- suggestions: Suggestion[];
48
- is_ready?: boolean;
49
- };
50
- meta: {
51
- request_id: string;
52
- request_at: string;
53
- };
54
- }
55
26
  interface CompletedParamState extends CompletedParam {
27
+ id: string;
56
28
  text: string;
57
29
  suggestionType: string;
58
30
  suggestionPlaceholder: string;
@@ -67,13 +39,29 @@ type Segment = {
67
39
  value: string;
68
40
  param: CompletedParamState;
69
41
  };
42
+ interface AIAutocompleteHandle {
43
+ focus: () => void;
44
+ reset: () => void;
45
+ }
46
+ interface APIConfig {
47
+ apiKey?: string;
48
+ authScheme?: "Bearer" | "Basic";
49
+ headers?: Record<string, string>;
50
+ }
70
51
  type OptionOverrides = Record<string, (query: string) => SuggestionOption[]>;
71
52
  interface AIAutocompleteProps {
72
53
  onSubmit: (result: AutocompleteResult) => void;
54
+ onError?: (error: Error) => void;
73
55
  optionOverrides?: OptionOverrides;
74
56
  maskCompletedText?: boolean;
75
57
  placeholder?: string;
76
58
  className?: string;
59
+ apiConfig?: APIConfig;
60
+ columns?: number;
61
+ value?: string;
62
+ completedParams?: CompletedParamState[];
63
+ onChange?: (value: string) => void;
64
+ onParamsChange?: (params: CompletedParamState[]) => void;
77
65
  }
78
66
  interface AutocompleteResult {
79
67
  query: string;
@@ -81,15 +69,21 @@ interface AutocompleteResult {
81
69
  completed_params: CompletedParam[];
82
70
  }
83
71
  interface UseAIAutocompleteOptions {
84
- onSubmit?: () => void;
72
+ onSubmit?: (result: AutocompleteResult) => void;
73
+ onError?: (error: Error) => void;
85
74
  optionOverrides?: OptionOverrides;
86
75
  maskCompletedText?: boolean;
87
76
  placeholder?: string;
77
+ apiConfig?: APIConfig;
78
+ columns?: number;
79
+ value?: string;
80
+ completedParams?: CompletedParamState[];
81
+ onChange?: (value: string) => void;
82
+ onParamsChange?: (params: CompletedParamState[]) => void;
88
83
  }
89
84
  interface UseAIAutocompleteReturn {
90
85
  completedParams: CompletedParamState[];
91
86
  suggestionPills: Suggestion[];
92
- activePillIndex: number;
93
87
  setActivePill: (index: number) => void;
94
88
  removeLastParam: () => void;
95
89
  reEditParam: (param: CompletedParamState) => void;
@@ -117,15 +111,16 @@ interface AIAutocompleteDropdownProps {
117
111
  suggestions: Suggestion[];
118
112
  activeIndex: number;
119
113
  onSelect: (option: SuggestionOption) => void;
114
+ onHighlight: (index: number) => void;
120
115
  isOpen: boolean;
121
116
  id: string;
122
117
  className?: string;
123
118
  }
124
119
 
125
- declare function AIAutocomplete({ onSubmit, optionOverrides, maskCompletedText, placeholder, className, }: AIAutocompleteProps): react_jsx_runtime.JSX.Element;
120
+ declare const AIAutocomplete: react.ForwardRefExoticComponent<AIAutocompleteProps & react.RefAttributes<AIAutocompleteHandle>>;
126
121
 
127
- declare function AIAutocompleteDropdown({ suggestions, activeIndex, onSelect, isOpen, id, className, }: AIAutocompleteDropdownProps): react_jsx_runtime.JSX.Element | null;
122
+ declare function AIAutocompleteDropdown({ suggestions, activeIndex, onSelect, onHighlight, isOpen, id, className, }: AIAutocompleteDropdownProps): react_jsx_runtime.JSX.Element;
128
123
 
129
- declare function useAIAutocomplete({ onSubmit, optionOverrides, maskCompletedText, placeholder: customPlaceholder, }: UseAIAutocompleteOptions): UseAIAutocompleteReturn;
124
+ declare function useAIAutocomplete({ onSubmit, onError, optionOverrides, maskCompletedText, placeholder: customPlaceholder, apiConfig, columns, value: controlledValue, completedParams: controlledParams, onChange: onChangeProp, onParamsChange, }: UseAIAutocompleteOptions): UseAIAutocompleteReturn;
130
125
 
131
- export { AIAutocomplete, AIAutocompleteDropdown, type AIAutocompleteDropdownProps, type AIAutocompleteProps, type AutocompleteRequest, type AutocompleteResponse, type AutocompleteResult, type CompletedParam, type CompletedParamState, type InputItem, type OptionOverrides, type Segment, type Suggestion, type SuggestionOption, type TaskKind, type UseAIAutocompleteOptions, type UseAIAutocompleteReturn, useAIAutocomplete };
126
+ export { AIAutocomplete, AIAutocompleteDropdown, type AIAutocompleteDropdownProps, type AIAutocompleteHandle, type AIAutocompleteProps, type APIConfig, type AutocompleteResult, type CompletedParam, type CompletedParamState, type OptionOverrides, type Segment, type Suggestion, type SuggestionOption, type TaskKind, type UseAIAutocompleteOptions, type UseAIAutocompleteReturn, useAIAutocomplete };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var de=Object.defineProperty;var $e=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var Ue=Object.prototype.hasOwnProperty;var qe=(e,i)=>{for(var o in i)de(e,o,{get:i[o],enumerable:!0})},ze=(e,i,o,p)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of Be(i))!Ue.call(e,t)&&t!==o&&de(e,t,{get:()=>i[t],enumerable:!(p=$e(i,t))||p.enumerable});return e};var Fe=e=>ze(de({},"__esModule",{value:!0}),e);var it={};qe(it,{AIAutocomplete:()=>Te,AIAutocompleteDropdown:()=>se,useAIAutocomplete:()=>le});module.exports=Fe(it);var T=require("react");var A={};var ve={};var Se={};var Q={};var re=require("react/jsx-runtime");function Pe({option:e,isHighlighted:i,onSelect:o,onHighlight:p,id:t}){let l=[Q.item,i?Q.highlighted:"",e.is_tappable?Q.tappable:Q.nonTappable].filter(Boolean).join(" ");return(0,re.jsxs)("div",{id:t,role:"option","aria-selected":i,className:l,tabIndex:e.is_tappable?0:-1,onClick:()=>e.is_tappable&&o(e),onKeyDown:r=>{e.is_tappable&&(r.key==="Enter"||r.key===" ")&&(r.preventDefault(),o(e))},onMouseEnter:p,children:[e.icon?`${e.icon} ${e.text}`:e.text,e.tag&&(0,re.jsx)("span",{className:Q.tag,children:e.tag})]})}var fe=require("react/jsx-runtime");function ke({options:e,activeIndex:i,onSelect:o,onHighlight:p,listboxId:t}){return(0,fe.jsx)("div",{className:Se.grid,children:e.map((l,r)=>(0,fe.jsx)(Pe,{option:l,isHighlighted:r===i,onSelect:o,onHighlight:()=>p(r),id:`${t}-option-${r}`},l.text))})}var me=require("react/jsx-runtime");function se({suggestions:e,activeIndex:i,onSelect:o,isOpen:p,id:t,className:l}){if(!p||e.length===0)return null;let r=e[0];return r.options.length===0?null:(0,me.jsx)("div",{id:t,role:"listbox",className:`${ve.dropdown} ${l??""}`,onMouseDown:b=>b.preventDefault(),children:(0,me.jsx)(ke,{options:r.options,activeIndex:i,onSelect:o,onHighlight:()=>{},listboxId:t})})}var ae={};var ge=require("react/jsx-runtime");function Ge(e){return e===0?.4:e===1?.3:.15}function we({pills:e,activePillIndex:i,onSelectPill:o}){return(0,ge.jsx)("span",{className:ae.list,children:e.map((p,t)=>(0,ge.jsx)("button",{type:"button",className:`${ae.pill} ${t===i?ae.active:""}`,style:{opacity:Ge(t)},onClick:()=>o(t),children:p.text},`${p.type}-${p.text}`))})}var c=require("react");var Ye="0.1.0",Ve=process?.env.MAGICX_API_ENDPOINT||"/api/suggest",Ae=!1;function je(){let e=process?.env.MAGICX_AI_AUTOCOMPLETE_API_KEY||"";return!e&&!Ae&&(Ae=!0,console.warn("[AIAutocomplete] No API key set (MAGICX_AI_AUTOCOMPLETE_API_KEY). Requests will be sent without an Authorization header.")),e}function Je(){return process?.env.MAGICX_AUTH_SCHEME==="Basic"?"Basic":"Bearer"}function Ze(){return crypto.randomUUID()}function et(e,i){return{placeholder:e.placeholder,type:e.type,...i&&{text:e.text},kind:e.kind}}async function Ie(e,i,o){let p=je(),t=Je(),l=!o?.maskCompletedText,r=i.find(x=>x.type==="contact"&&x.metadata?.contact_account_count)?.metadata?.contact_account_count,b=typeof r=="number"?r:void 0,v={data:{raw_query:e,completed_params:i.map(x=>et(x,l)),...b!=null&&{contact_account_count:b}},meta:{request_id:Ze(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:Ye}},h={"Content-Type":"application/json","X-App-Identifier":process?.env.MAGICX_APP_IDENTIFIER||"active-campaign-demo"};p&&(h.Authorization=t==="Basic"?`Basic ${btoa(p)}`:`Bearer ${p}`);let f=await fetch(Ve,{method:"POST",headers:h,body:JSON.stringify(v),signal:o?.signal});if(!f.ok)throw new Error(`API error: ${f.status} ${f.statusText}`);return f.json()}function ie(e,i){let o=e,p={},t=[];for(let l of i){let r=(p[l.type]??0)+1;p[l.type]=r;let v=`{{${l.type.toUpperCase().replace(/\s+/g,"_")}_${r}}}`,h=o.indexOf(l.text);h!==-1&&(o=o.slice(0,h)+v+o.slice(h+l.text.length)),t.push({...l,placeholder:v})}return{rawQuery:o,completedParams:t}}var tt=100,ot=300,nt=2;function Ce(e,i){let o=i.trimStart();if(!o)return e;let p=o.toLowerCase();return e.filter(t=>!t.is_tappable||t.text.toLowerCase().includes(p))}function he(e,i){let o=i.trim();if(!o)return null;let p=o.toLowerCase();return e.find(t=>t.is_tappable&&t.text.toLowerCase()===p)??null}function rt(e,i){let o=[],p=0;for(let l of i){let r=e.indexOf(l.text,p);r!==-1&&(r>p&&o.push({type:"text",value:e.slice(p,r)}),o.push({type:"completed",value:l.text,param:l}),p=r+l.text.length)}let t=e.slice(p);return t&&o.push({type:"text",value:t}),o}function st(e,i){let o=[],p=[],t=0;for(let l of i){let r=e.indexOf(l.text,t);r===-1?p.push(l):(o.push(l),t=r+l.text.length)}return{valid:o,invalid:p}}function at(e,i){return i?e.map(o=>{let p=i[o.type];if(!p)return o;let t=p("");if(t.length===0)return o;let l=new Set(t.map(b=>b.text)),r=(o.options??[]).filter(b=>!l.has(b.text));return{...o,options:[...t,...r]}}):e}function le({onSubmit:e,optionOverrides:i,maskCompletedText:o,placeholder:p}){let[t,l]=(0,c.useState)([]),[r,b]=(0,c.useState)(""),[v,h]=(0,c.useState)([]),[f,x]=(0,c.useState)(-1),[G,$]=(0,c.useState)(!1),[_,Y]=(0,c.useState)(null),[V,j]=(0,c.useState)(!1),E=(0,c.useRef)(0),B=(0,c.useRef)(null),U=(0,c.useRef)(""),q=(0,c.useRef)(e);q.current=e;let J=(0,c.useRef)(i);J.current=i;let Z=(0,c.useRef)(o);Z.current=o;let I=(0,c.useRef)(r);I.current=r;let D=(0,c.useRef)(v);D.current=v;let P=(0,c.useRef)(0),H=(0,c.useRef)(!1),ce=(0,c.useRef)(!1),pe=(0,c.useId)(),N=(0,c.useCallback)(async(s,d)=>{B.current?.abort();let n=new AbortController;B.current=n;let a=++E.current;D.current.some(u=>u.type!=="placeholder")||$(!0),Y(null);try{let u=await Ie(s,d,{maskCompletedText:Z.current,signal:n.signal});if(a!==E.current)return;let S=at(u.data.suggestions??[],J.current);j(u.data.is_ready??!1),U.current=s;let k=u.data.input??[],O=k[k.length-1],F=I.current;if(O?.state==="in_progress"){let R=F.lastIndexOf(O.text);R!==-1?P.current=R:P.current=F.length}else P.current=F.length;let C=S.filter(R=>R.type!=="placeholder")[0];if(C){let R=F.slice(P.current),K=he(C.options,R);K&&(l(L=>[...L,{placeholder:"",type:C.type,text:K.text,kind:K.kind,suggestionType:C.type,suggestionPlaceholder:C.text,options:C.options,metadata:K.metadata}]),S=S.filter(L=>L!==C))}h(S),$(!1),x(-1)}catch(u){a===E.current&&(Y(u instanceof Error?u:new Error(String(u))),$(!1))}},[]);(0,c.useEffect)(()=>(N("",[]),()=>{B.current?.abort()}),[N]);let _e=(0,c.useMemo)(()=>rt(r,t),[r,t]);P.current=Math.min(P.current,r.length);let ee=r.slice(P.current);console.log(`[filter] base=${P.current} query="${ee}" text="${r}"`);let z=v.filter(s=>s.type==="placeholder").map(s=>s.text).join(" ")||p||"",te=v.filter(s=>s.type!=="placeholder"),m=te[0],xe=m?i?.[m.type]:void 0,w=m?xe&&ee.trim()?xe(ee.trim()):Ce(m.options??[],ee):[],ue=z.length>0,oe=!G&&w.length>0&&(!!r||H.current||!ue),X=(0,c.useCallback)(s=>{if(!m)return;let d={placeholder:"",type:m.type,text:s.text,kind:s.kind,suggestionType:m.type,suggestionPlaceholder:m.text,options:m.options,metadata:s.metadata},n=P.current,a=r.slice(0,n);if(a.length>0&&!a.endsWith(" ")){let k=a.split(/\s+/).pop()??"";k&&s.text.toLowerCase().startsWith(k.toLowerCase())&&(a=a.slice(0,a.length-k.length))}let g=a.length>0&&a[a.length-1]!==" ",u=a+(g?" ":"")+s.text+" ";b(u),P.current=u.length,l(k=>[...k,d]),h(k=>k.filter(O=>O!==m)),H.current=!1,x(-1),te.length-1>0&&(ce.current=!0)},[m,te,r]),Oe=(0,c.useCallback)(s=>{let d=s.target.value,n=d.length>0?d[0].toUpperCase()+d.slice(1):d;b(n),H.current=!1,x(-1);let{valid:a,invalid:g}=st(n,t);if(g.length>0){l(a);for(let u of g)h(S=>[{type:u.suggestionType,text:u.suggestionPlaceholder,required:!0,options:u.options},...S])}if(m&&g.length===0){let u=n.slice(P.current),S=he(m.options,u);S&&(l(k=>[...k,{placeholder:"",type:m.type,text:S.text,kind:S.kind,suggestionType:m.type,suggestionPlaceholder:m.text,options:m.options,metadata:S.metadata}]),h(k=>k.filter(O=>O!==m)))}},[t,m]),W=(0,c.useRef)(null),M=(0,c.useRef)(null),ye=(0,c.useRef)(!0);(0,c.useEffect)(()=>{W.current&&clearTimeout(W.current),M.current&&clearTimeout(M.current);let s=d=>{if(ce.current)return ce.current=!1,!1;if(!r&&t.length===0)return ye.current?(N("",[]),!0):(ye.current=!0,!1);let n=r.slice(P.current),u=D.current.filter(L=>L.type!=="placeholder")[0],k=(u?Ce(u.options,n):[]).filter(L=>L.is_tappable),O=u?he(u.options,n)!==null:!1,F=n.trim().length>0;if(k.length>0&&!O&&F)return!1;let{rawQuery:ne,completedParams:C}=ie(r,t),R=ne.length<U.current.length,K=Math.abs(ne.length-U.current.length);return R||K>=d?(N(ne,C),!0):!1};return W.current=setTimeout(()=>{s(nt)&&M.current&&clearTimeout(M.current)},tt),M.current=setTimeout(()=>s(1),ot),()=>{W.current&&clearTimeout(W.current),M.current&&clearTimeout(M.current)}},[r,t,N]);let be=(0,c.useCallback)(()=>{let d=w.map((g,u)=>g.is_tappable?u:-1).filter(g=>g!==-1),n=d.filter(g=>g%2===0),a=d.filter(g=>g%2===1);return[...n,...a]},[w]),Re=(0,c.useCallback)(s=>{let d=be();switch(s.key){case"ArrowDown":{if(s.preventDefault(),d.length===0)return;let n=d.indexOf(f),a=n<d.length-1?n+1:0;x(d[a]);break}case"ArrowUp":{if(s.preventDefault(),d.length===0)return;let n=d.indexOf(f),a=n>0?n-1:d.length-1;x(d[a]);break}case"ArrowRight":{if(f<0)break;if(f%2===0){let a=f+1;a<w.length&&w[a]?.is_tappable&&(s.preventDefault(),x(a))}break}case"ArrowLeft":{if(f<0)break;if(f%2===1){let a=f-1;a>=0&&w[a]?.is_tappable&&(s.preventDefault(),x(a))}break}case"Enter":{s.preventDefault(),f>=0&&w[f]?.is_tappable?X(w[f]):q.current&&q.current();break}case"Tab":{if(f>=0&&w[f]?.is_tappable)s.preventDefault(),X(w[f]);else if(oe){let n=w.find(a=>a.is_tappable);n&&(s.preventDefault(),X(n))}else if(!r&&ue){s.preventDefault();let n=v.find(a=>a.type==="placeholder");b(z),P.current=z.length,n&&(l(a=>[...a,{placeholder:"",type:n.type,text:z,kind:null,suggestionType:n.type,suggestionPlaceholder:n.text,options:n.options}]),h(a=>a.filter(g=>g!==n)))}break}case"Escape":x(-1);break}},[f,w,ue,oe,z,X,v,be,r]),Ee=(0,c.useCallback)(s=>{let d=v.filter(u=>u.type!=="placeholder");if(s<0||s>=d.length)return;let n=d[s],a=d.filter((u,S)=>S!==s),g=v.filter(u=>u.type==="placeholder");h([...g,n,...a]),H.current=!0,x(-1)},[v]),De=(0,c.useCallback)(()=>{if(t.length===0)return;let s=t[t.length-1],d={type:s.suggestionType,text:s.suggestionPlaceholder,required:!0,options:s.options};l(n=>n.slice(0,-1)),h(n=>[d,...n]),x(-1)},[t]),Ne=(0,c.useCallback)(s=>{let d={type:s.suggestionType,text:s.suggestionPlaceholder,required:!0,options:s.options};b(n=>{let a=n.indexOf(s.text);if(a===-1)return n;let g=n.slice(0,a),u=n.slice(a+s.text.length),S=(g+u).replace(/ {2,}/g," ");return P.current=Math.min(P.current,S.length),S}),l(n=>n.filter(a=>a!==s)),h(n=>[d,...n]),x(-1),H.current=!0},[]),Me=(0,c.useCallback)(()=>{b(""),l([]),h([]),x(-1),j(!1),P.current=0,U.current="",N("",[])},[N]),Le=f>=0?`${pe}-option-${f}`:void 0;return{completedParams:t,suggestionPills:te,activePillIndex:0,setActivePill:Ee,removeLastParam:De,reEditParam:Ne,segments:_e,suggestions:v,activeIndex:f,isReady:V,isLoading:G,error:_,inputProps:{value:r,placeholder:z||void 0,onChange:Oe,onKeyDown:Re,role:"combobox","aria-expanded":oe,"aria-activedescendant":Le,"aria-autocomplete":"list","aria-controls":pe},reset:Me,dropdownProps:{suggestions:m?[{...m,options:w}]:[],activeIndex:f,onSelect:X,isOpen:oe,id:pe}}}var y=require("react/jsx-runtime");function Te({onSubmit:e,optionOverrides:i,maskCompletedText:o,placeholder:p,className:t}){let l=(0,T.useRef)(null),[r,b]=(0,T.useState)(!1),v=(0,T.useRef)(()=>{});(0,T.useEffect)(()=>{l.current?.focus()},[]);let{completedParams:h,suggestionPills:f,activePillIndex:x,setActivePill:G,segments:$,inputProps:_,dropdownProps:Y,reset:V}=le({onSubmit:()=>v.current(),optionOverrides:i,maskCompletedText:o,placeholder:p}),j=()=>{l.current?.focus()},E=!!_.value||h.length>0,B=(0,T.useCallback)(()=>{if(!E)return;let{rawQuery:I,completedParams:D}=ie(_.value,h);e({query:_.value.trim(),raw_query:I,completed_params:D}),V(),b(!0),setTimeout(()=>b(!1),3e3)},[E,_.value,h,e,V]);v.current=B;let{onChange:U,placeholder:q,...J}=_,Z=!_.value;return(0,y.jsxs)("div",{className:`${A.container} ${t??""}`,children:[(0,y.jsx)("div",{className:`${A.checkmark} ${r?A.checkmarkVisible:""}`,children:(0,y.jsxs)("svg",{width:"72",height:"72",viewBox:"0 0 24 24",fill:"none",role:"img","aria-label":"Success",children:[(0,y.jsx)("circle",{cx:"12",cy:"12",r:"12",fill:"#34C759"}),(0,y.jsx)("path",{d:"M7 12.5l3.5 3.5L17 9",stroke:"#000",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",className:A.checkmarkPath})]})}),(0,y.jsx)(se,{...Y}),(0,y.jsxs)("div",{className:A.inputWrapper,onClick:j,children:[(0,y.jsxs)("div",{className:A.editorArea,children:[(0,y.jsxs)("div",{className:A.sizerContent,"aria-hidden":"true",children:[Z&&q?(0,y.jsxs)("span",{className:A.placeholderText,children:[q," "]}):(0,y.jsxs)("span",{className:A.sizerText,children:[$.map((I,D)=>(0,y.jsx)("span",{children:I.value},`${D}-${I.type}`)),$.length===0&&"\xA0"]})," ",(0,y.jsx)(we,{pills:f,activePillIndex:x,onSelectPill:G})]}),(0,y.jsx)("textarea",{ref:l,className:A.textarea,rows:1,onChange:U,...J})]}),(0,y.jsx)("button",{type:"button",className:A.submitButton,disabled:!E,onClick:I=>{I.stopPropagation(),B()},"aria-label":"Submit",children:(0,y.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",role:"img","aria-label":"Submit",children:(0,y.jsx)("path",{d:"M9 14V4M9 4L4 9M9 4L14 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})}0&&(module.exports={AIAutocomplete,AIAutocompleteDropdown,useAIAutocomplete});
1
+ "use strict";var be=Object.defineProperty;var Je=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(e,o)=>{for(var t in o)be(e,t,{get:o[t],enumerable:!0})},ot=(e,o,t,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of Ze(o))!et.call(e,n)&&n!==t&&be(e,n,{get:()=>o[n],enumerable:!(r=Je(o,n))||r.enumerable});return e};var nt=e=>ot(be({},"__esModule",{value:!0}),e);var St={};tt(St,{AIAutocomplete:()=>ze,AIAutocompleteDropdown:()=>re,useAIAutocomplete:()=>ce});module.exports=nt(St);var D=require("react");var j={};var ye={};var Re={};var W={};var ne=require("react/jsx-runtime");function _e({option:e,isHighlighted:o,onSelect:t,onHighlight:r,id:n}){let a=[W.item,o?W.highlighted:"",e.is_tappable?W.tappable:W.nonTappable].filter(Boolean).join(" ");return(0,ne.jsxs)("div",{id:n,role:"option","aria-selected":o,className:a,tabIndex:e.is_tappable?0:-1,onClick:()=>e.is_tappable&&t(e),onKeyDown:i=>{e.is_tappable&&(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),t(e))},onMouseEnter:r,children:[e.icon?`${e.icon} ${e.text}`:e.text,e.tag&&(0,ne.jsx)("span",{className:W.tag,children:e.tag})]})}var Se=require("react/jsx-runtime");function Te({options:e,activeIndex:o,onSelect:t,onHighlight:r,listboxId:n}){return(0,Se.jsx)("div",{className:Re.grid,children:e.map((a,i)=>(0,Se.jsx)(_e,{option:a,isHighlighted:i===o,onSelect:t,onHighlight:()=>r(i),id:`${n}-option-${i}`},a.text))})}var xe=require("react/jsx-runtime");function re({suggestions:e,activeIndex:o,onSelect:t,onHighlight:r,isOpen:n,id:a,className:i}){let l=e[0],d=n&&l&&l.options.length>0;return(0,xe.jsx)("div",{id:a,role:"listbox",className:`${ye.dropdown} ${d?ye.visible:""} ${i??""}`,onMouseDown:g=>g.preventDefault(),children:l&&l.options.length>0&&(0,xe.jsx)(Te,{options:l.options,activeIndex:o,onSelect:t,onHighlight:r,listboxId:a})})}var ae={};var Pe=require("react/jsx-runtime");function lt(e){return e===0?.4:e===1?.3:.15}function Ee({pills:e,activePillIndex:o,onSelectPill:t}){return(0,Pe.jsx)("span",{className:ae.list,children:e.map((r,n)=>(0,Pe.jsx)("button",{type:"button",className:`${ae.pill} ${n===o?ae.active:""}`,style:{opacity:lt(n)},onClick:()=>t(n),children:r.text},`${r.type}-${r.text}`))})}var u=require("react");function se(e,o){let t=o.trimStart();if(!t)return e;let r=t.toLowerCase();return e.filter(n=>!n.is_tappable||n.text.toLowerCase().includes(r))}function Z(e,o){let t=o.trim();if(!t)return null;let r=t.toLowerCase();return e.find(n=>n.is_tappable&&n.text.toLowerCase()===r)??null}function Me(e,o){let t=[],r=0;for(let a of o){let i=e.indexOf(a.text,r);i!==-1&&(i>r&&t.push({type:"text",value:e.slice(r,i)}),t.push({type:"completed",value:a.text,param:a}),r=i+a.text.length)}let n=e.slice(r);return n&&t.push({type:"text",value:n}),t}function Ue(e,o){let t=[],r=[],n=0;for(let a of o){let i=e.indexOf(a.text,n);i===-1?r.push(a):(t.push(a),n=i+a.text.length)}return{valid:t,invalid:r}}var T=require("react");var ut="0.1.4",pt=process?.env.MAGICX_API_ENDPOINT||"/api/suggest",Le=!1;function mt(e){let o=e?.apiKey||process?.env.MAGICX_AI_AUTOCOMPLETE_API_KEY||"";return!o&&!Le&&(Le=!0,console.warn("[AIAutocomplete] No API key set (MAGICX_AI_AUTOCOMPLETE_API_KEY). Requests will be sent without an Authorization header.")),o}function dt(e){return e?.authScheme?e.authScheme:process?.env.MAGICX_AUTH_SCHEME==="Basic"?"Basic":"Bearer"}function ft(){return crypto.randomUUID()}function gt(e,o){return{placeholder:e.placeholder,type:e.type,...o&&{text:e.text},kind:e.kind}}async function Ne(e,o,t){let r=t?.apiConfig,n=mt(r),a=dt(r),i=!t?.maskCompletedText,l=t?.contactAccountCount,d={data:{raw_query:e,completed_params:o.map(b=>gt(b,i)),...l!=null&&{contact_account_count:l}},meta:{request_id:ft(),request_at:new Date().toISOString(),language:typeof navigator<"u"?navigator.language:"en-US",client_version:ut}},g={"Content-Type":"application/json","X-App-Identifier":process?.env.MAGICX_APP_IDENTIFIER||"active-campaign-demo",...r?.headers};n&&(g.Authorization=a==="Basic"?`Basic ${btoa(n)}`:`Bearer ${n}`);let p=await fetch(pt,{method:"POST",headers:g,body:JSON.stringify(d),signal:t?.signal});if(!p.ok)throw new Error(`API error: ${p.status} ${p.statusText}`);return p.json()}function G(e,o){let t=e,r={},n=[];for(let a of o){let i=(r[a.type]??0)+1;r[a.type]=i;let d=`{{${a.type.toUpperCase().replace(/\s+/g,"_")}_${i}}}`,g=t.indexOf(a.text);g!==-1&&(t=t.slice(0,g)+d+t.slice(g+a.text.length)),n.push({...a,placeholder:d})}return{rawQuery:t,completedParams:n}}function De(e,o){return o?e.map(t=>{let r=o[t.type];if(!r)return t;let n=r("");if(n.length===0)return t;let a=new Set(n.map(l=>l.text)),i=(t.options??[]).filter(l=>!a.has(l.text));return{...t,options:[...n,...i]}}):e}var ht=100,bt=300,yt=2;function Fe({textRef:e,suggestionsRef:o,filterBaseRef:t,maskCompletedTextRef:r,apiConfigRef:n,optionOverridesRef:a,onErrorRef:i,setCompletedParams:l,setSuggestions:d,setActiveDropdownIndex:g}){let[p,b]=(0,T.useState)(!1),[h,S]=(0,T.useState)(null),[k,x]=(0,T.useState)(!1),v=(0,T.useRef)(0),A=(0,T.useRef)(null),m=(0,T.useRef)(""),f=(0,T.useCallback)(async(s,c)=>{A.current?.abort();let P=new AbortController;A.current=P;let U=++v.current,F=e.current.length;o.current.some($=>$.type!=="placeholder")||b(!0),S(null);try{let $=c.find(_=>_.type==="contact"&&_.metadata?.contact_account_count)?.metadata?.contact_account_count,K=await Ne(s,c,{maskCompletedText:r.current,signal:P.signal,contactAccountCount:typeof $=="number"?$:void 0,apiConfig:n.current});if(U!==v.current)return;let R=De(K.data.suggestions??[],a.current);x(K.data.is_ready??!1),m.current=s;let E=K.data.input??[],q=E[E.length-1],H=e.current;if(q?.state==="in_progress"){let _=H.toLowerCase().lastIndexOf(q.text.toLowerCase());_!==-1?t.current=_:t.current=F}else t.current=F;let O=R.filter(_=>_.type!=="placeholder")[0];if(O){let _=H.slice(t.current),B=Z(O.options,_);B&&(l(M=>[...M,{id:crypto.randomUUID(),placeholder:"",type:O.type,text:B.text,kind:B.kind,suggestionType:O.type,suggestionPlaceholder:O.text,options:O.options,metadata:B.metadata}]),R=R.filter(M=>M!==O))}d(R),b(!1),g(-1)}catch($){if(U===v.current){let K=$ instanceof Error?$:new Error(String($));S(K),b(!1),i.current?.(K)}}},[e,o,t,r,n,a,i,l,d,g]);return(0,T.useEffect)(()=>(f("",[]),()=>{A.current?.abort()}),[f]),{doFetch:f,isLoading:p,error:h,isReady:k,lastRawQueryRef:m}}function $e({text:e,completedParams:o,doFetch:t,filterBaseRef:r,skipNextFetchRef:n,suggestionsRef:a,lastRawQueryRef:i}){let l=(0,T.useRef)(null),d=(0,T.useRef)(null),g=(0,T.useRef)(!0);(0,T.useEffect)(()=>{l.current&&clearTimeout(l.current),d.current&&clearTimeout(d.current);let p=b=>{if(n.current)return n.current=!1,!1;if(!e&&o.length===0)return g.current?(t("",[]),!0):(g.current=!0,!1);let h=e.slice(r.current),x=a.current.filter(F=>F.type!=="placeholder")[0],A=(x?se(x.options,h):[]).filter(F=>F.is_tappable),m=x?Z(x.options,h)!==null:!1,f=h.trim().length>0;if(A.length>0&&!m&&f)return!1;let{rawQuery:s,completedParams:c}=G(e,o),P=s.length<i.current.length,U=Math.abs(s.length-i.current.length);return P||U>=b?(t(s,c),!0):!1};return l.current=setTimeout(()=>{p(yt)&&d.current&&clearTimeout(d.current)},ht),d.current=setTimeout(()=>p(1),bt),()=>{l.current&&clearTimeout(l.current),d.current&&clearTimeout(d.current)}},[e,o,t,r,n,a,i])}var ve=require("react");function Ke({activeDropdownIndex:e,setActiveDropdownIndex:o,filteredOptions:t,selectOption:r,onSubmitRef:n,text:a,completedParams:i,isDropdownOpen:l,hasPlaceholder:d,placeholderText:g,suggestions:p,filterBaseRef:b,columns:h,setText:S,setCompletedParams:k,setSuggestions:x}){let v=(0,ve.useCallback)(()=>{let m=t.map((c,P)=>c.is_tappable?P:-1).filter(c=>c!==-1),f=m.filter(c=>c%h===0),s=m.filter(c=>c%h===1);return[...f,...s]},[t,h]);return{handleKeyDown:(0,ve.useCallback)(m=>{let f=v();switch(m.key){case"ArrowDown":{if(m.preventDefault(),f.length===0)return;let s=f.indexOf(e),c=s<f.length-1?s+1:0;o(f[c]);break}case"ArrowUp":{if(m.preventDefault(),f.length===0)return;let s=f.indexOf(e),c=s>0?s-1:f.length-1;o(f[c]);break}case"ArrowRight":{if(e<0)break;if(e%h===0){let s=e+1;s<t.length&&t[s]?.is_tappable&&(m.preventDefault(),o(s))}break}case"ArrowLeft":{if(e<0)break;if(e%h===1){let s=e-1;s>=0&&t[s]?.is_tappable&&(m.preventDefault(),o(s))}break}case"Enter":{if(m.preventDefault(),e>=0&&t[e]?.is_tappable)r(t[e]);else if(n.current){let{rawQuery:s,completedParams:c}=G(a,i),P={query:a.trim(),raw_query:s,completed_params:c};n.current(P)}break}case"Tab":{if(e>=0&&t[e]?.is_tappable)m.preventDefault(),r(t[e]);else if(l){let s=t.find(c=>c.is_tappable);s&&(m.preventDefault(),r(s))}else if(!a&&d){m.preventDefault();let s=p.find(c=>c.type==="placeholder");s?(S(g),b.current=g.length,k(c=>[...c,{id:crypto.randomUUID(),placeholder:"",type:s.type,text:g,kind:null,suggestionType:s.type,suggestionPlaceholder:s.text,options:s.options}]),x(c=>c.filter(P=>P!==s))):(S(g),b.current=g.length)}break}case"Escape":o(-1);break}},[e,h,i,t,b,v,d,l,n,g,r,o,k,x,S,p,a]),getTappableIndices:v}}var ie=require("react");function je({completedParams:e,suggestions:o,setCompletedParams:t,setSuggestions:r,setActiveDropdownIndex:n,filterBaseRef:a,pillTappedRef:i}){let l=(0,ie.useCallback)(p=>{let b=o.filter(x=>x.type!=="placeholder");if(p<0||p>=b.length)return;let h=b[p],S=b.filter((x,v)=>v!==p),k=o.filter(x=>x.type==="placeholder");r([...k,h,...S]),i.current=!0,n(-1)},[o,r,n,i]),d=(0,ie.useCallback)(()=>{if(e.length===0)return;let p=e[e.length-1],b={type:p.suggestionType,text:p.suggestionPlaceholder,required:!0,options:p.options};t(h=>h.slice(0,-1)),r(h=>[b,...h]),n(-1)},[e,t,r,n]),g=(0,ie.useCallback)(p=>{let b={type:p.suggestionType,text:p.suggestionPlaceholder,required:!0,options:p.options};return{apply:h=>{h(S=>{let k=0;for(let x of e){let v=S.indexOf(x.text,k);if(v!==-1){if(x.id===p.id){let A=S.slice(0,v),m=S.slice(v+p.text.length),f=(A+m).replace(/ {2,}/g," ");return a.current=Math.min(a.current,f.length),f}k=v+x.text.length}}return S}),t(S=>S.filter(k=>k.id!==p.id)),r(S=>[b,...S]),n(-1),i.current=!0}}},[e,t,r,n,a,i]);return{setActivePill:l,removeLastParam:d,reEditParam:g}}function ce({onSubmit:e,onError:o,optionOverrides:t,maskCompletedText:r,placeholder:n,apiConfig:a,columns:i=2,value:l,completedParams:d,onChange:g,onParamsChange:p}){let b=l!==void 0,h=d!==void 0,[S,k]=(0,u.useState)(""),[x,v]=(0,u.useState)([]),[A,m]=(0,u.useState)([]),[f,s]=(0,u.useState)(-1),c=b?l:S,P=h?d:x,U=(0,u.useRef)(e);U.current=e;let F=(0,u.useRef)(g);F.current=g;let z=(0,u.useRef)(p);z.current=p;let $=(0,u.useRef)(l);$.current=l;let K=(0,u.useRef)(d);K.current=d;let R=(0,u.useCallback)(y=>{if(typeof y=="function")if(b){let w=y($.current??"");F.current?.(w)}else k(w=>{let Q=y(w);return F.current?.(Q),Q});else b||k(y),F.current?.(y)},[b]),E=(0,u.useCallback)(y=>{if(typeof y=="function")if(h){let w=y(K.current??[]);z.current?.(w)}else v(w=>{let Q=y(w);return z.current?.(Q),Q});else h||v(y),z.current?.(y)},[h]),q=(0,u.useRef)(o);q.current=o;let H=(0,u.useRef)(t);H.current=t;let Y=(0,u.useRef)(r);Y.current=r;let O=(0,u.useRef)(a);O.current=a;let _=(0,u.useRef)(c);_.current=c;let B=(0,u.useRef)(A);B.current=A;let M=(0,u.useRef)(0),ee=(0,u.useRef)(!1),Ae=(0,u.useRef)(!1),le=(0,u.useId)(),{doFetch:ue,isLoading:Ce,error:qe,isReady:Be,lastRawQueryRef:pe}=Fe({textRef:_,suggestionsRef:B,filterBaseRef:M,maskCompletedTextRef:Y,apiConfigRef:O,optionOverridesRef:H,onErrorRef:q,setCompletedParams:E,setSuggestions:m,setActiveDropdownIndex:s});$e({text:c,completedParams:P,doFetch:ue,filterBaseRef:M,skipNextFetchRef:Ae,suggestionsRef:B,lastRawQueryRef:pe});let Qe=(0,u.useMemo)(()=>Me(c,P),[c,P]);M.current=Math.min(M.current,c.length);let me=c.slice(M.current),de=(0,u.useMemo)(()=>A.filter(w=>w.type==="placeholder").map(w=>w.text).join(" ")||n||"",[A,n]),te=(0,u.useMemo)(()=>A.filter(y=>y.type!=="placeholder"),[A]),C=te[0],ke=C?t?.[C.type]:void 0,we=C?ke?ke(me.trim()):C.options??[]:[],fe=(0,u.useMemo)(()=>se(we,me),[we,me]),Oe=de.length>0,ge=!Ce&&fe.length>0&&(!!c||ee.current||!Oe),Ie=(0,u.useCallback)(y=>{if(!C)return;let w={id:crypto.randomUUID(),placeholder:"",type:C.type,text:y.text,kind:y.kind,suggestionType:C.type,suggestionPlaceholder:C.text,options:C.options,metadata:y.metadata},Q=M.current,L=_.current.slice(0,Q);if(L.length>0&&!L.endsWith(" ")){let N=L.split(/\s+/).pop()??"";N&&y.text.toLowerCase().startsWith(N.toLowerCase())&&(L=L.slice(0,L.length-N.length))}let he=L.length>0&&L[L.length-1]!==" ",V=L+(he?" ":"")+y.text+" ";R(V),M.current=V.length,E(N=>[...N,w]),m(N=>N.filter(J=>J!==C)),ee.current=!1,s(-1),te.length-1>0&&(Ae.current=!0)},[C,te,R,E]),He=(0,u.useCallback)(y=>{let w=y.target.value,L=w.length>0&&!y.nativeEvent?.isComposing&&w[0]!==w[0].toUpperCase()?w[0].toUpperCase()+w.slice(1):w;R(L),ee.current=!1,s(-1);let{valid:he,invalid:V}=Ue(L,P);if(V.length>0){E(()=>he);for(let X of V)m(N=>[{type:X.suggestionType,text:X.suggestionPlaceholder,required:!0,options:X.options},...N])}if(C&&V.length===0){let X=L.slice(M.current),N=Z(C.options,X);N&&(E(J=>[...J,{id:crypto.randomUUID(),placeholder:"",type:C.type,text:N.text,kind:N.kind,suggestionType:C.type,suggestionPlaceholder:C.text,options:C.options,metadata:N.metadata}]),m(J=>J.filter(Ye=>Ye!==C)))}},[P,C,R,E]),{handleKeyDown:Ve}=Ke({activeDropdownIndex:f,setActiveDropdownIndex:s,filteredOptions:fe,selectOption:Ie,onSubmitRef:U,text:c,completedParams:P,isDropdownOpen:ge,hasPlaceholder:Oe,placeholderText:de,suggestions:A,filterBaseRef:M,columns:i,setText:R,setCompletedParams:E,setSuggestions:m}),oe=je({completedParams:P,suggestions:A,setCompletedParams:E,setSuggestions:m,setActiveDropdownIndex:s,filterBaseRef:M,pillTappedRef:ee}),Xe=(0,u.useCallback)(y=>{oe.reEditParam(y).apply(R)},[oe,R]),We=(0,u.useCallback)(()=>{R(""),E(()=>[]),m([]),s(-1),M.current=0,pe.current="",ue("",[])},[ue,R,E,pe]),Ge=f>=0?`${le}-option-${f}`:void 0;return{completedParams:P,suggestionPills:te,setActivePill:oe.setActivePill,removeLastParam:oe.removeLastParam,reEditParam:Xe,segments:Qe,suggestions:A,activeIndex:f,isReady:Be,isLoading:Ce,error:qe,inputProps:{value:c,placeholder:de||void 0,onChange:He,onKeyDown:Ve,role:"combobox","aria-expanded":ge,"aria-activedescendant":Ge,"aria-autocomplete":"list","aria-controls":le},reset:We,dropdownProps:{suggestions:C?[{...C,options:fe}]:[],activeIndex:f,onSelect:Ie,onHighlight:s,isOpen:ge,id:le}}}var I=require("react/jsx-runtime"),ze=(0,D.forwardRef)(function({onSubmit:o,onError:t,optionOverrides:r,maskCompletedText:n,placeholder:a,className:i,apiConfig:l,columns:d,value:g,completedParams:p,onChange:b,onParamsChange:h},S){let k=(0,D.useRef)(null),[x,v]=(0,D.useState)(!1),A=(0,D.useRef)(()=>{}),m=(0,D.useRef)(void 0);(0,D.useEffect)(()=>(k.current?.focus(),()=>clearTimeout(m.current)),[]);let{completedParams:f,suggestionPills:s,setActivePill:c,segments:P,inputProps:U,dropdownProps:F,reset:z}=ce({onSubmit:O=>A.current(O),onError:t,optionOverrides:r,maskCompletedText:n,placeholder:a,apiConfig:l,columns:d,value:g,completedParams:p,onChange:b,onParamsChange:h});(0,D.useImperativeHandle)(S,()=>({focus:()=>k.current?.focus(),reset:z}),[z]);let $=()=>{k.current?.focus()},K=!!U.value||f.length>0,R=(0,D.useCallback)(()=>{if(!K)return;let{rawQuery:O,completedParams:_}=G(U.value,f);o({query:U.value.trim(),raw_query:O,completed_params:_}),z(),v(!0),clearTimeout(m.current),m.current=setTimeout(()=>v(!1),3e3)},[K,U.value,f,o,z]);A.current=R;let{onChange:E,placeholder:q,...H}=U,Y=!U.value;return(0,I.jsxs)("div",{className:`${j.container} ${i??""}`,children:[(0,I.jsx)("div",{className:`${j.checkmark} ${x?j.checkmarkVisible:""}`,children:(0,I.jsxs)("svg",{width:"72",height:"72",viewBox:"0 0 24 24",fill:"none",role:"img","aria-label":"Success",children:[(0,I.jsx)("circle",{cx:"12",cy:"12",r:"12",fill:"#34C759"}),(0,I.jsx)("path",{d:"M7 12.5l3.5 3.5L17 9",stroke:"#000",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",className:j.checkmarkPath})]})}),(0,I.jsx)(re,{...F}),(0,I.jsxs)("div",{className:j.inputWrapper,onClick:$,children:[(0,I.jsxs)("div",{className:j.editorArea,children:[(0,I.jsxs)("div",{className:j.sizerContent,"aria-hidden":"true",children:[Y&&q?(0,I.jsxs)("span",{className:j.placeholderText,children:[q," "]}):(0,I.jsxs)("span",{className:j.sizerText,children:[P.map((O,_)=>(0,I.jsx)("span",{children:O.value},`${_}-${O.type}`)),P.length===0&&"\xA0"]})," ",(0,I.jsx)(Ee,{pills:s,activePillIndex:0,onSelectPill:c})]}),(0,I.jsx)("textarea",{ref:k,className:j.textarea,rows:1,onChange:E,...H})]}),(0,I.jsx)("button",{type:"button",className:j.submitButton,disabled:!K,onClick:O=>{O.stopPropagation(),R()},"aria-label":"Submit",children:(0,I.jsx)("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",role:"img","aria-label":"Submit",children:(0,I.jsx)("path",{d:"M9 14V4M9 4L4 9M9 4L14 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})});0&&(module.exports={AIAutocomplete,AIAutocompleteDropdown,useAIAutocomplete});
2
2
  //# sourceMappingURL=index.js.map