@magicx-eng/ai-autocomplete-angular 0.28.4 → 0.29.1

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.
@@ -1,4 +1,4 @@
1
- import { WEEKDAY_LABELS as WEEKDAY_LABELS$1, cellIso as cellIso$1, monthLabel as monthLabel$1, cellDay as cellDay$1, isoDate as isoDate$1, dateCellMarks as dateCellMarks$1, visibleDateRange as visibleDateRange$1, productInitial, attachProductRowWheel, optionsGridTemplateColumns, optionLabel as optionLabel$1, optionImageSrc as optionImageSrc$1, formatOptionCount as formatOptionCount$1, sanitizeOptionIconSvg as sanitizeOptionIconSvg$1, planOptionsGrid, sameOptionRows, isOptionsGridMobileViewport, needsOptionsGridMeasurement, measureOptionsGrid, optionEnterDelayMs, SCROLL_ARROW_LABEL, buildAttributionUrl, containScroll, attachScrollArrow, isCalendarFormat, getFooterHint, AIAutocomplete, dateSelectionFor, identifiedParamLabel, renderEditableContent, getCursorOffset, extractPlainText, plainTextLength, setCursorOffset, ModeController, buildSubmitResult as buildSubmitResult$1, withSkippedParams as withSkippedParams$1, formatDate as formatDate$1, parseDate as parseDate$1, parseLooseDate as parseLooseDate$1, DATE_RANGE_META_END as DATE_RANGE_META_END$1, DATE_RANGE_META_START as DATE_RANGE_META_START$1, formatDateRange as formatDateRange$1, parseLooseDateRange as parseLooseDateRange$1, selectedRangeFor as selectedRangeFor$1, DEFAULT_OPTION_COUNT_UNIT as DEFAULT_OPTION_COUNT_UNIT$1, optionCountLabel as optionCountLabel$1, optionHasImage as optionHasImage$1, PRODUCT_PATH_PREFIX as PRODUCT_PATH_PREFIX$1, productFromMatchedItem as productFromMatchedItem$1, productsFromCustomFields as productsFromCustomFields$1 } from '@magicx-eng/ai-autocomplete-vanilla';
1
+ import { WEEKDAY_LABELS as WEEKDAY_LABELS$1, cellIso as cellIso$1, monthLabel as monthLabel$1, cellDay as cellDay$1, isoDate as isoDate$1, dateCellMarks as dateCellMarks$1, visibleDateRange as visibleDateRange$1, productInitial, attachProductRowWheel, optionsGridTemplateColumns, optionLabel as optionLabel$1, optionImageSrc as optionImageSrc$1, formatOptionCount as formatOptionCount$1, sanitizeOptionIconSvg as sanitizeOptionIconSvg$1, planOptionsGrid, sameOptionRows, isOptionsGridMobileViewport, needsOptionsGridMeasurement, measureOptionsGrid, optionEnterDelayMs, SCROLL_ARROW_LABEL, buildAttributionUrl, containScroll, attachScrollArrow, isCalendarFormat, getFooterHint, AIAutocomplete, dateSelectionFor, identifiedParamLabel, renderEditableContent, chipIdFromTap, keepCaretOnChip, getCursorOffset, extractPlainText, plainTextLength, setCursorOffset, ModeController, buildSubmitResult as buildSubmitResult$1, withSkippedParams as withSkippedParams$1, formatDate as formatDate$1, parseDate as parseDate$1, parseLooseDate as parseLooseDate$1, DATE_RANGE_META_END as DATE_RANGE_META_END$1, DATE_RANGE_META_START as DATE_RANGE_META_START$1, formatDateRange as formatDateRange$1, parseLooseDateRange as parseLooseDateRange$1, selectedRangeFor as selectedRangeFor$1, DEFAULT_OPTION_COUNT_UNIT as DEFAULT_OPTION_COUNT_UNIT$1, optionCountLabel as optionCountLabel$1, optionHasImage as optionHasImage$1, PRODUCT_PATH_PREFIX as PRODUCT_PATH_PREFIX$1, productFromMatchedItem as productFromMatchedItem$1, productsFromCustomFields as productsFromCustomFields$1 } from '@magicx-eng/ai-autocomplete-vanilla';
2
2
  import * as i1 from '@angular/common';
3
3
  import { CommonModule, isPlatformBrowser } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
@@ -1355,6 +1355,15 @@ class AIAutocompleteController {
1355
1355
  return;
1356
1356
  this.core.reset();
1357
1357
  }
1358
+ /**
1359
+ * Records a submit in telemetry. Enter is recorded by the SDK; call this
1360
+ * from a submit button you render, so each submit is counted once.
1361
+ */
1362
+ recordSubmit(result) {
1363
+ if (this.isDestroyed)
1364
+ return;
1365
+ this.core.recordSubmit(result);
1366
+ }
1358
1367
  /** Pick a dropdown option (or replace the re-edited param if in re-edit mode). */
