@magicx-eng/ai-autocomplete-vanilla 0.1.13 → 0.1.15
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 +23 -10
- package/index.d.mts +88 -0
- package/index.d.ts +88 -0
- package/index.js +183 -65
- package/index.js.map +1 -1
- package/index.mjs +183 -65
- package/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,15 +6,18 @@ A framework-agnostic vanilla JS/TypeScript library that provides a guided AI-pow
|
|
|
6
6
|
|
|
7
7
|
- **Three tiers of integration** — full drop-in component, dropdown-only, or fully headless
|
|
8
8
|
- **Zero dependencies** — no React, no framework, no virtual DOM
|
|
9
|
-
- **
|
|
10
|
-
- **Pill
|
|
9
|
+
- **Rich inline input** — a single `contentEditable` surface: typed text, bold completed params, and inline pills all share one editing context
|
|
10
|
+
- **Pill-based input** — non-editable inline pills for unfilled parameters, bold inline text for completed ones
|
|
11
|
+
- **Instant exact-match bolding** — typing the full text of an option immediately promotes it to a completed param (no debounced fetch wait). Works in the normal typing flow *and* while re-editing an existing completed param.
|
|
12
|
+
- **Re-edit completed params** — tap a bold completed param to replace it; the dropdown re-opens with the cached options the server originally returned for that param
|
|
11
13
|
- **Light/dark mode** — built-in themes with `prefers-color-scheme` support, fully overridable via CSS variables
|
|
12
14
|
- **Access token auth** — short-lived tokens with automatic refresh, single-flight deduplication, and 401 retry
|
|
13
|
-
- **Keyboard navigation** — arrow keys, enter to submit, tab to autocomplete
|
|
15
|
+
- **Keyboard navigation** — arrow keys, enter to submit, tab to autocomplete, backspace to un-bold the last completed param
|
|
14
16
|
- **Client-side filtering** — instant substring filtering on every keystroke
|
|
15
17
|
- **Option overrides** — inject or dynamically generate client-side options per suggestion type
|
|
16
18
|
- **Controlled & uncontrolled** — works out of the box or integrates with external state
|
|
17
|
-
- **Accessible** — ARIA combobox pattern with `role="listbox"`, `aria-activedescendant`
|
|
19
|
+
- **Accessible** — ARIA combobox 1.2 pattern with `role="listbox"`, `aria-activedescendant`
|
|
20
|
+
- **IME-safe** — composition events are buffered so input text is committed once, after composition ends
|
|
18
21
|
- **Animations** — option selection streak animation, text shimmer on newly added params
|
|
19
22
|
- **Lightweight** — ~10 KB gzipped, styles auto-injected at runtime
|
|
20
23
|
- **TypeScript first** — full type definitions shipped with the package
|
|
@@ -115,7 +118,13 @@ ac.update({ animations: false, optionsPosition: "above" });
|
|
|
115
118
|
|
|
116
119
|
> **Tier 1 auto-resets** after both Enter key and built-in submit-button clicks — your `onSubmit` runs, then the SDK clears the input and starts a new session. You don't need to call `ac.reset()` yourself in Tier 1.
|
|
117
120
|
|
|
118
|
-
> `autoFocus`, `focus()`, and `blur()` only operate on the
|
|
121
|
+
> `autoFocus`, `focus()`, and `blur()` only operate on the contentEditable editor the library owns (Tier 1 / `renderMode: "full"`). In Tier 2/3, the consumer owns the input and calls `.focus()` / `.blur()` on their own element; the `onFocus` / `onBlur` callbacks still fire whenever `setFocused()` is called.
|
|
122
|
+
|
|
123
|
+
> **Backspace into a completed param** — pressing Backspace while the caret is inside (or immediately after) a bold completed param drops the param's "completed" status and removes one grapheme before the caret. The remaining text stays in the editor as plain (un-bold) text so the user can keep editing instead of losing the whole phrase.
|
|
124
|
+
|
|
125
|
+
> **Re-edit a completed param** — tapping a bold completed param enters *re-edit mode*. The dropdown re-opens with the cached options the server originally returned for that param. Typing atomically replaces the bold (and re-promotes it to bold if what you type exactly matches one of the cached options); clicking an option replaces it with the new selection; pressing Escape or moving the caret out exits without changes.
|
|
126
|
+
|
|
127
|
+
> **Caret placement after a completion** — whenever a completed param is added (by any means — option click, exact-match typing, or re-edit), the caret lands right after the trailing space following the bold so typing can continue immediately. A space is inserted if one wasn't already there.
|
|
119
128
|
|
|
120
129
|
#### Custom submit button
|
|
121
130
|
|
|
@@ -221,7 +230,7 @@ unsub();
|
|
|
221
230
|
| `suggestions` | `Suggestion[]` | All suggestions from server (including placeholder type) |
|
|
222
231
|
| `actionableSuggestions` | `Suggestion[]` | Non-placeholder suggestions (the pills) |
|
|
223
232
|
| `filteredOptions` | `SuggestionOption[]` | Options for the active suggestion, filtered by current query |
|
|
224
|
-
| `segments` | `Segment[]` | Input text split into typed text vs completed params —
|
|
233
|
+
| `segments` | `Segment[]` | Input text split into typed text vs completed params — completed segments render as bold `<strong>` runs inside the editor |
|
|
225
234
|
| `placeholderText` | `string` | Placeholder text from server suggestions (joined `placeholder`-type suggestion texts) |
|
|
226
235
|
| `activeDropdownIndex` | `number` | Highlighted option index (-1 = none) |
|
|
227
236
|
| `isDropdownOpen` | `boolean` | Whether the dropdown should be visible |
|
|
@@ -240,7 +249,7 @@ unsub();
|
|
|
240
249
|
| `selectOption(option)` | Select a dropdown option. Updates text, creates completed param, triggers shimmer. |
|
|
241
250
|
| `setActiveDropdownIndex(index)` | Set the highlighted option (for mouse hover). |
|
|
242
251
|
| `setActivePill(index)` | Reorder pills — moves pill at `index` to front (active). |
|
|
243
|
-
| `removeLastParam()` | Remove last completed param
|
|
252
|
+
| `removeLastParam()` | Remove the last completed param from state. The text stays in the input as plain text. |
|
|
244
253
|
| `clearNewParamId()` | Clear shimmer animation state. |
|
|
245
254
|
| `reset()` | Clear all state, re-fetch initial suggestions, and start a new session (rotates `session_id`). Call this after handling submit. |
|
|
246
255
|
| `setValue(text)` | Set text (controlled mode). |
|
|
@@ -332,6 +341,7 @@ Override these on the container element. All built-in defaults use `:where()` (z
|
|
|
332
341
|
|
|
333
342
|
| Variable | Default (light) | Default (dark) | Description |
|
|
334
343
|
|---|---|---|---|
|
|
344
|
+
| `--aia-font-family` | `inherit` | `inherit` | Font used by the library. Defaults to `inherit` so the library picks up your page's font automatically. Set this to pin a specific font on the library without changing the surrounding page. |
|
|
335
345
|
| `--aia-pill-bg` | `#bdbdbd` | `#bdbdbd` | Pill background |
|
|
336
346
|
| `--aia-pill-color` | `#000000` | `#ffffff` | Pill text |
|
|
337
347
|
| `--aia-pill-font-size` | `19px` | `19px` | Pill font size |
|
|
@@ -341,7 +351,7 @@ Override these on the container element. All built-in defaults use `:where()` (z
|
|
|
341
351
|
| `--aia-option-font-size` | `19px` | `19px` | Option font size |
|
|
342
352
|
| `--aia-written-text-color` | `#000000` | `#ffffff` | Input text |
|
|
343
353
|
| `--aia-written-text-font-size` | `19px` | `19px` | Input text font size |
|
|
344
|
-
| `--aia-caret-color` | `--aia-written-text-color` | `--aia-written-text-color` |
|
|
354
|
+
| `--aia-caret-color` | `--aia-written-text-color` | `--aia-written-text-color` | Editor caret color. Override independently of input text color. |
|
|
345
355
|
| `--aia-submit-bg` | `#000000` | `#ffffff` | Submit button background |
|
|
346
356
|
| `--aia-submit-color` | `#ffffff` | `#000000` | Submit button icon color |
|
|
347
357
|
| `--aia-dropdown-bg` | — | — | Optional bg color the dropdown's "glass" rim shadow tints toward. Set this to the page background behind the dropdown so the bottom-corner glow blends seamlessly. |
|
|
@@ -373,14 +383,17 @@ For styling beyond the CSS variables, target these stable `data-aia-*` attribute
|
|
|
373
383
|
|
|
374
384
|
| Attribute | Element |
|
|
375
385
|
|---|---|
|
|
376
|
-
| `[data-aia-editor]` | Editor area wrapping the
|
|
377
|
-
| `[data-aia-
|
|
386
|
+
| `[data-aia-editor]` | Editor area wrapping the contentEditable + inline pill list |
|
|
387
|
+
| `[data-aia-input]` | The contentEditable `<div>` that owns typed text and bold completed params. Replaces the previous `[data-aia-textarea]` selector. |
|
|
388
|
+
| `[data-aia-pill-list-container]` | Inline sibling of the editor that holds unfilled-suggestion pills |
|
|
378
389
|
| `[data-aia-submit]` | Submit button |
|
|
379
390
|
| `[data-aia-pill]` | Each unfilled-suggestion pill |
|
|
380
391
|
| `[data-aia-pillbar]` | Pill bar container inside the dropdown |
|
|
381
392
|
| `[data-aia-option]` | Each suggestion option |
|
|
382
393
|
| `[data-aia-dropdown]` | The dropdown root (listbox) |
|
|
383
394
|
|
|
395
|
+
Completed params render as inline `<strong>` elements inside the editor. Override their weight with `[data-aia-input] strong { font-weight: 700; }` (the built-in style uses `:where()` so any consumer selector wins without `!important`).
|
|
396
|
+
|
|
384
397
|
The vanilla core also exposes stable BEM class names (`magicx-aia-*`); both can be used.
|
|
385
398
|
|
|
386
399
|
```css
|
package/index.d.mts
CHANGED
|
@@ -22,8 +22,11 @@ interface Suggestion {
|
|
|
22
22
|
interface CompletedParamState extends CompletedParam {
|
|
23
23
|
id: string;
|
|
24
24
|
text: string;
|
|
25
|
+
/** Source suggestion's `type` — used by re-edit mode to render the dropdown pill. */
|
|
25
26
|
suggestionType: string;
|
|
27
|
+
/** Source suggestion's `text` — used by re-edit mode to render the dropdown pill. */
|
|
26
28
|
suggestionPlaceholder: string;
|
|
29
|
+
/** Cached options from the suggestion that produced this param — re-edit shows these. */
|
|
27
30
|
options: SuggestionOption[];
|
|
28
31
|
metadata?: Record<string, unknown>;
|
|
29
32
|
}
|
|
@@ -85,6 +88,19 @@ interface CoreState {
|
|
|
85
88
|
skipNextFetch: boolean;
|
|
86
89
|
lastRawQuery: string;
|
|
87
90
|
isFocused: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Re-edit state: while non-null, the user is editing a bold completed param.
|
|
93
|
+
* The snapshot stays here even after the param is removed from
|
|
94
|
+
* `completedParams` (when typing/backspace replaces its text), so the
|
|
95
|
+
* dropdown can keep filtering the cached options.
|
|
96
|
+
*/
|
|
97
|
+
editingParam: CompletedParamState | null;
|
|
98
|
+
/** Plain-text offset where the edited param started (anchor for the edit region). */
|
|
99
|
+
editingAnchor: number | null;
|
|
100
|
+
/** Plain-text offset of the right edge of the edit region. Caret outside [anchor, tail] exits edit mode. */
|
|
101
|
+
editingTail: number | null;
|
|
102
|
+
/** Current caret offset within the editor. Tracked via DOM `selectionchange`. */
|
|
103
|
+
caretOffset: number | null;
|
|
88
104
|
}
|
|
89
105
|
/**
|
|
90
106
|
* Render mode:
|
|
@@ -136,6 +152,14 @@ interface CoreOptions {
|
|
|
136
152
|
onBlur?: () => void;
|
|
137
153
|
value?: string;
|
|
138
154
|
completedParams?: CompletedParamState[];
|
|
155
|
+
/**
|
|
156
|
+
* Headless-mode caret setter. The core invokes this in place of writing to
|
|
157
|
+
* its own `domRefs.input` when re-edit / Backspace flows need to park the
|
|
158
|
+
* caret at a specific plain-text offset. Wrappers that own the DOM (React,
|
|
159
|
+
* etc.) must provide this — vanilla "full" mode falls back to `domRefs`.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
setCursor?: (offset: number) => void;
|
|
139
163
|
}
|
|
140
164
|
|
|
141
165
|
declare class AIAutocomplete {
|
|
@@ -166,7 +190,54 @@ declare class AIAutocomplete {
|
|
|
166
190
|
setCompletedParams(params: CompletedParamState[]): void;
|
|
167
191
|
setActivePill(index: number): void;
|
|
168
192
|
removeLastParam(): void;
|
|
193
|
+
/**
|
|
194
|
+
* Backspace inside a completed param: drop the param's "completed" status so
|
|
195
|
+
* it renders as plain (un-bold) text, AND remove one grapheme before the
|
|
196
|
+
* caret — same single-character delete a normal Backspace would do. The
|
|
197
|
+
* remaining text stays in the input so the user can continue editing what
|
|
198
|
+
* they had typed instead of losing the whole phrase.
|
|
199
|
+
*
|
|
200
|
+
* Returns true when a param was reconciled (caller should `preventDefault`).
|
|
201
|
+
*/
|
|
202
|
+
removeParamAtCaret(offset: number): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Set the editor caret at the given plain-text offset. Uses the core's own
|
|
205
|
+
* `domRefs.input` in "full" mode; falls back to the wrapper-provided
|
|
206
|
+
* `setCursor` callback in "headless" mode where the wrapper owns the DOM.
|
|
207
|
+
*/
|
|
208
|
+
private scheduleSetCursor;
|
|
169
209
|
clearNewParamId(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Enter re-edit mode for the bold completed param with the given id. The
|
|
212
|
+
* caller is responsible for highlighting the param via the Selection API
|
|
213
|
+
* (DOM concern). This method just sets the state snapshot so the dropdown
|
|
214
|
+
* starts filtering the param's cached options.
|
|
215
|
+
*/
|
|
216
|
+
startEditingParam(paramId: string): void;
|
|
217
|
+
/**
|
|
218
|
+
* Replace the editing range (`text[editingAnchor..editingTail]`) with the
|
|
219
|
+
* given replacement. Used by the DOM layer's `beforeinput` intercept: while
|
|
220
|
+
* the edited param's strong still exists in `completedParams`, typing or
|
|
221
|
+
* backspace should swap the WHOLE param atomically (instead of inserting
|
|
222
|
+
* one char into the bold span). Returns true when the replacement was
|
|
223
|
+
* applied — callers should `preventDefault` only in that case.
|
|
224
|
+
*/
|
|
225
|
+
replaceEditingRange(replacement: string): boolean;
|
|
226
|
+
/** Clear re-edit state. Selection collapsing is a DOM concern handled by the caller. */
|
|
227
|
+
exitEditMode(): void;
|
|
228
|
+
/**
|
|
229
|
+
* Update caret offset after a text-input event. While in edit mode, extends
|
|
230
|
+
* `editingTail` to keep up with the user typing past the previous tail.
|
|
231
|
+
* Exits edit mode if the user backspaced past `editingAnchor` (deleting a
|
|
232
|
+
* character before where the edit started).
|
|
233
|
+
*/
|
|
234
|
+
handleCaretAfterInput(offset: number | null): void;
|
|
235
|
+
/**
|
|
236
|
+
* Update caret offset from a selection-move event that was NOT preceded by
|
|
237
|
+
* an input event (so the user moved the cursor by click or arrows, not by
|
|
238
|
+
* typing). Exits edit mode if the caret moved outside the edit region.
|
|
239
|
+
*/
|
|
240
|
+
handleCaretMove(offset: number | null): void;
|
|
170
241
|
setActiveDropdownIndex(index: number): void;
|
|
171
242
|
handleTextChange(value: string): void;
|
|
172
243
|
handleKeyDown(e: KeyboardEvent): void;
|
|
@@ -179,6 +250,7 @@ declare class AIAutocomplete {
|
|
|
179
250
|
on(event: string, callback: (...args: unknown[]) => void): () => void;
|
|
180
251
|
update(opts: Partial<CoreOptions>): void;
|
|
181
252
|
selectOption(option: SuggestionOption): void;
|
|
253
|
+
private selectOptionInEditMode;
|
|
182
254
|
private fireTelemetry;
|
|
183
255
|
private recomputeDerived;
|
|
184
256
|
private setupContainer;
|
|
@@ -189,6 +261,22 @@ declare class AIAutocomplete {
|
|
|
189
261
|
/** Auto-clear newParamId after shimmer animation. */
|
|
190
262
|
private subscribeNewParamTimer;
|
|
191
263
|
private handleChange;
|
|
264
|
+
/**
|
|
265
|
+
* When the user has typed text that exactly matches (case-insensitive) one
|
|
266
|
+
* of the active suggestion's options, promote it to a completed param right
|
|
267
|
+
* away. The fetchController does the same check when the debounced fetch
|
|
268
|
+
* lands; doing it instantly here means bold styling appears as soon as the
|
|
269
|
+
* option is fully typed, without waiting 100–300ms for the round-trip.
|
|
270
|
+
*/
|
|
271
|
+
private maybePromoteExactMatch;
|
|
272
|
+
/**
|
|
273
|
+
* Edit-mode counterpart to {@link maybePromoteExactMatch}. When the user is
|
|
274
|
+
* editing a bold completed param and the typed text exactly matches one of
|
|
275
|
+
* that param's cached options, promote it back to a completed param (bold)
|
|
276
|
+
* — same instant-bold affordance as the normal typing flow, just driven by
|
|
277
|
+
* the edited param's cached options instead of the active suggestion.
|
|
278
|
+
*/
|
|
279
|
+
private maybePromoteEditExactMatch;
|
|
192
280
|
}
|
|
193
281
|
|
|
194
282
|
type Listener<S> = (next: S, prev: S) => void;
|
package/index.d.ts
CHANGED
|
@@ -22,8 +22,11 @@ interface Suggestion {
|
|
|
22
22
|
interface CompletedParamState extends CompletedParam {
|
|
23
23
|
id: string;
|
|
24
24
|
text: string;
|
|
25
|
+
/** Source suggestion's `type` — used by re-edit mode to render the dropdown pill. */
|
|
25
26
|
suggestionType: string;
|
|
27
|
+
/** Source suggestion's `text` — used by re-edit mode to render the dropdown pill. */
|
|
26
28
|
suggestionPlaceholder: string;
|
|
29
|
+
/** Cached options from the suggestion that produced this param — re-edit shows these. */
|
|
27
30
|
options: SuggestionOption[];
|
|
28
31
|
metadata?: Record<string, unknown>;
|
|
29
32
|
}
|
|
@@ -85,6 +88,19 @@ interface CoreState {
|
|
|
85
88
|
skipNextFetch: boolean;
|
|
86
89
|
lastRawQuery: string;
|
|
87
90
|
isFocused: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Re-edit state: while non-null, the user is editing a bold completed param.
|
|
93
|
+
* The snapshot stays here even after the param is removed from
|
|
94
|
+
* `completedParams` (when typing/backspace replaces its text), so the
|
|
95
|
+
* dropdown can keep filtering the cached options.
|
|
96
|
+
*/
|
|
97
|
+
editingParam: CompletedParamState | null;
|
|
98
|
+
/** Plain-text offset where the edited param started (anchor for the edit region). */
|
|
99
|
+
editingAnchor: number | null;
|
|
100
|
+
/** Plain-text offset of the right edge of the edit region. Caret outside [anchor, tail] exits edit mode. */
|
|
101
|
+
editingTail: number | null;
|
|
102
|
+
/** Current caret offset within the editor. Tracked via DOM `selectionchange`. */
|
|
103
|
+
caretOffset: number | null;
|
|
88
104
|
}
|
|
89
105
|
/**
|
|
90
106
|
* Render mode:
|
|
@@ -136,6 +152,14 @@ interface CoreOptions {
|
|
|
136
152
|
onBlur?: () => void;
|
|
137
153
|
value?: string;
|
|
138
154
|
completedParams?: CompletedParamState[];
|
|
155
|
+
/**
|
|
156
|
+
* Headless-mode caret setter. The core invokes this in place of writing to
|
|
157
|
+
* its own `domRefs.input` when re-edit / Backspace flows need to park the
|
|
158
|
+
* caret at a specific plain-text offset. Wrappers that own the DOM (React,
|
|
159
|
+
* etc.) must provide this — vanilla "full" mode falls back to `domRefs`.
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
setCursor?: (offset: number) => void;
|
|
139
163
|
}
|
|
140
164
|
|
|
141
165
|
declare class AIAutocomplete {
|
|
@@ -166,7 +190,54 @@ declare class AIAutocomplete {
|
|
|
166
190
|
setCompletedParams(params: CompletedParamState[]): void;
|
|
167
191
|
setActivePill(index: number): void;
|
|
168
192
|
removeLastParam(): void;
|
|
193
|
+
/**
|
|
194
|
+
* Backspace inside a completed param: drop the param's "completed" status so
|
|
195
|
+
* it renders as plain (un-bold) text, AND remove one grapheme before the
|
|
196
|
+
* caret — same single-character delete a normal Backspace would do. The
|
|
197
|
+
* remaining text stays in the input so the user can continue editing what
|
|
198
|
+
* they had typed instead of losing the whole phrase.
|
|
199
|
+
*
|
|
200
|
+
* Returns true when a param was reconciled (caller should `preventDefault`).
|
|
201
|
+
*/
|
|
202
|
+
removeParamAtCaret(offset: number): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Set the editor caret at the given plain-text offset. Uses the core's own
|
|
205
|
+
* `domRefs.input` in "full" mode; falls back to the wrapper-provided
|
|
206
|
+
* `setCursor` callback in "headless" mode where the wrapper owns the DOM.
|
|
207
|
+
*/
|
|
208
|
+
private scheduleSetCursor;
|
|
169
209
|
clearNewParamId(): void;
|
|
210
|
+
/**
|
|
211
|
+
* Enter re-edit mode for the bold completed param with the given id. The
|
|
212
|
+
* caller is responsible for highlighting the param via the Selection API
|
|
213
|
+
* (DOM concern). This method just sets the state snapshot so the dropdown
|
|
214
|
+
* starts filtering the param's cached options.
|
|
215
|
+
*/
|
|
216
|
+
startEditingParam(paramId: string): void;
|
|
217
|
+
/**
|
|
218
|
+
* Replace the editing range (`text[editingAnchor..editingTail]`) with the
|
|
219
|
+
* given replacement. Used by the DOM layer's `beforeinput` intercept: while
|
|
220
|
+
* the edited param's strong still exists in `completedParams`, typing or
|
|
221
|
+
* backspace should swap the WHOLE param atomically (instead of inserting
|
|
222
|
+
* one char into the bold span). Returns true when the replacement was
|
|
223
|
+
* applied — callers should `preventDefault` only in that case.
|
|
224
|
+
*/
|
|
225
|
+
replaceEditingRange(replacement: string): boolean;
|
|
226
|
+
/** Clear re-edit state. Selection collapsing is a DOM concern handled by the caller. */
|
|
227
|
+
exitEditMode(): void;
|
|
228
|
+
/**
|
|
229
|
+
* Update caret offset after a text-input event. While in edit mode, extends
|
|
230
|
+
* `editingTail` to keep up with the user typing past the previous tail.
|
|
231
|
+
* Exits edit mode if the user backspaced past `editingAnchor` (deleting a
|
|
232
|
+
* character before where the edit started).
|
|
233
|
+
*/
|
|
234
|
+
handleCaretAfterInput(offset: number | null): void;
|
|
235
|
+
/**
|
|
236
|
+
* Update caret offset from a selection-move event that was NOT preceded by
|
|
237
|
+
* an input event (so the user moved the cursor by click or arrows, not by
|
|
238
|
+
* typing). Exits edit mode if the caret moved outside the edit region.
|
|
239
|
+
*/
|
|
240
|
+
handleCaretMove(offset: number | null): void;
|
|
170
241
|
setActiveDropdownIndex(index: number): void;
|
|
171
242
|
handleTextChange(value: string): void;
|
|
172
243
|
handleKeyDown(e: KeyboardEvent): void;
|
|
@@ -179,6 +250,7 @@ declare class AIAutocomplete {
|
|
|
179
250
|
on(event: string, callback: (...args: unknown[]) => void): () => void;
|
|
180
251
|
update(opts: Partial<CoreOptions>): void;
|
|
181
252
|
selectOption(option: SuggestionOption): void;
|
|
253
|
+
private selectOptionInEditMode;
|
|
182
254
|
private fireTelemetry;
|
|
183
255
|
private recomputeDerived;
|
|
184
256
|
private setupContainer;
|
|
@@ -189,6 +261,22 @@ declare class AIAutocomplete {
|
|
|
189
261
|
/** Auto-clear newParamId after shimmer animation. */
|
|
190
262
|
private subscribeNewParamTimer;
|
|
191
263
|
private handleChange;
|
|
264
|
+
/**
|
|
265
|
+
* When the user has typed text that exactly matches (case-insensitive) one
|
|
266
|
+
* of the active suggestion's options, promote it to a completed param right
|
|
267
|
+
* away. The fetchController does the same check when the debounced fetch
|
|
268
|
+
* lands; doing it instantly here means bold styling appears as soon as the
|
|
269
|
+
* option is fully typed, without waiting 100–300ms for the round-trip.
|
|
270
|
+
*/
|
|
271
|
+
private maybePromoteExactMatch;
|
|
272
|
+
/**
|
|
273
|
+
* Edit-mode counterpart to {@link maybePromoteExactMatch}. When the user is
|
|
274
|
+
* editing a bold completed param and the typed text exactly matches one of
|
|
275
|
+
* that param's cached options, promote it back to a completed param (bold)
|
|
276
|
+
* — same instant-bold affordance as the normal typing flow, just driven by
|
|
277
|
+
* the edited param's cached options instead of the active suggestion.
|
|
278
|
+
*/
|
|
279
|
+
private maybePromoteEditExactMatch;
|
|
192
280
|
}
|
|
193
281
|
|
|
194
282
|
type Listener<S> = (next: S, prev: S) => void;
|