1359
1368
  selectOption(option) {
1360
1369
  if (this.isDestroyed)
@@ -1729,6 +1738,23 @@ class AIAutocompleteEditorHostDirective {
1729
1738
  }
1730
1739
  }
1731
1740
  // === Host event handlers ===
1741
+ /**
1742
+ * A tap on a chip opens *that* chip. Touch browsers place the caret where
1743
+ * they see fit (iOS snaps it to a word boundary, and the focusing tap often
1744
+ * parks it at the end of the text — inside the last chip when the input ends
1745
+ * with one), so the selectionchange path can miss the tapped chip or open
1746
+ * the wrong one. The click target is the element actually hit and overrides
1747
+ * it; `keepCaretOnChip` then pulls a stray caret onto the tapped chip so the
1748
+ * next selectionchange doesn't close or redirect what the tap opened.
1749
+ */
1750
+ onClick(event) {
1751
+ const el = this.el.nativeElement;
1752
+ const id = chipIdFromTap(el, event.target);
1753
+ if (!id)
1754
+ return;
1755
+ this.controller.startEditingParam(id);
1756
+ keepCaretOnChip(el, id);
1757
+ }
1732
1758
  onCompositionStart() {
1733
1759
  this.composing = true;
1734
1760
  }
@@ -1876,7 +1902,7 @@ class AIAutocompleteEditorHostDirective {
1876
1902
  }
1877
1903
  }
1878
1904
  AIAutocompleteEditorHostDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteEditorHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1879
- AIAutocompleteEditorHostDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteEditorHostDirective, isStandalone: true, selector: "[aiaEditorHost]", inputs: { controller: ["aiaEditorHost", "controller"], autoFocus: "autoFocus", showChipIcons: "showChipIcons", showChipImages: "showChipImages" }, host: { attributes: { "role": "combobox", "aria-autocomplete": "list", "aria-haspopup": "listbox", "spellcheck": "true", "enterkeyhint": "send", "tabindex": "0" }, listeners: { "input": "onInput()", "keydown": "onKeyDown($event)", "compositionstart": "onCompositionStart()", "compositionend": "onCompositionEnd()", "paste": "onPaste($event)", "focus": "onFocus()", "blur": "onBlur()" } }, usesOnChanges: true, ngImport: i0 });
1905
+ AIAutocompleteEditorHostDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteEditorHostDirective, isStandalone: true, selector: "[aiaEditorHost]", inputs: { controller: ["aiaEditorHost", "controller"], autoFocus: "autoFocus", showChipIcons: "showChipIcons", showChipImages: "showChipImages" }, host: { attributes: { "role": "combobox", "aria-autocomplete": "list", "aria-haspopup": "listbox", "spellcheck": "true", "enterkeyhint": "send", "tabindex": "0" }, listeners: { "input": "onInput()", "keydown": "onKeyDown($event)", "compositionstart": "onCompositionStart()", "compositionend": "onCompositionEnd()", "paste": "onPaste($event)", "click": "onClick($event)", "focus": "onFocus()", "blur": "onBlur()" } }, usesOnChanges: true, ngImport: i0 });
1880
1906
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteEditorHostDirective, decorators: [{
1881
1907
  type: Directive,
1882
1908
  args: [{
@@ -1894,6 +1920,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
1894
1920
  "(compositionstart)": "onCompositionStart()",
1895
1921
  "(compositionend)": "onCompositionEnd()",
1896
1922
  "(paste)": "onPaste($event)",
1923
+ "(click)": "onClick($event)",
1897
1924
  "(focus)": "onFocus()",
1898
1925
  "(blur)": "onBlur()",
1899
1926
  },
@@ -2047,6 +2074,7 @@ class AIAutocompleteComponent {
2047
2074
  this.controller = new AIAutocompleteController({
2048
2075
  apiConfig: this.apiConfig,
2049
2076
  additionalContext: this.additionalContext,
2077
+ visitorId: this.visitorId,
2050
2078
  optionOverrides: this.optionOverrides,
2051
2079
  maskCompletedText: this.maskCompletedText,
2052
2080
  columns: this.columns,
@@ -2131,6 +2159,7 @@ class AIAutocompleteComponent {
2131
2159
  // Reactive options
2132
2160
  if (changes["apiConfig"] ||
2133
2161
  changes["additionalContext"] ||
2162
+ changes["visitorId"] ||
2134
2163
  changes["optionOverrides"] ||
2135
2164
  changes["dropdownTrigger"] ||
2136
2165
  changes["optionsPosition"] ||
@@ -2141,6 +2170,7 @@ class AIAutocompleteComponent {
2141
2170
  this.controller.update({
2142
2171
  apiConfig: this.apiConfig,
2143
2172
  additionalContext: this.additionalContext,
2173
+ visitorId: this.visitorId,
2144
2174
  optionOverrides: this.optionOverrides,
2145
2175
  dropdownTrigger: this.dropdownTrigger,
2146
2176
  optionsPosition: this.optionsPosition,
@@ -2273,18 +2303,23 @@ class AIAutocompleteComponent {
2273
2303
  * the React component uses — so the emitted query reflects whatever's in
2274
2304
  * the DOM right now, not a possibly-stale state snapshot.
2275
2305
  */
2276
- handleSubmit(_result) {
2306
+ // `fromButton`: the SDK records an Enter submit itself before it calls back
2307
+ // here; a click on our own button never passes through it.
2308
+ handleSubmit(_result, fromButton = false) {
2277
2309
  const editor = this.editorRef?.nativeElement;
2278
2310
  if (!editor)
2279
2311
  return;
2280
2312
  const text = extractPlainText(editor);
2281
2313
  const state = this.controller.getState();
2282
2314
  const params = this.completedParams ?? state.completedParams;
2283
- this.submitted.emit(buildSubmitResult$1(text, params, state.skippedParams, {
2315
+ const result = buildSubmitResult$1(text, params, state.skippedParams, {
2284
2316
  identifiedParams: state.identifiedParams,
2285
2317
  isReady: state.isReady,
2286
2318
  customFields: state.customFields,
2287
- }));
2319
+ });
2320
+ if (fromButton)
2321
+ this.controller.recordSubmit(result);
2322
+ this.submitted.emit(result);
2288
2323
  if (this.resetOnSubmit)
2289
2324
  this.controller.reset();
2290
2325
  }
@@ -2301,7 +2336,7 @@ class AIAutocompleteComponent {
2301
2336
  completed_params: [],
2302
2337
  identified_params: [],
2303
2338
  is_ready: state.isReady,
2304
- });
2339
+ }, true);
2305
2340
  }
2306
2341
  measurePillWrap() {
2307
2342
  const container = this.pillContainerRef?.nativeElement;
@@ -2328,7 +2363,7 @@ class AIAutocompleteComponent {
2328
2363
  }
2329
2364
  }
2330
2365
  AIAutocompleteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2331
- AIAutocompleteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteComponent, isStandalone: true, selector: "ai-autocomplete", inputs: { apiConfig: "apiConfig", additionalContext: "additionalContext", optionOverrides: "optionOverrides", maskCompletedText: "maskCompletedText", columns: "columns", pillPlacement: "pillPlacement", mode: "mode", optionsPosition: "optionsPosition", animations: "animations", dropdownTrigger: "dropdownTrigger", closeDropdownOnBlur: "closeDropdownOnBlur", showNonTappableOptions: "showNonTappableOptions", showSkipButton: "showSkipButton", showOptionIcons: "showOptionIcons", showOptionImages: "showOptionImages", showOptionCounts: "showOptionCounts", productsLayout: "productsLayout", productImageFallback: "productImageFallback", showChipIcons: "showChipIcons", showChipImages: "showChipImages", autoFocus: "autoFocus", value: "value", completedParams: "completedParams", showProducts: "showProducts", products: "products", submitButton: "submitButton", resetOnSubmit: "resetOnSubmit" }, outputs: { submitted: "submitted", resultChange: "resultChange", errored: "errored", valueChange: "valueChange", completedParamsChange: "completedParamsChange", focused: "focused", blurred: "blurred", productSelect: "productSelect" }, providers: [
2366
+ AIAutocompleteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteComponent, isStandalone: true, selector: "ai-autocomplete", inputs: { apiConfig: "apiConfig", additionalContext: "additionalContext", visitorId: "visitorId", optionOverrides: "optionOverrides", maskCompletedText: "maskCompletedText", columns: "columns", pillPlacement: "pillPlacement", mode: "mode", optionsPosition: "optionsPosition", animations: "animations", dropdownTrigger: "dropdownTrigger", closeDropdownOnBlur: "closeDropdownOnBlur", showNonTappableOptions: "showNonTappableOptions", showSkipButton: "showSkipButton", showOptionIcons: "showOptionIcons", showOptionImages: "showOptionImages", showOptionCounts: "showOptionCounts", productsLayout: "productsLayout", productImageFallback: "productImageFallback", showChipIcons: "showChipIcons", showChipImages: "showChipImages", autoFocus: "autoFocus", value: "value", completedParams: "completedParams", showProducts: "showProducts", products: "products", submitButton: "submitButton", resetOnSubmit: "resetOnSubmit" }, outputs: { submitted: "submitted", resultChange: "resultChange", errored: "errored", valueChange: "valueChange", completedParamsChange: "completedParamsChange", focused: "focused", blurred: "blurred", productSelect: "productSelect" }, providers: [
2332
2367
  {
2333
2368
  provide: NG_VALUE_ACCESSOR,
2334
2369
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
@@ -2356,6 +2391,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
2356
2391
  type: Input
2357
2392
  }], additionalContext: [{
2358
2393
  type: Input
2394
+ }], visitorId: [{
2395
+ type: Input
2359
2396
  }], optionOverrides: [{
2360
2397
  type: Input
2361
2398
  }], maskCompletedText: [{