@magicx-eng/ai-autocomplete-angular 0.2.0 → 0.3.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.
- package/esm2020/lib/ai-autocomplete/ai-autocomplete.component.mjs +6 -4
- package/esm2020/lib/ai-autocomplete-dropdown/ai-autocomplete-dropdown.component.mjs +33 -5
- package/esm2020/lib/controller/ai-autocomplete.controller.mjs +5 -1
- package/esm2020/lib/internal/layout/cluster.component.mjs +45 -0
- package/esm2020/lib/internal/layout/grid.component.mjs +95 -0
- package/esm2020/lib/internal/layout/stack.component.mjs +29 -0
- package/esm2020/lib/internal/pill-list/pill-list.component.mjs +27 -8
- package/esm2020/lib/internal/submit-button/submit-button.component.mjs +29 -0
- package/esm2020/lib/internal/suggestion-grid/suggestion-grid.component.mjs +10 -62
- package/esm2020/lib/internal/suggestion-item/suggestion-item.component.mjs +3 -3
- package/esm2020/lib/shared/types.mjs +1 -1
- package/fesm2015/magicx-eng-ai-autocomplete-angular.mjs +267 -81
- package/fesm2015/magicx-eng-ai-autocomplete-angular.mjs.map +1 -1
- package/fesm2020/magicx-eng-ai-autocomplete-angular.mjs +263 -77
- package/fesm2020/magicx-eng-ai-autocomplete-angular.mjs.map +1 -1
- package/lib/ai-autocomplete/ai-autocomplete.component.d.ts +1 -1
- package/lib/ai-autocomplete/ai-autocomplete.component.d.ts.map +1 -1
- package/lib/ai-autocomplete-dropdown/ai-autocomplete-dropdown.component.d.ts +5 -1
- package/lib/ai-autocomplete-dropdown/ai-autocomplete-dropdown.component.d.ts.map +1 -1
- package/lib/controller/ai-autocomplete.controller.d.ts +6 -0
- package/lib/controller/ai-autocomplete.controller.d.ts.map +1 -1
- package/lib/internal/layout/cluster.component.d.ts +23 -0
- package/lib/internal/layout/cluster.component.d.ts.map +1 -0
- package/lib/internal/layout/grid.component.d.ts +43 -0
- package/lib/internal/layout/grid.component.d.ts.map +1 -0
- package/lib/internal/layout/stack.component.d.ts +16 -0
- package/lib/internal/layout/stack.component.d.ts.map +1 -0
- package/lib/internal/pill-list/pill-list.component.d.ts +16 -3
- package/lib/internal/pill-list/pill-list.component.d.ts.map +1 -1
- package/lib/internal/submit-button/submit-button.component.d.ts +17 -0
- package/lib/internal/submit-button/submit-button.component.d.ts.map +1 -0
- package/lib/internal/suggestion-grid/suggestion-grid.component.d.ts +7 -20
- package/lib/internal/suggestion-grid/suggestion-grid.component.d.ts.map +1 -1
- package/lib/shared/types.d.ts +6 -0
- package/lib/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,16 +1,86 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import {
|
|
4
|
+
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input, EventEmitter, Output, inject, NgZone, ChangeDetectorRef, ViewChild, ElementRef, Renderer2, Directive, PLATFORM_ID, forwardRef, NgModule } from '@angular/core';
|
|
5
5
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
|
-
import { AIAutocomplete, getCursorOffset, extractPlainText, renderEditableContent, plainTextLength, setCursorOffset, ModeController, buildQuery } from '@magicx-eng/ai-autocomplete-vanilla';
|
|
6
|
+
import { getFooterHint, AIAutocomplete, getCursorOffset, extractPlainText, renderEditableContent, plainTextLength, setCursorOffset, ModeController, buildQuery } from '@magicx-eng/ai-autocomplete-vanilla';
|
|
7
7
|
import { BehaviorSubject, combineLatest, map as map$1, distinctUntilChanged, shareReplay, Subject, takeUntil } from 'rxjs';
|
|
8
8
|
import { map } from 'rxjs/operators';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Horizontal layout primitive — children sit in a row and wrap when out of
|
|
12
|
+
* room. Mirrors the React `<Cluster>` component / vanilla `.aia-cluster` CSS
|
|
13
|
+
* primitive. `noWrap` keeps a single row; `inline` makes it inline-level.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
class ClusterComponent {
|
|
18
|
+
constructor() {
|
|
19
|
+
/** Cross-axis alignment. Defaults to `center`. */
|
|
20
|
+
this.align = "center";
|
|
21
|
+
/** Main-axis distribution. Defaults to `start`. */
|
|
22
|
+
this.justify = "start";
|
|
23
|
+
/** When true, the cluster does NOT flex-wrap (single-row clusters). */
|
|
24
|
+
this.noWrap = false;
|
|
25
|
+
/** Render inline-level (inline-flex) instead of block. */
|
|
26
|
+
this.inline = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
ClusterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ClusterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
30
|
+
ClusterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ClusterComponent, isStandalone: true, selector: "aia-cluster", inputs: { gap: "gap", align: "align", justify: "justify", noWrap: "noWrap", inline: "inline" }, host: { properties: { "attr.data-align": "align", "attr.data-justify": "justify", "attr.data-nowrap": "noWrap ? '' : null", "attr.data-inline": "inline ? '' : null", "style.--aia-cluster-gap": "gap" }, classAttribute: "aia-cluster" }, ngImport: i0, template: "<ng-content></ng-content>", isInline: true, styles: ["@layer layout{.aia-cluster{display:flex;flex-wrap:wrap;gap:var(--aia-cluster-gap, .5rem)}.aia-cluster[data-inline]{display:inline-flex}.aia-cluster[data-nowrap]{flex-wrap:nowrap}.aia-cluster[data-align=start]{align-items:start}.aia-cluster[data-align=center]{align-items:center}.aia-cluster[data-align=end]{align-items:end}.aia-cluster[data-align=baseline]{align-items:baseline}.aia-cluster[data-justify=start]{justify-content:start}.aia-cluster[data-justify=center]{justify-content:center}.aia-cluster[data-justify=end]{justify-content:end}.aia-cluster[data-justify=between]{justify-content:space-between}.aia-cluster[data-justify=around]{justify-content:space-around}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
31
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ClusterComponent, decorators: [{
|
|
32
|
+
type: Component,
|
|
33
|
+
args: [{ selector: "aia-cluster", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-content></ng-content>", host: {
|
|
34
|
+
class: "aia-cluster",
|
|
35
|
+
"[attr.data-align]": "align",
|
|
36
|
+
"[attr.data-justify]": "justify",
|
|
37
|
+
"[attr.data-nowrap]": "noWrap ? '' : null",
|
|
38
|
+
"[attr.data-inline]": "inline ? '' : null",
|
|
39
|
+
"[style.--aia-cluster-gap]": "gap",
|
|
40
|
+
}, styles: ["@layer layout{.aia-cluster{display:flex;flex-wrap:wrap;gap:var(--aia-cluster-gap, .5rem)}.aia-cluster[data-inline]{display:inline-flex}.aia-cluster[data-nowrap]{flex-wrap:nowrap}.aia-cluster[data-align=start]{align-items:start}.aia-cluster[data-align=center]{align-items:center}.aia-cluster[data-align=end]{align-items:end}.aia-cluster[data-align=baseline]{align-items:baseline}.aia-cluster[data-justify=start]{justify-content:start}.aia-cluster[data-justify=center]{justify-content:center}.aia-cluster[data-justify=end]{justify-content:end}.aia-cluster[data-justify=between]{justify-content:space-between}.aia-cluster[data-justify=around]{justify-content:space-around}}\n"] }]
|
|
41
|
+
}], propDecorators: { gap: [{
|
|
42
|
+
type: Input
|
|
43
|
+
}], align: [{
|
|
44
|
+
type: Input
|
|
45
|
+
}], justify: [{
|
|
46
|
+
type: Input
|
|
47
|
+
}], noWrap: [{
|
|
48
|
+
type: Input
|
|
49
|
+
}], inline: [{
|
|
50
|
+
type: Input
|
|
51
|
+
}] } });
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Vertical layout primitive — children stack top-to-bottom with `space` gap.
|
|
55
|
+
* Mirrors the React `<Stack>` component / vanilla `.aia-stack` CSS primitive.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
class StackComponent {
|
|
60
|
+
constructor() {
|
|
61
|
+
/** Cross-axis alignment of children. Defaults to `stretch` (full width). */
|
|
62
|
+
this.align = "stretch";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
StackComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: StackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
66
|
+
StackComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: StackComponent, isStandalone: true, selector: "aia-stack", inputs: { space: "space", align: "align" }, host: { properties: { "attr.data-align": "align", "style.--aia-stack-space": "space" }, classAttribute: "aia-stack" }, ngImport: i0, template: "<ng-content></ng-content>", isInline: true, styles: ["@layer layout{.aia-stack{display:flex;flex-direction:column;gap:var(--aia-stack-space, .5rem)}.aia-stack[data-align=start]{align-items:start}.aia-stack[data-align=center]{align-items:center}.aia-stack[data-align=end]{align-items:end}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: StackComponent, decorators: [{
|
|
68
|
+
type: Component,
|
|
69
|
+
args: [{ selector: "aia-stack", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-content></ng-content>", host: {
|
|
70
|
+
class: "aia-stack",
|
|
71
|
+
"[attr.data-align]": "align",
|
|
72
|
+
"[style.--aia-stack-space]": "space",
|
|
73
|
+
}, styles: ["@layer layout{.aia-stack{display:flex;flex-direction:column;gap:var(--aia-stack-space, .5rem)}.aia-stack[data-align=start]{align-items:start}.aia-stack[data-align=center]{align-items:center}.aia-stack[data-align=end]{align-items:end}}\n"] }]
|
|
74
|
+
}], propDecorators: { space: [{
|
|
75
|
+
type: Input
|
|
76
|
+
}], align: [{
|
|
77
|
+
type: Input
|
|
78
|
+
}] } });
|
|
79
|
+
|
|
10
80
|
/**
|
|
11
81
|
* Internal pill list used by both the dropdown and Tier 1's inline pillbar.
|
|
12
82
|
* Mirrors `packages/react/src/components/PillList.tsx` one-for-one — including
|
|
13
|
-
* the per-index opacity ramp (0.
|
|
83
|
+
* the per-index opacity ramp (1 / 0.7 / 0.4 / 0.2) and the skeleton-loading
|
|
14
84
|
* fallback that preserves layout while the next fetch is in flight.
|
|
15
85
|
*
|
|
16
86
|
* @internal
|
|
@@ -27,19 +97,36 @@ class PillListComponent {
|
|
|
27
97
|
* rendered instead.
|
|
28
98
|
*/
|
|
29
99
|
this.loading = false;
|
|
100
|
+
/**
|
|
101
|
+
* Whether the active (leading) pill should render selected (full opacity)
|
|
102
|
+
* rather than its positional `first` tier. Auto trigger ⇒ true while a
|
|
103
|
+
* dropdown option is highlighted; manual trigger ⇒ true after the user taps
|
|
104
|
+
* the pill. See `AIAutocompleteController.isActivePillSelected$`.
|
|
105
|
+
*/
|
|
106
|
+
this.activeSelected = false;
|
|
30
107
|
this.selectPill = new EventEmitter();
|
|
31
108
|
/** Fallback widths when loading with zero cached pills (matches React). */
|
|
32
109
|
this.fallbackSkeletonWidths = [125, 69];
|
|
33
110
|
this.trackByType = (_, pill) => pill.type;
|
|
34
111
|
this.trackByWidth = (_, w) => w;
|
|
35
112
|
}
|
|
36
|
-
/**
|
|
113
|
+
/** The active pill is "selected" only when `activeSelected` is set. */
|
|
114
|
+
isSelected(index) {
|
|
115
|
+
return this.activeSelected && index === this.activePillIndex;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Opacity per pill state — mirrors PillList.tsx `PILL_OPACITY`. The selected
|
|
119
|
+
* pill is full opacity; otherwise pills take a positional tier (first / next
|
|
120
|
+
* / last).
|
|
121
|
+
*/
|
|
37
122
|
pillOpacity(index) {
|
|
123
|
+
if (this.isSelected(index))
|
|
124
|
+
return 1; // Selected
|
|
38
125
|
if (index === 0)
|
|
39
|
-
return 0.
|
|
126
|
+
return 0.7; // First
|
|
40
127
|
if (index === 1)
|
|
41
|
-
return 0.
|
|
42
|
-
return 0.
|
|
128
|
+
return 0.4; // Next
|
|
129
|
+
return 0.2; // Last
|
|
43
130
|
}
|
|
44
131
|
onPillClick(index) {
|
|
45
132
|
if (this.loading)
|
|
@@ -52,10 +139,10 @@ class PillListComponent {
|
|
|
52
139
|
}
|
|
53
140
|
}
|
|
54
141
|
PillListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PillListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
55
|
-
PillListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PillListComponent, isStandalone: true, selector: "aia-pill-list", inputs: { pills: "pills", activePillIndex: "activePillIndex", rounded: "rounded", loading: "loading" }, outputs: { selectPill: "selectPill" }, ngImport: i0, template: "<ng-container *ngIf=\"loading && pills.length === 0; else realPills\">\n <span class=\"aia-pill-list\" data-aia-pill-list-loading=\"\">\n <span\n *ngFor=\"let w of fallbackSkeletonWidths; trackBy: trackByWidth; let i = index\"\n data-aia-pill-skeleton=\"\"\n class=\"aia-pill aia-pill-skeleton\"\n [class.aia-pill-rounded]=\"rounded\"\n [style.width.px]=\"w\"\n [style.opacity]=\"pillOpacity(i)\"\n ></span>\n </span>\n</ng-container>\n\n<ng-template #realPills>\n <span\n class=\"aia-pill-list\"\n [attr.data-aia-pill-list-loading]=\"loading ? '' : null\"\n >\n <button\n *ngFor=\"let pill of pills; trackBy: trackByType; let i = index\"\n type=\"button\"\n data-aia-pill=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n tabindex=\"-1\"\n class=\"aia-pill\"\n [class.aia-pill-rounded]=\"rounded\"\n [class.aia-pill-active]=\"i
|
|
142
|
+
PillListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: PillListComponent, isStandalone: true, selector: "aia-pill-list", inputs: { pills: "pills", activePillIndex: "activePillIndex", rounded: "rounded", loading: "loading", activeSelected: "activeSelected" }, outputs: { selectPill: "selectPill" }, ngImport: i0, template: "<ng-container *ngIf=\"loading && pills.length === 0; else realPills\">\n <span class=\"aia-pill-list\" data-aia-pill-list-loading=\"\">\n <span\n *ngFor=\"let w of fallbackSkeletonWidths; trackBy: trackByWidth; let i = index\"\n data-aia-pill-skeleton=\"\"\n class=\"aia-pill aia-pill-skeleton\"\n [class.aia-pill-rounded]=\"rounded\"\n [style.width.px]=\"w\"\n [style.opacity]=\"pillOpacity(i)\"\n ></span>\n </span>\n</ng-container>\n\n<ng-template #realPills>\n <span\n class=\"aia-pill-list\"\n [attr.data-aia-pill-list-loading]=\"loading ? '' : null\"\n >\n <button\n *ngFor=\"let pill of pills; trackBy: trackByType; let i = index\"\n type=\"button\"\n data-aia-pill=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n tabindex=\"-1\"\n class=\"aia-pill\"\n [class.aia-pill-rounded]=\"rounded\"\n [class.aia-pill-active]=\"isSelected(i) && !loading\"\n [class.aia-pill-skeleton]=\"loading\"\n [style.opacity]=\"pillOpacity(i)\"\n [disabled]=\"loading\"\n (mousedown)=\"onPillMouseDown($event)\"\n (click)=\"onPillClick(i)\"\n >\n {{ pill.text }}\n </button>\n </span>\n</ng-template>\n", styles: [".aia-pill-list{position:relative;z-index:1;pointer-events:auto;display:inline-flex;gap:7px;align-items:center;vertical-align:middle}.aia-pill{display:inline-flex;align-items:center;justify-content:center;padding:7px 8px;border:none;border-radius:999px;background:rgba(49,50,85,.25);background:color-mix(in srgb,var(--aia-pill-bg, var(--aia-color-background-supportive, #313255)) 30%,transparent);color:var(--aia-pill-color, var(--aia-color-text-muted, #c1c4cb));font-family:inherit;font-size:var(--aia-pill-font-size, 14px);font-weight:500;line-height:normal;cursor:pointer;white-space:nowrap;animation:aiaPillFadeIn .4s cubic-bezier(.4,0,.2,1) forwards}.aia-pill-rounded{border-radius:999px}.aia-pill-skeleton{pointer-events:none;cursor:default;color:transparent;animation:aiaPillSkeletonPulse 1.4s ease-in-out infinite}@keyframes aiaPillFadeIn{0%{opacity:0}}@keyframes aiaPillSkeletonPulse{0%,to{filter:brightness(1)}50%{filter:brightness(.55)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
56
143
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PillListComponent, decorators: [{
|
|
57
144
|
type: Component,
|
|
58
|
-
args: [{ selector: "aia-pill-list", standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"loading && pills.length === 0; else realPills\">\n <span class=\"aia-pill-list\" data-aia-pill-list-loading=\"\">\n <span\n *ngFor=\"let w of fallbackSkeletonWidths; trackBy: trackByWidth; let i = index\"\n data-aia-pill-skeleton=\"\"\n class=\"aia-pill aia-pill-skeleton\"\n [class.aia-pill-rounded]=\"rounded\"\n [style.width.px]=\"w\"\n [style.opacity]=\"pillOpacity(i)\"\n ></span>\n </span>\n</ng-container>\n\n<ng-template #realPills>\n <span\n class=\"aia-pill-list\"\n [attr.data-aia-pill-list-loading]=\"loading ? '' : null\"\n >\n <button\n *ngFor=\"let pill of pills; trackBy: trackByType; let i = index\"\n type=\"button\"\n data-aia-pill=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n tabindex=\"-1\"\n class=\"aia-pill\"\n [class.aia-pill-rounded]=\"rounded\"\n [class.aia-pill-active]=\"i
|
|
145
|
+
args: [{ selector: "aia-pill-list", standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"loading && pills.length === 0; else realPills\">\n <span class=\"aia-pill-list\" data-aia-pill-list-loading=\"\">\n <span\n *ngFor=\"let w of fallbackSkeletonWidths; trackBy: trackByWidth; let i = index\"\n data-aia-pill-skeleton=\"\"\n class=\"aia-pill aia-pill-skeleton\"\n [class.aia-pill-rounded]=\"rounded\"\n [style.width.px]=\"w\"\n [style.opacity]=\"pillOpacity(i)\"\n ></span>\n </span>\n</ng-container>\n\n<ng-template #realPills>\n <span\n class=\"aia-pill-list\"\n [attr.data-aia-pill-list-loading]=\"loading ? '' : null\"\n >\n <button\n *ngFor=\"let pill of pills; trackBy: trackByType; let i = index\"\n type=\"button\"\n data-aia-pill=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n tabindex=\"-1\"\n class=\"aia-pill\"\n [class.aia-pill-rounded]=\"rounded\"\n [class.aia-pill-active]=\"isSelected(i) && !loading\"\n [class.aia-pill-skeleton]=\"loading\"\n [style.opacity]=\"pillOpacity(i)\"\n [disabled]=\"loading\"\n (mousedown)=\"onPillMouseDown($event)\"\n (click)=\"onPillClick(i)\"\n >\n {{ pill.text }}\n </button>\n </span>\n</ng-template>\n", styles: [".aia-pill-list{position:relative;z-index:1;pointer-events:auto;display:inline-flex;gap:7px;align-items:center;vertical-align:middle}.aia-pill{display:inline-flex;align-items:center;justify-content:center;padding:7px 8px;border:none;border-radius:999px;background:rgba(49,50,85,.25);background:color-mix(in srgb,var(--aia-pill-bg, var(--aia-color-background-supportive, #313255)) 30%,transparent);color:var(--aia-pill-color, var(--aia-color-text-muted, #c1c4cb));font-family:inherit;font-size:var(--aia-pill-font-size, 14px);font-weight:500;line-height:normal;cursor:pointer;white-space:nowrap;animation:aiaPillFadeIn .4s cubic-bezier(.4,0,.2,1) forwards}.aia-pill-rounded{border-radius:999px}.aia-pill-skeleton{pointer-events:none;cursor:default;color:transparent;animation:aiaPillSkeletonPulse 1.4s ease-in-out infinite}@keyframes aiaPillFadeIn{0%{opacity:0}}@keyframes aiaPillSkeletonPulse{0%,to{filter:brightness(1)}50%{filter:brightness(.55)}}\n"] }]
|
|
59
146
|
}], propDecorators: { pills: [{
|
|
60
147
|
type: Input
|
|
61
148
|
}], activePillIndex: [{
|
|
@@ -64,10 +151,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
64
151
|
type: Input
|
|
65
152
|
}], loading: [{
|
|
66
153
|
type: Input
|
|
154
|
+
}], activeSelected: [{
|
|
155
|
+
type: Input
|
|
67
156
|
}], selectPill: [{
|
|
68
157
|
type: Output
|
|
69
158
|
}] } });
|
|
70
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Intrinsic grid layout primitive — auto-fits as many columns as fit between
|
|
162
|
+
* `min` and `max` wide, wrapping to new rows when there's no more horizontal
|
|
163
|
+
* room. Mirrors the React `<Grid>` component / vanilla `.aia-grid` primitive.
|
|
164
|
+
*
|
|
165
|
+
* Optionally scrolls (`scroll`, capped height) with a bottom fade overlay
|
|
166
|
+
* (`fade`) that appears while there's hidden overflow below. The fade is driven
|
|
167
|
+
* by a ResizeObserver + scroll listener + MutationObserver (for projected
|
|
168
|
+
* content changes) — all run outside Angular's zone so high-frequency layout
|
|
169
|
+
* events don't trip change detection (mirrors the former SuggestionGrid).
|
|
170
|
+
*
|
|
171
|
+
* @internal
|
|
172
|
+
*/
|
|
173
|
+
class GridComponent {
|
|
174
|
+
constructor() {
|
|
175
|
+
/** Minimum cell width. CSS length, e.g. "16rem". Columns auto-fit at runtime. */
|
|
176
|
+
this.min = "16rem";
|
|
177
|
+
/** Cap the height and scroll vertically when content overflows. */
|
|
178
|
+
this.scroll = false;
|
|
179
|
+
/** Show a bottom fade overlay while the grid has hidden overflow below. */
|
|
180
|
+
this.fade = false;
|
|
181
|
+
this.hasBottomOverflow = false;
|
|
182
|
+
this.zone = inject(NgZone);
|
|
183
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
184
|
+
}
|
|
185
|
+
ngAfterViewInit() {
|
|
186
|
+
if (!this.fade)
|
|
187
|
+
return;
|
|
188
|
+
this.bindOverflowTracking();
|
|
189
|
+
this.measureOverflow();
|
|
190
|
+
}
|
|
191
|
+
ngOnDestroy() {
|
|
192
|
+
this.resizeObserver?.disconnect();
|
|
193
|
+
this.mutationObserver?.disconnect();
|
|
194
|
+
if (this.scrollListener && this.gridRef) {
|
|
195
|
+
this.gridRef.nativeElement.removeEventListener("scroll", this.scrollListener);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
bindOverflowTracking() {
|
|
199
|
+
const grid = this.gridRef?.nativeElement;
|
|
200
|
+
if (!grid)
|
|
201
|
+
return;
|
|
202
|
+
this.zone.runOutsideAngular(() => {
|
|
203
|
+
this.scrollListener = () => this.measureOverflow();
|
|
204
|
+
grid.addEventListener("scroll", this.scrollListener, { passive: true });
|
|
205
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
206
|
+
this.resizeObserver = new ResizeObserver(() => this.measureOverflow());
|
|
207
|
+
this.resizeObserver.observe(grid);
|
|
208
|
+
}
|
|
209
|
+
// Projected option count changes don't resize the capped grid box, so
|
|
210
|
+
// ResizeObserver misses them — watch the child list directly to match
|
|
211
|
+
// React's useLayoutEffect-on-options re-measure.
|
|
212
|
+
if (typeof MutationObserver !== "undefined") {
|
|
213
|
+
this.mutationObserver = new MutationObserver(() => this.measureOverflow());
|
|
214
|
+
this.mutationObserver.observe(grid, { childList: true, subtree: true });
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
measureOverflow() {
|
|
219
|
+
const grid = this.gridRef?.nativeElement;
|
|
220
|
+
if (!grid)
|
|
221
|
+
return;
|
|
222
|
+
const next = grid.scrollHeight - grid.scrollTop - grid.clientHeight > 1;
|
|
223
|
+
if (next !== this.hasBottomOverflow) {
|
|
224
|
+
this.zone.run(() => {
|
|
225
|
+
this.hasBottomOverflow = next;
|
|
226
|
+
this.cdr.markForCheck();
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
GridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
232
|
+
GridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: GridComponent, isStandalone: true, selector: "aia-grid", inputs: { min: "min", max: "max", gap: "gap", scroll: "scroll", maxHeight: "maxHeight", fade: "fade" }, viewQueries: [{ propertyName: "gridRef", first: true, predicate: ["grid"], descendants: true }], ngImport: i0, template: "<div [class.aia-grid-fade]=\"fade\" [attr.data-fade]=\"fade && hasBottomOverflow ? '' : null\">\n <div\n #grid\n class=\"aia-grid\"\n [attr.data-scroll]=\"scroll ? '' : null\"\n [style.--aia-grid-min]=\"min\"\n [style.--aia-grid-max]=\"max\"\n [style.--aia-grid-gap]=\"gap\"\n [style.--aia-grid-max-height]=\"maxHeight\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: ["aia-grid{display:contents}@layer layout{.aia-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--aia-grid-min),100%),var(--aia-grid-max, 1fr)));gap:var(--aia-grid-gap, 0)}.aia-grid[data-scroll]{grid-auto-rows:min-content;align-content:start;justify-content:start;padding:var(--aia-grid-scroll-pad, 0);max-height:var(--aia-grid-max-height, 200px);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--aia-scrollbar-thumb, rgba(0, 0, 0, .3)) transparent}.aia-grid[data-scroll]::-webkit-scrollbar{width:6px}.aia-grid[data-scroll]::-webkit-scrollbar-track{background:transparent}.aia-grid[data-scroll]::-webkit-scrollbar-thumb{background:var(--aia-scrollbar-thumb, rgba(0, 0, 0, .3));border-radius:3px}.aia-grid-fade{position:relative}.aia-grid-fade:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:50%;pointer-events:none;opacity:0;transition:opacity .15s ease-out;backdrop-filter:blur(12px);mask-image:linear-gradient(to bottom,transparent,white)}.aia-grid-fade[data-fade]:after{opacity:1}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
233
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GridComponent, decorators: [{
|
|
234
|
+
type: Component,
|
|
235
|
+
args: [{ selector: "aia-grid", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div [class.aia-grid-fade]=\"fade\" [attr.data-fade]=\"fade && hasBottomOverflow ? '' : null\">\n <div\n #grid\n class=\"aia-grid\"\n [attr.data-scroll]=\"scroll ? '' : null\"\n [style.--aia-grid-min]=\"min\"\n [style.--aia-grid-max]=\"max\"\n [style.--aia-grid-gap]=\"gap\"\n [style.--aia-grid-max-height]=\"maxHeight\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: ["aia-grid{display:contents}@layer layout{.aia-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--aia-grid-min),100%),var(--aia-grid-max, 1fr)));gap:var(--aia-grid-gap, 0)}.aia-grid[data-scroll]{grid-auto-rows:min-content;align-content:start;justify-content:start;padding:var(--aia-grid-scroll-pad, 0);max-height:var(--aia-grid-max-height, 200px);overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--aia-scrollbar-thumb, rgba(0, 0, 0, .3)) transparent}.aia-grid[data-scroll]::-webkit-scrollbar{width:6px}.aia-grid[data-scroll]::-webkit-scrollbar-track{background:transparent}.aia-grid[data-scroll]::-webkit-scrollbar-thumb{background:var(--aia-scrollbar-thumb, rgba(0, 0, 0, .3));border-radius:3px}.aia-grid-fade{position:relative}.aia-grid-fade:after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:50%;pointer-events:none;opacity:0;transition:opacity .15s ease-out;backdrop-filter:blur(12px);mask-image:linear-gradient(to bottom,transparent,white)}.aia-grid-fade[data-fade]:after{opacity:1}}\n"] }]
|
|
236
|
+
}], propDecorators: { min: [{
|
|
237
|
+
type: Input
|
|
238
|
+
}], max: [{
|
|
239
|
+
type: Input
|
|
240
|
+
}], gap: [{
|
|
241
|
+
type: Input
|
|
242
|
+
}], scroll: [{
|
|
243
|
+
type: Input
|
|
244
|
+
}], maxHeight: [{
|
|
245
|
+
type: Input
|
|
246
|
+
}], fade: [{
|
|
247
|
+
type: Input
|
|
248
|
+
}], gridRef: [{
|
|
249
|
+
type: ViewChild,
|
|
250
|
+
args: ["grid", { static: false }]
|
|
251
|
+
}] } });
|
|
252
|
+
|
|
71
253
|
/**
|
|
72
254
|
* Internal single-option cell used inside the suggestion grid. Mirrors
|
|
73
255
|
* `packages/react/src/components/SuggestionItem.tsx`. Handles:
|
|
@@ -122,10 +304,10 @@ class SuggestionItemComponent {
|
|
|
122
304
|
}
|
|
123
305
|
}
|
|
124
306
|
SuggestionItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SuggestionItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
125
|
-
SuggestionItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SuggestionItemComponent, isStandalone: true, selector: "aia-suggestion-item", inputs: { option: "option", isHighlighted: "isHighlighted", id: "id", loading: "loading" }, outputs: { select: "select", highlight: "highlight" }, ngImport: i0, template: "<div\n [id]=\"id\"\n role=\"option\"\n data-aia-option=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n [attr.aria-selected]=\"isHighlighted\"\n class=\"aia-suggestion-item\"\n [class.aia-suggestion-item-highlighted]=\"isHighlighted && !loading\"\n [class.aia-suggestion-item-tappable]=\"option.is_tappable\"\n [class.aia-suggestion-item-non-tappable]=\"!option.is_tappable\"\n [class.aia-suggestion-item-pressed]=\"pressed\"\n [attr.tabindex]=\"loading || !option.is_tappable ? -1 : 0\"\n (click)=\"onSelect()\"\n (keydown)=\"onKeyDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n <div class=\"aia-suggestion-streaks\"></div>\n <div class=\"aia-suggestion-streaks-vert\"></div>\n <span class=\"aia-suggestion-content\">\n <span class=\"aia-suggestion-text\">\n <ng-container *ngIf=\"option.icon; else noIcon\"\n >{{ option.icon }} {{ option.text }}</ng-container\n >\n <ng-template #noIcon>{{ option.text }}</ng-template>\n </span>\n <span *ngIf=\"option.tag\" class=\"aia-suggestion-tag\">{{ option.tag }}</span>\n </span>\n</div>\n", styles: [".aia-suggestion-item{position:relative;overflow:visible;display:flex;align-items:flex-start;font-family:inherit;font-size:var(--aia-option-font-size,
|
|
307
|
+
SuggestionItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SuggestionItemComponent, isStandalone: true, selector: "aia-suggestion-item", inputs: { option: "option", isHighlighted: "isHighlighted", id: "id", loading: "loading" }, outputs: { select: "select", highlight: "highlight" }, ngImport: i0, template: "<div\n [id]=\"id\"\n role=\"option\"\n data-aia-option=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n [attr.aria-selected]=\"isHighlighted\"\n class=\"aia-suggestion-item\"\n [class.aia-suggestion-item-highlighted]=\"isHighlighted && !loading\"\n [class.aia-suggestion-item-tappable]=\"option.is_tappable\"\n [class.aia-suggestion-item-non-tappable]=\"!option.is_tappable\"\n [class.aia-suggestion-item-pressed]=\"pressed\"\n [attr.tabindex]=\"loading || !option.is_tappable ? -1 : 0\"\n (click)=\"onSelect()\"\n (keydown)=\"onKeyDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n <div class=\"aia-suggestion-streaks\"></div>\n <div class=\"aia-suggestion-streaks-vert\"></div>\n <span class=\"aia-suggestion-content\">\n <span class=\"aia-suggestion-text\">\n <ng-container *ngIf=\"option.icon; else noIcon\"\n >{{ option.icon }} {{ option.text }}</ng-container\n >\n <ng-template #noIcon>{{ option.text }}</ng-template>\n </span>\n <span *ngIf=\"option.tag\" class=\"aia-suggestion-tag\">{{ option.tag }}</span>\n </span>\n</div>\n", styles: [".aia-suggestion-item{position:relative;overflow:visible;display:flex;align-items:flex-start;font-family:inherit;font-size:var(--aia-option-font-size, 14px);font-weight:300;line-height:18px;color:var(--aia-option-color, var(--aia-color-text-muted, #c1c4cb));white-space:normal;word-break:break-word;border-radius:8px;padding:7px 8px;animation:aiaSuggestionFadeIn .5s cubic-bezier(.4,0,.2,1) forwards}@keyframes aiaSuggestionFadeIn{0%{opacity:0}}.aia-suggestion-content{position:relative;z-index:2}.aia-suggestion-item-tappable{cursor:pointer}.aia-suggestion-item-tappable:hover{color:var(--aia-option-color-selected, var(--aia-color-text-default, #fff))}.aia-suggestion-item-non-tappable{cursor:default}.aia-suggestion-item-highlighted{color:var(--aia-option-color-selected, var(--aia-color-text-default, #fff));background:var(--aia-option-bg, transparent);font-weight:700}.aia-suggestion-tag{font-size:11px;margin-left:6px;opacity:.5}.aia-suggestion-item-pressed{opacity:.8;color:var(--aia-color-text-default, #fff);background:rgba(var(--aia-streak-rgb, 255, 255, 255),.06);animation:aiaGlassFade .5s ease forwards,aiaTapDown .5s ease forwards}@keyframes aiaTapDown{0%{transform:scale(1)}30%{transform:scale(.97)}to{transform:scale(1)}}@keyframes aiaGlassFade{0%{background:var(--aia-streak-glass-bg, rgba(255, 255, 255, .1))}to{background:transparent}}.aia-suggestion-streaks{position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;overflow:hidden}.aia-suggestion-streaks:before{content:\"\";position:absolute;bottom:-3px;left:60%;width:0;height:6px;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.5) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.2) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.2);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks:after{content:\"\";position:absolute;top:-3px;right:60%;width:0;height:6px;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.5) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.2) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.2);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks-vert{position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;overflow:hidden}.aia-suggestion-streaks-vert:before{content:\"\";position:absolute;bottom:0;right:-3px;width:6px;height:0;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.4) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.15) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.15);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks-vert:after{content:\"\";position:absolute;top:0;left:-3px;width:6px;height:0;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.4) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.15) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.15);filter:blur(1px);border-radius:50%}.aia-suggestion-item-pressed .aia-suggestion-streaks:before{animation:aiaStreakHorizRight .5s cubic-bezier(.4,0,.2,1) forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks:after{animation:aiaStreakHorizLeft .5s cubic-bezier(.4,0,.2,1) forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks-vert:before{animation:aiaStreakVertUp .3s cubic-bezier(.3,0,.2,1) .2s forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks-vert:after{animation:aiaStreakVertDown .3s cubic-bezier(.3,0,.2,1) .2s forwards}@keyframes aiaStreakHorizRight{0%{width:0;height:4px;opacity:0;filter:blur(1px);box-shadow:0 0 8px 3px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}15%{height:4px;opacity:1;filter:blur(1px);box-shadow:0 0 10px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}80%{width:50%;height:10px;opacity:.8;filter:blur(3px);box-shadow:0 0 16px 6px rgba(var(--aia-streak-rgb, 255, 255, 255),.1)}to{width:50%;height:12px;opacity:0;filter:blur(5px);box-shadow:0 0 20px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.03)}}@keyframes aiaStreakHorizLeft{0%{width:0;height:4px;opacity:0;filter:blur(1px);box-shadow:0 0 8px 3px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}15%{height:4px;opacity:1;filter:blur(1px);box-shadow:0 0 10px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}80%{width:50%;height:10px;opacity:.8;filter:blur(3px);box-shadow:0 0 16px 6px rgba(var(--aia-streak-rgb, 255, 255, 255),.1)}to{width:50%;height:12px;opacity:0;filter:blur(5px);box-shadow:0 0 20px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.03)}}@keyframes aiaStreakVertUp{0%{height:0;width:6px;opacity:.9;filter:blur(1.8px);box-shadow:0 0 12px 5px rgba(var(--aia-streak-rgb, 255, 255, 255),.25)}75%{height:100%;width:10px;opacity:.4;filter:blur(3px);box-shadow:0 0 18px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.06)}to{height:100%;width:14px;opacity:0;filter:blur(5px);box-shadow:0 0 24px 10px rgba(var(--aia-streak-rgb, 255, 255, 255),.02)}}@keyframes aiaStreakVertDown{0%{height:0;width:6px;opacity:.9;filter:blur(1.8px);box-shadow:0 0 12px 5px rgba(var(--aia-streak-rgb, 255, 255, 255),.25)}75%{height:100%;width:10px;opacity:.4;filter:blur(3px);box-shadow:0 0 18px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.06)}to{height:100%;width:14px;opacity:0;filter:blur(5px);box-shadow:0 0 24px 10px rgba(var(--aia-streak-rgb, 255, 255, 255),.02)}}.aia-suggestion-item[data-aia-loading]{cursor:default;animation:aiaSuggestionSkeletonPulse 1.4s ease-in-out infinite}.aia-suggestion-item[data-aia-loading] .aia-suggestion-text{color:transparent;background:var(--aia-skeleton-bg, var(--aia-pill-bg, rgba(189, 189, 189, .51)));border-radius:999px;-webkit-box-decoration-break:clone;box-decoration-break:clone}.aia-suggestion-item[data-aia-loading] .aia-suggestion-tag{display:none}@keyframes aiaSuggestionSkeletonPulse{0%,to{filter:brightness(1)}50%{filter:brightness(.55)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
126
308
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SuggestionItemComponent, decorators: [{
|
|
127
309
|
type: Component,
|
|
128
|
-
args: [{ selector: "aia-suggestion-item", standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n [id]=\"id\"\n role=\"option\"\n data-aia-option=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n [attr.aria-selected]=\"isHighlighted\"\n class=\"aia-suggestion-item\"\n [class.aia-suggestion-item-highlighted]=\"isHighlighted && !loading\"\n [class.aia-suggestion-item-tappable]=\"option.is_tappable\"\n [class.aia-suggestion-item-non-tappable]=\"!option.is_tappable\"\n [class.aia-suggestion-item-pressed]=\"pressed\"\n [attr.tabindex]=\"loading || !option.is_tappable ? -1 : 0\"\n (click)=\"onSelect()\"\n (keydown)=\"onKeyDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n <div class=\"aia-suggestion-streaks\"></div>\n <div class=\"aia-suggestion-streaks-vert\"></div>\n <span class=\"aia-suggestion-content\">\n <span class=\"aia-suggestion-text\">\n <ng-container *ngIf=\"option.icon; else noIcon\"\n >{{ option.icon }} {{ option.text }}</ng-container\n >\n <ng-template #noIcon>{{ option.text }}</ng-template>\n </span>\n <span *ngIf=\"option.tag\" class=\"aia-suggestion-tag\">{{ option.tag }}</span>\n </span>\n</div>\n", styles: [".aia-suggestion-item{position:relative;overflow:visible;display:flex;align-items:flex-start;font-family:inherit;font-size:var(--aia-option-font-size,
|
|
310
|
+
args: [{ selector: "aia-suggestion-item", standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n [id]=\"id\"\n role=\"option\"\n data-aia-option=\"\"\n [attr.data-aia-loading]=\"loading ? '' : null\"\n [attr.aria-selected]=\"isHighlighted\"\n class=\"aia-suggestion-item\"\n [class.aia-suggestion-item-highlighted]=\"isHighlighted && !loading\"\n [class.aia-suggestion-item-tappable]=\"option.is_tappable\"\n [class.aia-suggestion-item-non-tappable]=\"!option.is_tappable\"\n [class.aia-suggestion-item-pressed]=\"pressed\"\n [attr.tabindex]=\"loading || !option.is_tappable ? -1 : 0\"\n (click)=\"onSelect()\"\n (keydown)=\"onKeyDown($event)\"\n (mouseenter)=\"onMouseEnter()\"\n>\n <div class=\"aia-suggestion-streaks\"></div>\n <div class=\"aia-suggestion-streaks-vert\"></div>\n <span class=\"aia-suggestion-content\">\n <span class=\"aia-suggestion-text\">\n <ng-container *ngIf=\"option.icon; else noIcon\"\n >{{ option.icon }} {{ option.text }}</ng-container\n >\n <ng-template #noIcon>{{ option.text }}</ng-template>\n </span>\n <span *ngIf=\"option.tag\" class=\"aia-suggestion-tag\">{{ option.tag }}</span>\n </span>\n</div>\n", styles: [".aia-suggestion-item{position:relative;overflow:visible;display:flex;align-items:flex-start;font-family:inherit;font-size:var(--aia-option-font-size, 14px);font-weight:300;line-height:18px;color:var(--aia-option-color, var(--aia-color-text-muted, #c1c4cb));white-space:normal;word-break:break-word;border-radius:8px;padding:7px 8px;animation:aiaSuggestionFadeIn .5s cubic-bezier(.4,0,.2,1) forwards}@keyframes aiaSuggestionFadeIn{0%{opacity:0}}.aia-suggestion-content{position:relative;z-index:2}.aia-suggestion-item-tappable{cursor:pointer}.aia-suggestion-item-tappable:hover{color:var(--aia-option-color-selected, var(--aia-color-text-default, #fff))}.aia-suggestion-item-non-tappable{cursor:default}.aia-suggestion-item-highlighted{color:var(--aia-option-color-selected, var(--aia-color-text-default, #fff));background:var(--aia-option-bg, transparent);font-weight:700}.aia-suggestion-tag{font-size:11px;margin-left:6px;opacity:.5}.aia-suggestion-item-pressed{opacity:.8;color:var(--aia-color-text-default, #fff);background:rgba(var(--aia-streak-rgb, 255, 255, 255),.06);animation:aiaGlassFade .5s ease forwards,aiaTapDown .5s ease forwards}@keyframes aiaTapDown{0%{transform:scale(1)}30%{transform:scale(.97)}to{transform:scale(1)}}@keyframes aiaGlassFade{0%{background:var(--aia-streak-glass-bg, rgba(255, 255, 255, .1))}to{background:transparent}}.aia-suggestion-streaks{position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;overflow:hidden}.aia-suggestion-streaks:before{content:\"\";position:absolute;bottom:-3px;left:60%;width:0;height:6px;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.5) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.2) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.2);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks:after{content:\"\";position:absolute;top:-3px;right:60%;width:0;height:6px;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.5) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.2) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.2);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks-vert{position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;overflow:hidden}.aia-suggestion-streaks-vert:before{content:\"\";position:absolute;bottom:0;right:-3px;width:6px;height:0;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.4) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.15) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.15);filter:blur(1px);border-radius:50%}.aia-suggestion-streaks-vert:after{content:\"\";position:absolute;top:0;left:-3px;width:6px;height:0;opacity:0;background:radial-gradient(ellipse at center,rgba(var(--aia-streak-rgb, 255, 255, 255),.4) 0%,rgba(var(--aia-streak-rgb, 255, 255, 255),.15) 40%,transparent 70%);box-shadow:0 0 12px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.15);filter:blur(1px);border-radius:50%}.aia-suggestion-item-pressed .aia-suggestion-streaks:before{animation:aiaStreakHorizRight .5s cubic-bezier(.4,0,.2,1) forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks:after{animation:aiaStreakHorizLeft .5s cubic-bezier(.4,0,.2,1) forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks-vert:before{animation:aiaStreakVertUp .3s cubic-bezier(.3,0,.2,1) .2s forwards}.aia-suggestion-item-pressed .aia-suggestion-streaks-vert:after{animation:aiaStreakVertDown .3s cubic-bezier(.3,0,.2,1) .2s forwards}@keyframes aiaStreakHorizRight{0%{width:0;height:4px;opacity:0;filter:blur(1px);box-shadow:0 0 8px 3px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}15%{height:4px;opacity:1;filter:blur(1px);box-shadow:0 0 10px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}80%{width:50%;height:10px;opacity:.8;filter:blur(3px);box-shadow:0 0 16px 6px rgba(var(--aia-streak-rgb, 255, 255, 255),.1)}to{width:50%;height:12px;opacity:0;filter:blur(5px);box-shadow:0 0 20px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.03)}}@keyframes aiaStreakHorizLeft{0%{width:0;height:4px;opacity:0;filter:blur(1px);box-shadow:0 0 8px 3px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}15%{height:4px;opacity:1;filter:blur(1px);box-shadow:0 0 10px 4px rgba(var(--aia-streak-rgb, 255, 255, 255),.3)}80%{width:50%;height:10px;opacity:.8;filter:blur(3px);box-shadow:0 0 16px 6px rgba(var(--aia-streak-rgb, 255, 255, 255),.1)}to{width:50%;height:12px;opacity:0;filter:blur(5px);box-shadow:0 0 20px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.03)}}@keyframes aiaStreakVertUp{0%{height:0;width:6px;opacity:.9;filter:blur(1.8px);box-shadow:0 0 12px 5px rgba(var(--aia-streak-rgb, 255, 255, 255),.25)}75%{height:100%;width:10px;opacity:.4;filter:blur(3px);box-shadow:0 0 18px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.06)}to{height:100%;width:14px;opacity:0;filter:blur(5px);box-shadow:0 0 24px 10px rgba(var(--aia-streak-rgb, 255, 255, 255),.02)}}@keyframes aiaStreakVertDown{0%{height:0;width:6px;opacity:.9;filter:blur(1.8px);box-shadow:0 0 12px 5px rgba(var(--aia-streak-rgb, 255, 255, 255),.25)}75%{height:100%;width:10px;opacity:.4;filter:blur(3px);box-shadow:0 0 18px 8px rgba(var(--aia-streak-rgb, 255, 255, 255),.06)}to{height:100%;width:14px;opacity:0;filter:blur(5px);box-shadow:0 0 24px 10px rgba(var(--aia-streak-rgb, 255, 255, 255),.02)}}.aia-suggestion-item[data-aia-loading]{cursor:default;animation:aiaSuggestionSkeletonPulse 1.4s ease-in-out infinite}.aia-suggestion-item[data-aia-loading] .aia-suggestion-text{color:transparent;background:var(--aia-skeleton-bg, var(--aia-pill-bg, rgba(189, 189, 189, .51)));border-radius:999px;-webkit-box-decoration-break:clone;box-decoration-break:clone}.aia-suggestion-item[data-aia-loading] .aia-suggestion-tag{display:none}@keyframes aiaSuggestionSkeletonPulse{0%,to{filter:brightness(1)}50%{filter:brightness(.55)}}\n"] }]
|
|
129
311
|
}], propDecorators: { option: [{
|
|
130
312
|
type: Input
|
|
131
313
|
}], isHighlighted: [{
|
|
@@ -141,11 +323,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
141
323
|
}] } });
|
|
142
324
|
|
|
143
325
|
/**
|
|
144
|
-
* Internal
|
|
145
|
-
* `packages/react/src/components/SuggestionGrid.tsx` —
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
326
|
+
* Internal grid of suggestion options. Mirrors
|
|
327
|
+
* `packages/react/src/components/SuggestionGrid.tsx` — a thin wrapper over the
|
|
328
|
+
* `Grid` layout primitive (which owns the auto-fit columns and the
|
|
329
|
+
* capped-height scroll + bottom-fade). It only wires each option to its
|
|
330
|
+
* select/highlight handlers and listbox-scoped id.
|
|
149
331
|
*
|
|
150
332
|
* @internal
|
|
151
333
|
*/
|
|
@@ -157,64 +339,14 @@ class SuggestionGridComponent {
|
|
|
157
339
|
this.loading = false;
|
|
158
340
|
this.select = new EventEmitter();
|
|
159
341
|
this.highlight = new EventEmitter();
|
|
160
|
-
this.hasBottomOverflow = false;
|
|
161
|
-
this.zone = inject(NgZone);
|
|
162
|
-
this.cdr = inject(ChangeDetectorRef);
|
|
163
342
|
this.trackByOptionText = (_, opt) => opt.text;
|
|
164
343
|
}
|
|
165
|
-
ngAfterViewInit() {
|
|
166
|
-
this.bindOverflowTracking();
|
|
167
|
-
this.measureOverflow();
|
|
168
|
-
}
|
|
169
|
-
ngOnChanges() {
|
|
170
|
-
// Synchronously re-measure when options change — matches React's
|
|
171
|
-
// useLayoutEffect on [options]. ResizeObserver alone misses this case
|
|
172
|
-
// because the observed box doesn't grow when the grid hits max-height.
|
|
173
|
-
queueMicrotask(() => this.measureOverflow());
|
|
174
|
-
}
|
|
175
|
-
ngOnDestroy() {
|
|
176
|
-
this.resizeObserver?.disconnect();
|
|
177
|
-
if (this.scrollListener && this.gridRef) {
|
|
178
|
-
this.gridRef.nativeElement.removeEventListener("scroll", this.scrollListener);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
onSelectItem(option) {
|
|
182
|
-
this.select.emit(option);
|
|
183
|
-
}
|
|
184
|
-
onHighlightItem(index) {
|
|
185
|
-
this.highlight.emit(index);
|
|
186
|
-
}
|
|
187
|
-
bindOverflowTracking() {
|
|
188
|
-
const grid = this.gridRef?.nativeElement;
|
|
189
|
-
if (!grid)
|
|
190
|
-
return;
|
|
191
|
-
this.zone.runOutsideAngular(() => {
|
|
192
|
-
this.scrollListener = () => this.measureOverflow();
|
|
193
|
-
grid.addEventListener("scroll", this.scrollListener, { passive: true });
|
|
194
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
195
|
-
this.resizeObserver = new ResizeObserver(() => this.measureOverflow());
|
|
196
|
-
this.resizeObserver.observe(grid);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
measureOverflow() {
|
|
201
|
-
const grid = this.gridRef?.nativeElement;
|
|
202
|
-
if (!grid)
|
|
203
|
-
return;
|
|
204
|
-
const next = grid.scrollHeight - grid.scrollTop - grid.clientHeight > 1;
|
|
205
|
-
if (next !== this.hasBottomOverflow) {
|
|
206
|
-
this.zone.run(() => {
|
|
207
|
-
this.hasBottomOverflow = next;
|
|
208
|
-
this.cdr.markForCheck();
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
344
|
}
|
|
213
345
|
SuggestionGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SuggestionGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
214
|
-
SuggestionGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SuggestionGridComponent, isStandalone: true, selector: "aia-suggestion-grid", inputs: { options: "options", activeIndex: "activeIndex", listboxId: "listboxId", loading: "loading" }, outputs: { select: "select", highlight: "highlight" },
|
|
346
|
+
SuggestionGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SuggestionGridComponent, isStandalone: true, selector: "aia-suggestion-grid", inputs: { options: "options", activeIndex: "activeIndex", listboxId: "listboxId", loading: "loading" }, outputs: { select: "select", highlight: "highlight" }, ngImport: i0, template: "<aia-grid min=\"250px\" max=\"250px\" gap=\"0\" [scroll]=\"true\" [fade]=\"true\">\n <aia-suggestion-item\n *ngFor=\"let option of options; trackBy: trackByOptionText; let i = index\"\n [option]=\"option\"\n [isHighlighted]=\"i === activeIndex\"\n [id]=\"listboxId + '-option-' + i\"\n [loading]=\"loading\"\n (select)=\"select.emit($event)\"\n (highlight)=\"highlight.emit(i)\"\n ></aia-suggestion-item>\n</aia-grid>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: GridComponent, selector: "aia-grid", inputs: ["min", "max", "gap", "scroll", "maxHeight", "fade"] }, { kind: "component", type: SuggestionItemComponent, selector: "aia-suggestion-item", inputs: ["option", "isHighlighted", "id", "loading"], outputs: ["select", "highlight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
215
347
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SuggestionGridComponent, decorators: [{
|
|
216
348
|
type: Component,
|
|
217
|
-
args: [{ selector: "aia-suggestion-grid", standalone: true, imports: [CommonModule, SuggestionItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<
|
|
349
|
+
args: [{ selector: "aia-suggestion-grid", standalone: true, imports: [CommonModule, GridComponent, SuggestionItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<aia-grid min=\"250px\" max=\"250px\" gap=\"0\" [scroll]=\"true\" [fade]=\"true\">\n <aia-suggestion-item\n *ngFor=\"let option of options; trackBy: trackByOptionText; let i = index\"\n [option]=\"option\"\n [isHighlighted]=\"i === activeIndex\"\n [id]=\"listboxId + '-option-' + i\"\n [loading]=\"loading\"\n (select)=\"select.emit($event)\"\n (highlight)=\"highlight.emit(i)\"\n ></aia-suggestion-item>\n</aia-grid>\n" }]
|
|
218
350
|
}], propDecorators: { options: [{
|
|
219
351
|
type: Input
|
|
220
352
|
}], activeIndex: [{
|
|
@@ -227,9 +359,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
227
359
|
type: Output
|
|
228
360
|
}], highlight: [{
|
|
229
361
|
type: Output
|
|
230
|
-
}], gridRef: [{
|
|
231
|
-
type: ViewChild,
|
|
232
|
-
args: ["grid", { static: false }]
|
|
233
362
|
}] } });
|
|
234
363
|
|
|
235
364
|
/**
|
|
@@ -258,6 +387,9 @@ class AIAutocompleteDropdownComponent {
|
|
|
258
387
|
// next controller.dropdown$ tick — and we'd lose the showPills update entirely
|
|
259
388
|
// if the controller is idle. Updated from ngOnChanges below.
|
|
260
389
|
this.showPills$ = new BehaviorSubject(true);
|
|
390
|
+
// Last content emitted while the dropdown was visible. Reused during the
|
|
391
|
+
// close fade so the populated dropdown fades out as one — see initVm.
|
|
392
|
+
this.lastVisibleContent = null;
|
|
261
393
|
this.trackByWidth = (_, w) => w;
|
|
262
394
|
}
|
|
263
395
|
ngOnInit() {
|
|
@@ -287,16 +419,32 @@ class AIAutocompleteDropdownComponent {
|
|
|
287
419
|
const showsOptions = options.length > 0;
|
|
288
420
|
const showsFallbackSkeleton = dd.isLoading && !showsOptions;
|
|
289
421
|
const isVisible = dd.isOpen && (showsOptions || showsPills || dd.isLoading);
|
|
290
|
-
|
|
422
|
+
// While closing, reuse the last visible content so the populated
|
|
423
|
+
// dropdown fades out as one. Otherwise the pills/options vanish the
|
|
424
|
+
// instant the state empties (e.g. skipping the last pill with →),
|
|
425
|
+
// leaving the always-present footer alone for a flash of a footer-only
|
|
426
|
+
// "no options" box mid-fade. Only `isVisible` tracks live state to
|
|
427
|
+
// drive the opacity transition.
|
|
428
|
+
if (!isVisible && this.lastVisibleContent) {
|
|
429
|
+
return { ...this.lastVisibleContent, isVisible: false };
|
|
430
|
+
}
|
|
431
|
+
const optionHighlighted = dd.activeIndex >= 0 && Boolean(options[dd.activeIndex]?.is_tappable);
|
|
432
|
+
const { key: footerKey, hint: footerHint } = getFooterHint(dd.hasTabbedToHighlight, optionHighlighted, dd.isInputEmpty);
|
|
433
|
+
const content = {
|
|
291
434
|
pills: dd.pills,
|
|
292
435
|
options,
|
|
293
436
|
activeIndex: dd.activeIndex,
|
|
437
|
+
isActivePillSelected: dd.isActivePillSelected,
|
|
294
438
|
isLoading: dd.isLoading,
|
|
295
439
|
showsPills,
|
|
296
440
|
showsOptions,
|
|
297
441
|
showsFallbackSkeleton,
|
|
298
|
-
|
|
442
|
+
footerKey,
|
|
443
|
+
footerHint,
|
|
299
444
|
};
|
|
445
|
+
if (isVisible)
|
|
446
|
+
this.lastVisibleContent = content;
|
|
447
|
+
return { ...content, isVisible };
|
|
300
448
|
}));
|
|
301
449
|
}
|
|
302
450
|
onPillClick(index) {
|
|
@@ -314,10 +462,16 @@ class AIAutocompleteDropdownComponent {
|
|
|
314
462
|
}
|
|
315
463
|
}
|
|
316
464
|
AIAutocompleteDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
317
|
-
AIAutocompleteDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteDropdownComponent, isStandalone: true, selector: "ai-autocomplete-dropdown", inputs: { controller: "controller", showPills: "showPills", className: "className" }, usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"vm$ | async as vm\"\n [id]=\"controller.listboxId\"\n role=\"listbox\"\n data-aia-dropdown=\"\"\n [attr.data-aia-loading]=\"vm.isLoading ? '' : null\"\n [class]=\"className ? 'magicx-aia-dropdown ' + className : 'magicx-aia-dropdown'\"\n [class.magicx-aia-dropdown-visible]=\"vm.isVisible\"\n (mousedown)=\"preventBlur($event)\"\n>\n <
|
|
465
|
+
AIAutocompleteDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AIAutocompleteDropdownComponent, isStandalone: true, selector: "ai-autocomplete-dropdown", inputs: { controller: "controller", showPills: "showPills", className: "className" }, usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"vm$ | async as vm\"\n [id]=\"controller.listboxId\"\n role=\"listbox\"\n data-aia-dropdown=\"\"\n [attr.data-aia-loading]=\"vm.isLoading ? '' : null\"\n [class]=\"className ? 'magicx-aia-dropdown ' + className : 'magicx-aia-dropdown'\"\n [class.magicx-aia-dropdown-visible]=\"vm.isVisible\"\n (mousedown)=\"preventBlur($event)\"\n>\n <aia-stack space=\"2px\">\n <aia-cluster\n *ngIf=\"vm.showsPills\"\n class=\"magicx-aia-dropdown-pillbar\"\n data-aia-pillbar=\"\"\n [noWrap]=\"true\"\n >\n <aia-pill-list\n [pills]=\"vm.pills\"\n [activePillIndex]=\"0\"\n [activeSelected]=\"vm.isActivePillSelected\"\n [rounded]=\"true\"\n [loading]=\"vm.isLoading\"\n (selectPill)=\"onPillClick($event)\"\n ></aia-pill-list>\n </aia-cluster>\n\n <aia-suggestion-grid\n *ngIf=\"vm.showsOptions\"\n [options]=\"vm.options\"\n [activeIndex]=\"vm.activeIndex\"\n [listboxId]=\"controller.listboxId\"\n [loading]=\"vm.isLoading\"\n (select)=\"onSelect($event)\"\n (highlight)=\"onHighlight($event)\"\n ></aia-suggestion-grid>\n\n <div\n *ngIf=\"vm.showsFallbackSkeleton\"\n class=\"magicx-aia-dropdown-skeleton-bars\"\n data-aia-skeleton-bars=\"\"\n >\n <span\n *ngFor=\"let w of fallbackSkeletonBarWidths; trackBy: trackByWidth\"\n class=\"magicx-aia-dropdown-skeleton-bar\"\n [style.width.px]=\"w\"\n ></span>\n </div>\n\n <footer class=\"magicx-aia-footer\" data-aia-footer=\"\">\n <div class=\"magicx-aia-footer-divider\"></div>\n <div class=\"magicx-aia-footer-row\">\n <span class=\"magicx-aia-footer-hint-group\">\n <kbd class=\"magicx-aia-footer-key\">{{ vm.footerKey }}</kbd>\n <span class=\"magicx-aia-footer-hint\">{{ vm.footerHint }}</span>\n </span>\n <a\n class=\"magicx-aia-footer-brand-link\"\n href=\"https://ai-autocomplete.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span class=\"magicx-aia-footer-brand\">AI</span>\n <span class=\"magicx-aia-footer-badge\">Autocomplete</span>\n </a>\n </div>\n </footer>\n </aia-stack>\n</div>\n", styles: [".magicx-aia-dropdown{position:absolute;left:0;right:0;top:100%;max-width:544px;margin-top:6px;display:flex;flex-direction:column;box-sizing:border-box;padding:4px;overflow:hidden;container-type:inline-size;z-index:10;opacity:0;pointer-events:none;transition:opacity .4s cubic-bezier(.4,0,.2,1);background:var(--aia-surface, #ffffff);border:1px solid var(--aia-dropdown-border, #e5e7eb);border-radius:25px;box-shadow:var(--aia-dropdown-shadow, 0 8px 12px rgba(0, 0, 0, .12))}.magicx-aia-dropdown[data-aia-surface=glass]{background:transparent;border-color:transparent;box-shadow:#fff -3.2px -3.2px 3.2px -3.2px inset,#fff 6.4px 6.4px 1.6px -8px inset,var(--aia-dropdown-bg, transparent) -6.4px 6.4px 1.6px -8px inset,var(--aia-dropdown-bg, transparent) 6.4px -6.4px 1.6px -8px inset,#ffffff26 -1.6px 0 0 -1.6px inset,#ffffff26 0 -1.6px 0 -1.6px inset,#ffffff4d 0 1.6px inset,#ffffff4d 1.6px 0 inset,inset 0 0 30px 5px #0000000d,#00000014 0 0 30px 2px;backdrop-filter:blur(30px)}.magicx-aia-dropdown-visible{opacity:1;pointer-events:auto}.magicx-aia-dropdown-pillbar{padding:7px 8px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 48px),transparent 100%);-webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 48px),transparent 100%)}.magicx-aia-dropdown-pillbar::-webkit-scrollbar{display:none}.magicx-aia-footer{display:flex;flex-direction:column;gap:8px;padding:7px 8px}.magicx-aia-footer-divider{border-top:.5px solid var(--aia-footer-divider, rgba(176, 176, 176, .4))}.magicx-aia-footer-row{display:flex;align-items:center;justify-content:space-between}.magicx-aia-footer-hint-group{display:inline-flex;align-items:center;gap:5px}.magicx-aia-footer-brand-link{display:inline-flex;align-items:center;gap:2px;text-decoration:none;cursor:pointer;transition:opacity .15s ease-out}.magicx-aia-footer-brand-link:hover{opacity:.7}.magicx-aia-footer-key{display:inline-flex;align-items:center;justify-content:center;min-width:30px;height:22px;padding:2px 6px;border:.5px solid var(--aia-footer-hint-color, #505050);border-radius:5px;font-family:inherit;font-size:11px;line-height:18px;color:var(--aia-footer-hint-color, #505050)}.magicx-aia-footer-hint{font-family:inherit;font-size:11px;line-height:18px;color:var(--aia-footer-hint-color, #505050)}.magicx-aia-footer-brand{font-family:inherit;font-size:10px;line-height:18px;color:var(--aia-footer-brand-color, #b0b0b0)}.magicx-aia-footer-badge{display:inline-flex;align-items:center;height:23px;padding:2.5px 5.5px;border:.5px solid var(--aia-footer-badge-border, rgba(189, 189, 189, .51));border-radius:999px;font-family:inherit;font-size:10px;line-height:18px;color:var(--aia-footer-brand-color, #b0b0b0)}.magicx-aia-dropdown-skeleton-bars{display:flex;flex-direction:column;gap:20px;padding:7px 8px}.magicx-aia-dropdown-skeleton-bar{display:block;height:14px;border-radius:999px;background:var(--aia-skeleton-bg, var(--aia-pill-bg, rgba(189, 189, 189, .51)));opacity:.5;animation:aiaDropdownSkeletonPulse 1.4s ease-in-out infinite}.magicx-aia-dropdown-skeleton-bar:nth-child(2){animation-delay:.15s}.magicx-aia-dropdown-skeleton-bar:nth-child(3){animation-delay:.3s}@keyframes aiaDropdownSkeletonPulse{0%,to{opacity:.5}50%{opacity:.25}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: PillListComponent, selector: "aia-pill-list", inputs: ["pills", "activePillIndex", "rounded", "loading", "activeSelected"], outputs: ["selectPill"] }, { kind: "component", type: SuggestionGridComponent, selector: "aia-suggestion-grid", inputs: ["options", "activeIndex", "listboxId", "loading"], outputs: ["select", "highlight"] }, { kind: "component", type: StackComponent, selector: "aia-stack", inputs: ["space", "align"] }, { kind: "component", type: ClusterComponent, selector: "aia-cluster", inputs: ["gap", "align", "justify", "noWrap", "inline"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
318
466
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteDropdownComponent, decorators: [{
|
|
319
467
|
type: Component,
|
|
320
|
-
args: [{ selector: "ai-autocomplete-dropdown", standalone: true, imports: [
|
|
468
|
+
args: [{ selector: "ai-autocomplete-dropdown", standalone: true, imports: [
|
|
469
|
+
CommonModule,
|
|
470
|
+
PillListComponent,
|
|
471
|
+
SuggestionGridComponent,
|
|
472
|
+
StackComponent,
|
|
473
|
+
ClusterComponent,
|
|
474
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n *ngIf=\"vm$ | async as vm\"\n [id]=\"controller.listboxId\"\n role=\"listbox\"\n data-aia-dropdown=\"\"\n [attr.data-aia-loading]=\"vm.isLoading ? '' : null\"\n [class]=\"className ? 'magicx-aia-dropdown ' + className : 'magicx-aia-dropdown'\"\n [class.magicx-aia-dropdown-visible]=\"vm.isVisible\"\n (mousedown)=\"preventBlur($event)\"\n>\n <aia-stack space=\"2px\">\n <aia-cluster\n *ngIf=\"vm.showsPills\"\n class=\"magicx-aia-dropdown-pillbar\"\n data-aia-pillbar=\"\"\n [noWrap]=\"true\"\n >\n <aia-pill-list\n [pills]=\"vm.pills\"\n [activePillIndex]=\"0\"\n [activeSelected]=\"vm.isActivePillSelected\"\n [rounded]=\"true\"\n [loading]=\"vm.isLoading\"\n (selectPill)=\"onPillClick($event)\"\n ></aia-pill-list>\n </aia-cluster>\n\n <aia-suggestion-grid\n *ngIf=\"vm.showsOptions\"\n [options]=\"vm.options\"\n [activeIndex]=\"vm.activeIndex\"\n [listboxId]=\"controller.listboxId\"\n [loading]=\"vm.isLoading\"\n (select)=\"onSelect($event)\"\n (highlight)=\"onHighlight($event)\"\n ></aia-suggestion-grid>\n\n <div\n *ngIf=\"vm.showsFallbackSkeleton\"\n class=\"magicx-aia-dropdown-skeleton-bars\"\n data-aia-skeleton-bars=\"\"\n >\n <span\n *ngFor=\"let w of fallbackSkeletonBarWidths; trackBy: trackByWidth\"\n class=\"magicx-aia-dropdown-skeleton-bar\"\n [style.width.px]=\"w\"\n ></span>\n </div>\n\n <footer class=\"magicx-aia-footer\" data-aia-footer=\"\">\n <div class=\"magicx-aia-footer-divider\"></div>\n <div class=\"magicx-aia-footer-row\">\n <span class=\"magicx-aia-footer-hint-group\">\n <kbd class=\"magicx-aia-footer-key\">{{ vm.footerKey }}</kbd>\n <span class=\"magicx-aia-footer-hint\">{{ vm.footerHint }}</span>\n </span>\n <a\n class=\"magicx-aia-footer-brand-link\"\n href=\"https://ai-autocomplete.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span class=\"magicx-aia-footer-brand\">AI</span>\n <span class=\"magicx-aia-footer-badge\">Autocomplete</span>\n </a>\n </div>\n </footer>\n </aia-stack>\n</div>\n", styles: [".magicx-aia-dropdown{position:absolute;left:0;right:0;top:100%;max-width:544px;margin-top:6px;display:flex;flex-direction:column;box-sizing:border-box;padding:4px;overflow:hidden;container-type:inline-size;z-index:10;opacity:0;pointer-events:none;transition:opacity .4s cubic-bezier(.4,0,.2,1);background:var(--aia-surface, #ffffff);border:1px solid var(--aia-dropdown-border, #e5e7eb);border-radius:25px;box-shadow:var(--aia-dropdown-shadow, 0 8px 12px rgba(0, 0, 0, .12))}.magicx-aia-dropdown[data-aia-surface=glass]{background:transparent;border-color:transparent;box-shadow:#fff -3.2px -3.2px 3.2px -3.2px inset,#fff 6.4px 6.4px 1.6px -8px inset,var(--aia-dropdown-bg, transparent) -6.4px 6.4px 1.6px -8px inset,var(--aia-dropdown-bg, transparent) 6.4px -6.4px 1.6px -8px inset,#ffffff26 -1.6px 0 0 -1.6px inset,#ffffff26 0 -1.6px 0 -1.6px inset,#ffffff4d 0 1.6px inset,#ffffff4d 1.6px 0 inset,inset 0 0 30px 5px #0000000d,#00000014 0 0 30px 2px;backdrop-filter:blur(30px)}.magicx-aia-dropdown-visible{opacity:1;pointer-events:auto}.magicx-aia-dropdown-pillbar{padding:7px 8px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 48px),transparent 100%);-webkit-mask-image:linear-gradient(to right,#000 0,#000 calc(100% - 48px),transparent 100%)}.magicx-aia-dropdown-pillbar::-webkit-scrollbar{display:none}.magicx-aia-footer{display:flex;flex-direction:column;gap:8px;padding:7px 8px}.magicx-aia-footer-divider{border-top:.5px solid var(--aia-footer-divider, rgba(176, 176, 176, .4))}.magicx-aia-footer-row{display:flex;align-items:center;justify-content:space-between}.magicx-aia-footer-hint-group{display:inline-flex;align-items:center;gap:5px}.magicx-aia-footer-brand-link{display:inline-flex;align-items:center;gap:2px;text-decoration:none;cursor:pointer;transition:opacity .15s ease-out}.magicx-aia-footer-brand-link:hover{opacity:.7}.magicx-aia-footer-key{display:inline-flex;align-items:center;justify-content:center;min-width:30px;height:22px;padding:2px 6px;border:.5px solid var(--aia-footer-hint-color, #505050);border-radius:5px;font-family:inherit;font-size:11px;line-height:18px;color:var(--aia-footer-hint-color, #505050)}.magicx-aia-footer-hint{font-family:inherit;font-size:11px;line-height:18px;color:var(--aia-footer-hint-color, #505050)}.magicx-aia-footer-brand{font-family:inherit;font-size:10px;line-height:18px;color:var(--aia-footer-brand-color, #b0b0b0)}.magicx-aia-footer-badge{display:inline-flex;align-items:center;height:23px;padding:2.5px 5.5px;border:.5px solid var(--aia-footer-badge-border, rgba(189, 189, 189, .51));border-radius:999px;font-family:inherit;font-size:10px;line-height:18px;color:var(--aia-footer-brand-color, #b0b0b0)}.magicx-aia-dropdown-skeleton-bars{display:flex;flex-direction:column;gap:20px;padding:7px 8px}.magicx-aia-dropdown-skeleton-bar{display:block;height:14px;border-radius:999px;background:var(--aia-skeleton-bg, var(--aia-pill-bg, rgba(189, 189, 189, .51)));opacity:.5;animation:aiaDropdownSkeletonPulse 1.4s ease-in-out infinite}.magicx-aia-dropdown-skeleton-bar:nth-child(2){animation-delay:.15s}.magicx-aia-dropdown-skeleton-bar:nth-child(3){animation-delay:.3s}@keyframes aiaDropdownSkeletonPulse{0%,to{opacity:.5}50%{opacity:.25}}\n"] }]
|
|
321
475
|
}], propDecorators: { controller: [{
|
|
322
476
|
type: Input
|
|
323
477
|
}], showPills: [{
|
|
@@ -422,6 +576,7 @@ class AIAutocompleteController {
|
|
|
422
576
|
this.isReady$ = deriveField(this.rawState$, (s) => s.isReady);
|
|
423
577
|
this.isFocused$ = deriveField(this.rawState$, (s) => s.isFocused);
|
|
424
578
|
this.isDropdownOpen$ = deriveField(this.rawState$, (s) => s.isDropdownOpen);
|
|
579
|
+
this.isActivePillSelected$ = deriveField(this.rawState$, (s) => s.isActivePillSelected);
|
|
425
580
|
this.placeholderText$ = deriveField(this.rawState$, (s) => s.placeholderText);
|
|
426
581
|
this.error$ = deriveField(this.rawState$, (s) => s.error);
|
|
427
582
|
this.editingParam$ = deriveField(this.rawState$, (s) => s.editingParam);
|
|
@@ -649,7 +804,10 @@ function computeDropdown(s) {
|
|
|
649
804
|
activeIndex: s.activeDropdownIndex,
|
|
650
805
|
isOpen: s.isDropdownOpen,
|
|
651
806
|
pills: dropdownPills,
|
|
807
|
+
isActivePillSelected: s.isActivePillSelected,
|
|
652
808
|
isLoading: computeUiLoading(s),
|
|
809
|
+
hasTabbedToHighlight: s.hasTabbedToHighlight,
|
|
810
|
+
isInputEmpty: s.text.trim().length === 0,
|
|
653
811
|
};
|
|
654
812
|
}
|
|
655
813
|
|
|
@@ -904,6 +1062,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
904
1062
|
type: Input
|
|
905
1063
|
}] } });
|
|
906
1064
|
|
|
1065
|
+
/**
|
|
1066
|
+
* Internal default submit button (up-arrow). Angular analogue of React's
|
|
1067
|
+
* `SubmitButton`. The default/custom/hidden branching stays in the parent
|
|
1068
|
+
* (`AIAutocompleteComponent`); this is only the built-in button.
|
|
1069
|
+
*
|
|
1070
|
+
* @internal
|
|
1071
|
+
*/
|
|
1072
|
+
class SubmitButtonComponent {
|
|
1073
|
+
constructor() {
|
|
1074
|
+
this.disabled = false;
|
|
1075
|
+
this.submit = new EventEmitter();
|
|
1076
|
+
}
|
|
1077
|
+
onClick(event) {
|
|
1078
|
+
this.submit.emit(event);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
SubmitButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SubmitButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1082
|
+
SubmitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SubmitButtonComponent, isStandalone: true, selector: "aia-submit-button", inputs: { disabled: "disabled" }, outputs: { submit: "submit" }, ngImport: i0, template: "<button\n type=\"button\"\n data-aia-submit=\"\"\n class=\"magicx-aia-submit-button\"\n [disabled]=\"disabled\"\n aria-label=\"Submit\"\n (click)=\"onClick($event)\"\n>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" role=\"img\" aria-label=\"Submit\">\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</button>\n", styles: [".magicx-aia-submit-button{flex-shrink:0;width:32px;height:32px;border-radius:50%;border:none;background:var(--aia-submit-bg, var(--aia-color-text-default, #fff));color:var(--aia-submit-color, var(--aia-color-bg-default, #000));cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:opacity .2s ease}.magicx-aia-submit-button:hover{opacity:.85}.magicx-aia-submit-button:disabled{opacity:.4;cursor:default}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1083
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SubmitButtonComponent, decorators: [{
|
|
1084
|
+
type: Component,
|
|
1085
|
+
args: [{ selector: "aia-submit-button", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<button\n type=\"button\"\n data-aia-submit=\"\"\n class=\"magicx-aia-submit-button\"\n [disabled]=\"disabled\"\n aria-label=\"Submit\"\n (click)=\"onClick($event)\"\n>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" role=\"img\" aria-label=\"Submit\">\n <path\n d=\"M9 14V4M9 4L4 9M9 4L14 9\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</button>\n", styles: [".magicx-aia-submit-button{flex-shrink:0;width:32px;height:32px;border-radius:50%;border:none;background:var(--aia-submit-bg, var(--aia-color-text-default, #fff));color:var(--aia-submit-color, var(--aia-color-bg-default, #000));cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;transition:opacity .2s ease}.magicx-aia-submit-button:hover{opacity:.85}.magicx-aia-submit-button:disabled{opacity:.4;cursor:default}\n"] }]
|
|
1086
|
+
}], propDecorators: { disabled: [{
|
|
1087
|
+
type: Input
|
|
1088
|
+
}], submit: [{
|
|
1089
|
+
type: Output
|
|
1090
|
+
}] } });
|
|
1091
|
+
|
|
907
1092
|
/**
|
|
908
1093
|
* Tier 1 component — `<ai-autocomplete>`. The Angular equivalent of React's
|
|
909
1094
|
* `<AIAutocomplete />`. Owns the contentEditable editor, inline pills, mode
|
|
@@ -1218,7 +1403,7 @@ AIAutocompleteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
|
|
|
1218
1403
|
useExisting: forwardRef(() => AIAutocompleteComponent),
|
|
1219
1404
|
multi: true,
|
|
1220
1405
|
},
|
|
1221
|
-
], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true }, { propertyName: "pillContainerRef", first: true, predicate: ["pillContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"magicx-aia magicx-aia-container\"\n [attr.data-pill-placement]=\"pillPlacement\"\n [attr.data-options-position]=\"optionsPosition\"\n [attr.data-animations]=\"animations ? 'on' : 'off'\"\n [attr.data-mode]=\"resolvedMode\"\n>\n <ai-autocomplete-dropdown\n *ngIf=\"controller\"\n [controller]=\"controller\"\n [showPills]=\"showDropdownPills\"\n ></ai-autocomplete-dropdown>\n\n <div\n class=\"magicx-aia-input-wrapper\"\n (click)=\"onWrapperClick($event)\"\n (keyup)=\"$event.stopPropagation()\"\n >\n <div class=\"magicx-aia-editor-area\" data-aia-editor=\"\">\n <div\n #editor\n *ngIf=\"controller\"\n [aiaEditorHost]=\"controller\"\n [autoFocus]=\"autoFocus\"\n class=\"magicx-aia-input\"\n data-aia-input=\"\"\n ></div>\n\n <ng-container *ngIf=\"controller && showInlinePills\">\n <span\n #pillContainer\n class=\"magicx-aia-pill-list-container\"\n data-aia-pill-list-container=\"\"\n *ngIf=\"\n (controller.isLoading$ | async) ||\n ((controller.suggestionPills$ | async)?.length ?? 0) > 0\n \"\n >\n <aia-pill-list\n [pills]=\"(controller.suggestionPills$ | async) ?? []\"\n [activePillIndex]=\"0\"\n [loading]=\"(controller.isLoading$ | async) ?? false\"\n (selectPill)=\"onSelectPill($event)\"\n ></aia-pill-list>\n </span>\n </ng-container>\n </div>\n\n <ng-container [ngSwitch]=\"submitButtonState\">\n <button\n *ngSwitchCase=\"'default'\"\n
|
|
1406
|
+
], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true }, { propertyName: "pillContainerRef", first: true, predicate: ["pillContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n #container\n class=\"magicx-aia magicx-aia-container\"\n [attr.data-pill-placement]=\"pillPlacement\"\n [attr.data-options-position]=\"optionsPosition\"\n [attr.data-animations]=\"animations ? 'on' : 'off'\"\n [attr.data-mode]=\"resolvedMode\"\n>\n <ai-autocomplete-dropdown\n *ngIf=\"controller\"\n [controller]=\"controller\"\n [showPills]=\"showDropdownPills\"\n ></ai-autocomplete-dropdown>\n\n <div\n class=\"magicx-aia-input-wrapper\"\n (click)=\"onWrapperClick($event)\"\n (keyup)=\"$event.stopPropagation()\"\n >\n <div class=\"magicx-aia-editor-area\" data-aia-editor=\"\">\n <div\n #editor\n *ngIf=\"controller\"\n [aiaEditorHost]=\"controller\"\n [autoFocus]=\"autoFocus\"\n class=\"magicx-aia-input\"\n data-aia-input=\"\"\n ></div>\n\n <ng-container *ngIf=\"controller && showInlinePills\">\n <span\n #pillContainer\n class=\"magicx-aia-pill-list-container\"\n data-aia-pill-list-container=\"\"\n *ngIf=\"\n (controller.isLoading$ | async) ||\n ((controller.suggestionPills$ | async)?.length ?? 0) > 0\n \"\n >\n <aia-pill-list\n [pills]=\"(controller.suggestionPills$ | async) ?? []\"\n [activePillIndex]=\"0\"\n [activeSelected]=\"(controller.isActivePillSelected$ | async) ?? false\"\n [loading]=\"(controller.isLoading$ | async) ?? false\"\n (selectPill)=\"onSelectPill($event)\"\n ></aia-pill-list>\n </span>\n </ng-container>\n </div>\n\n <ng-container [ngSwitch]=\"submitButtonState\">\n <aia-submit-button\n *ngSwitchCase=\"'default'\"\n [disabled]=\"\n !(\n controller &&\n canSubmit({\n segments: (controller.segments$ | async) ?? [],\n completedParams: (controller.completedParams$ | async) ?? []\n })\n )\n \"\n (submit)=\"onSubmitButtonClick($event)\"\n ></aia-submit-button>\n\n <span\n *ngSwitchCase=\"'custom'\"\n data-aia-submit=\"\"\n class=\"magicx-aia-submit-slot\"\n (click)=\"onSubmitSlotClick($event)\"\n >\n <ng-container *ngTemplateOutlet=\"customSubmitTemplate\"></ng-container>\n </span>\n </ng-container>\n </div>\n</div>\n", styles: [":where(.magicx-aia,.magicx-aia *,.magicx-aia *::before,.magicx-aia *::after){box-sizing:border-box}:where(.magicx-aia),:where(.magicx-aia[data-mode=\"light\"]){--aia-surface: #ffffff;--aia-border: #b0b0b0;--aia-dropdown-border: #e5e7eb;--aia-dropdown-shadow: 0 8px 12px rgba(0, 0, 0, .12);--aia-pill-bg: #bdbdbd;--aia-pill-color: #333539;--aia-pill-font-size: 14px;--aia-option-bg: #eef2ff;--aia-option-color: #505050;--aia-option-color-selected: #000000;--aia-option-font-size: 14px;--aia-written-text-color: #000000;--aia-written-text-font-size: 14px;--aia-caret-color: var(--aia-written-text-color, #000000);--aia-submit-bg: #000000;--aia-submit-color: #ffffff;--aia-color-text-muted: #6b7280;--aia-skeleton-bg: rgba(189, 189, 189, .51);--aia-streak-rgb: 99, 102, 241;--aia-streak-glass-bg: rgba(99, 102, 241, .1);--aia-footer-divider: rgba(176, 176, 176, .4);--aia-footer-hint-color: #505050;--aia-footer-brand-color: #b0b0b0;--aia-footer-badge-border: rgba(189, 189, 189, .51)}:where(.magicx-aia[data-mode=\"dark\"]){--aia-surface: #000000;--aia-border: #505050;--aia-dropdown-border: #484848;--aia-dropdown-shadow: 0 8px 12px rgba(0, 0, 0, .12);--aia-pill-bg: #bdbdbd;--aia-pill-color: #b0b0b0;--aia-pill-font-size: 14px;--aia-option-bg: transparent;--aia-option-color: #b0b0b0;--aia-option-color-selected: #ffffff;--aia-option-font-size: 14px;--aia-written-text-color: #ffffff;--aia-written-text-font-size: 14px;--aia-caret-color: var(--aia-written-text-color, #ffffff);--aia-submit-bg: #ffffff;--aia-submit-color: #000000;--aia-color-text-muted: #c1c4cb;--aia-skeleton-bg: #333539;--aia-streak-rgb: 255, 255, 255;--aia-streak-glass-bg: rgba(255, 255, 255, .1);--aia-footer-divider: rgba(255, 255, 255, .15);--aia-footer-hint-color: #b0b0b0;--aia-footer-brand-color: #505050;--aia-footer-badge-border: #505050}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown]{top:auto;bottom:100%;margin-top:0;margin-bottom:6px}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown] .aia-stack{flex-direction:column-reverse}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown] .magicx-aia-footer{flex-direction:column-reverse}:where(.magicx-aia[data-animations=\"off\"]) *,:where(.magicx-aia[data-animations=\"off\"]) *:before,:where(.magicx-aia[data-animations=\"off\"]) *:after{animation-duration:0s!important;transition-duration:0s!important}.magicx-aia-container{position:relative;font-family:var(--aia-font-family, inherit);container-type:inline-size}.magicx-aia-input-wrapper{padding:12px 10px;border:1px solid var(--aia-border, #b0b0b0);border-radius:24px;background:var(--aia-surface, #ffffff);overflow:hidden;display:flex;align-items:center;gap:12px}.magicx-aia-editor-area{position:relative;flex:1;min-width:0;min-height:19px;line-height:19px;font-family:inherit;font-size:var(--aia-written-text-font-size, 14px);white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.magicx-aia-input{display:inline;outline:none;background:transparent;color:var(--aia-written-text-color, var(--aia-color-text-default, #fff));caret-color:var( --aia-caret-color, var(--aia-written-text-color, var(--aia-color-text-default, #fff)) );font-weight:300;vertical-align:middle}:where(.magicx-aia-input) strong{font-weight:600;letter-spacing:-.01em}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]{background-color:color-mix(in srgb,var(--aia-edit-outline, currentColor) 20%,transparent);border-radius:6px;padding:2px 3px;margin:0 -1.5px;caret-color:transparent}.magicx-aia-input:has(strong[class~=\"magicx-aia-segment--editing\"]){caret-color:transparent}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]::selection{background:transparent;color:inherit}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]::-moz-selection{background:transparent;color:inherit}.magicx-aia-input[data-aia-empty=true][data-placeholder]:before{content:attr(data-placeholder);color:var(--aia-color-text-muted, #c1c4cb);opacity:.7;pointer-events:none}.magicx-aia-input[data-aia-empty=true]{display:inline-block;min-width:1px}.magicx-aia-pill-list-container{display:inline;margin-left:8px}.magicx-aia-pill-list-container:empty,.magicx-aia-pill-list-container[data-aia-pill-wrapped]{margin-left:0}.magicx-aia-submit-slot{display:contents}:where(.magicx-aia-input) strong[class~=magicx-aia-shimmer-revealed]{color:transparent;background:linear-gradient(120deg,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 0%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 44%,#b0b0b0 48%,#b0b0b0 52%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 56%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 100%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text}:where(.magicx-aia-input) strong[class~=magicx-aia-shimmer-sweep]{animation:aiaTextShimmer .65s ease-out forwards}@keyframes aiaTextShimmer{0%{background-position:100% 0}to{background-position:-50% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: AIAutocompleteDropdownComponent, selector: "ai-autocomplete-dropdown", inputs: ["controller", "showPills", "className"] }, { kind: "directive", type: AIAutocompleteEditorHostDirective, selector: "[aiaEditorHost]", inputs: ["aiaEditorHost", "autoFocus"] }, { kind: "component", type: PillListComponent, selector: "aia-pill-list", inputs: ["pills", "activePillIndex", "rounded", "loading", "activeSelected"], outputs: ["selectPill"] }, { kind: "component", type: SubmitButtonComponent, selector: "aia-submit-button", inputs: ["disabled"], outputs: ["submit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1222
1407
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AIAutocompleteComponent, decorators: [{
|
|
1223
1408
|
type: Component,
|
|
1224
1409
|
args: [{ selector: "ai-autocomplete", standalone: true, imports: [
|
|
@@ -1226,6 +1411,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1226
1411
|
AIAutocompleteDropdownComponent,
|
|
1227
1412
|
AIAutocompleteEditorHostDirective,
|
|
1228
1413
|
PillListComponent,
|
|
1414
|
+
SubmitButtonComponent,
|
|
1229
1415
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
1230
1416
|
{
|
|
1231
1417
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -1233,7 +1419,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1233
1419
|
useExisting: forwardRef(() => AIAutocompleteComponent),
|
|
1234
1420
|
multi: true,
|
|
1235
1421
|
},
|
|
1236
|
-
], template: "<div\n #container\n class=\"magicx-aia magicx-aia-container\"\n [attr.data-pill-placement]=\"pillPlacement\"\n [attr.data-options-position]=\"optionsPosition\"\n [attr.data-animations]=\"animations ? 'on' : 'off'\"\n [attr.data-mode]=\"resolvedMode\"\n>\n <ai-autocomplete-dropdown\n *ngIf=\"controller\"\n [controller]=\"controller\"\n [showPills]=\"showDropdownPills\"\n ></ai-autocomplete-dropdown>\n\n <div\n class=\"magicx-aia-input-wrapper\"\n (click)=\"onWrapperClick($event)\"\n (keyup)=\"$event.stopPropagation()\"\n >\n <div class=\"magicx-aia-editor-area\" data-aia-editor=\"\">\n <div\n #editor\n *ngIf=\"controller\"\n [aiaEditorHost]=\"controller\"\n [autoFocus]=\"autoFocus\"\n class=\"magicx-aia-input\"\n data-aia-input=\"\"\n ></div>\n\n <ng-container *ngIf=\"controller && showInlinePills\">\n <span\n #pillContainer\n class=\"magicx-aia-pill-list-container\"\n data-aia-pill-list-container=\"\"\n *ngIf=\"\n (controller.isLoading$ | async) ||\n ((controller.suggestionPills$ | async)?.length ?? 0) > 0\n \"\n >\n <aia-pill-list\n [pills]=\"(controller.suggestionPills$ | async) ?? []\"\n [activePillIndex]=\"0\"\n [loading]=\"(controller.isLoading$ | async) ?? false\"\n (selectPill)=\"onSelectPill($event)\"\n ></aia-pill-list>\n </span>\n </ng-container>\n </div>\n\n <ng-container [ngSwitch]=\"submitButtonState\">\n <button\n *ngSwitchCase=\"'default'\"\n
|
|
1422
|
+
], template: "<div\n #container\n class=\"magicx-aia magicx-aia-container\"\n [attr.data-pill-placement]=\"pillPlacement\"\n [attr.data-options-position]=\"optionsPosition\"\n [attr.data-animations]=\"animations ? 'on' : 'off'\"\n [attr.data-mode]=\"resolvedMode\"\n>\n <ai-autocomplete-dropdown\n *ngIf=\"controller\"\n [controller]=\"controller\"\n [showPills]=\"showDropdownPills\"\n ></ai-autocomplete-dropdown>\n\n <div\n class=\"magicx-aia-input-wrapper\"\n (click)=\"onWrapperClick($event)\"\n (keyup)=\"$event.stopPropagation()\"\n >\n <div class=\"magicx-aia-editor-area\" data-aia-editor=\"\">\n <div\n #editor\n *ngIf=\"controller\"\n [aiaEditorHost]=\"controller\"\n [autoFocus]=\"autoFocus\"\n class=\"magicx-aia-input\"\n data-aia-input=\"\"\n ></div>\n\n <ng-container *ngIf=\"controller && showInlinePills\">\n <span\n #pillContainer\n class=\"magicx-aia-pill-list-container\"\n data-aia-pill-list-container=\"\"\n *ngIf=\"\n (controller.isLoading$ | async) ||\n ((controller.suggestionPills$ | async)?.length ?? 0) > 0\n \"\n >\n <aia-pill-list\n [pills]=\"(controller.suggestionPills$ | async) ?? []\"\n [activePillIndex]=\"0\"\n [activeSelected]=\"(controller.isActivePillSelected$ | async) ?? false\"\n [loading]=\"(controller.isLoading$ | async) ?? false\"\n (selectPill)=\"onSelectPill($event)\"\n ></aia-pill-list>\n </span>\n </ng-container>\n </div>\n\n <ng-container [ngSwitch]=\"submitButtonState\">\n <aia-submit-button\n *ngSwitchCase=\"'default'\"\n [disabled]=\"\n !(\n controller &&\n canSubmit({\n segments: (controller.segments$ | async) ?? [],\n completedParams: (controller.completedParams$ | async) ?? []\n })\n )\n \"\n (submit)=\"onSubmitButtonClick($event)\"\n ></aia-submit-button>\n\n <span\n *ngSwitchCase=\"'custom'\"\n data-aia-submit=\"\"\n class=\"magicx-aia-submit-slot\"\n (click)=\"onSubmitSlotClick($event)\"\n >\n <ng-container *ngTemplateOutlet=\"customSubmitTemplate\"></ng-container>\n </span>\n </ng-container>\n </div>\n</div>\n", styles: [":where(.magicx-aia,.magicx-aia *,.magicx-aia *::before,.magicx-aia *::after){box-sizing:border-box}:where(.magicx-aia),:where(.magicx-aia[data-mode=\"light\"]){--aia-surface: #ffffff;--aia-border: #b0b0b0;--aia-dropdown-border: #e5e7eb;--aia-dropdown-shadow: 0 8px 12px rgba(0, 0, 0, .12);--aia-pill-bg: #bdbdbd;--aia-pill-color: #333539;--aia-pill-font-size: 14px;--aia-option-bg: #eef2ff;--aia-option-color: #505050;--aia-option-color-selected: #000000;--aia-option-font-size: 14px;--aia-written-text-color: #000000;--aia-written-text-font-size: 14px;--aia-caret-color: var(--aia-written-text-color, #000000);--aia-submit-bg: #000000;--aia-submit-color: #ffffff;--aia-color-text-muted: #6b7280;--aia-skeleton-bg: rgba(189, 189, 189, .51);--aia-streak-rgb: 99, 102, 241;--aia-streak-glass-bg: rgba(99, 102, 241, .1);--aia-footer-divider: rgba(176, 176, 176, .4);--aia-footer-hint-color: #505050;--aia-footer-brand-color: #b0b0b0;--aia-footer-badge-border: rgba(189, 189, 189, .51)}:where(.magicx-aia[data-mode=\"dark\"]){--aia-surface: #000000;--aia-border: #505050;--aia-dropdown-border: #484848;--aia-dropdown-shadow: 0 8px 12px rgba(0, 0, 0, .12);--aia-pill-bg: #bdbdbd;--aia-pill-color: #b0b0b0;--aia-pill-font-size: 14px;--aia-option-bg: transparent;--aia-option-color: #b0b0b0;--aia-option-color-selected: #ffffff;--aia-option-font-size: 14px;--aia-written-text-color: #ffffff;--aia-written-text-font-size: 14px;--aia-caret-color: var(--aia-written-text-color, #ffffff);--aia-submit-bg: #ffffff;--aia-submit-color: #000000;--aia-color-text-muted: #c1c4cb;--aia-skeleton-bg: #333539;--aia-streak-rgb: 255, 255, 255;--aia-streak-glass-bg: rgba(255, 255, 255, .1);--aia-footer-divider: rgba(255, 255, 255, .15);--aia-footer-hint-color: #b0b0b0;--aia-footer-brand-color: #505050;--aia-footer-badge-border: #505050}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown]{top:auto;bottom:100%;margin-top:0;margin-bottom:6px}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown] .aia-stack{flex-direction:column-reverse}:where(.magicx-aia[data-options-position=\"above\"]) [data-aia-dropdown] .magicx-aia-footer{flex-direction:column-reverse}:where(.magicx-aia[data-animations=\"off\"]) *,:where(.magicx-aia[data-animations=\"off\"]) *:before,:where(.magicx-aia[data-animations=\"off\"]) *:after{animation-duration:0s!important;transition-duration:0s!important}.magicx-aia-container{position:relative;font-family:var(--aia-font-family, inherit);container-type:inline-size}.magicx-aia-input-wrapper{padding:12px 10px;border:1px solid var(--aia-border, #b0b0b0);border-radius:24px;background:var(--aia-surface, #ffffff);overflow:hidden;display:flex;align-items:center;gap:12px}.magicx-aia-editor-area{position:relative;flex:1;min-width:0;min-height:19px;line-height:19px;font-family:inherit;font-size:var(--aia-written-text-font-size, 14px);white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.magicx-aia-input{display:inline;outline:none;background:transparent;color:var(--aia-written-text-color, var(--aia-color-text-default, #fff));caret-color:var( --aia-caret-color, var(--aia-written-text-color, var(--aia-color-text-default, #fff)) );font-weight:300;vertical-align:middle}:where(.magicx-aia-input) strong{font-weight:600;letter-spacing:-.01em}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]{background-color:color-mix(in srgb,var(--aia-edit-outline, currentColor) 20%,transparent);border-radius:6px;padding:2px 3px;margin:0 -1.5px;caret-color:transparent}.magicx-aia-input:has(strong[class~=\"magicx-aia-segment--editing\"]){caret-color:transparent}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]::selection{background:transparent;color:inherit}:where(.magicx-aia-input) strong[class~=magicx-aia-segment--editing]::-moz-selection{background:transparent;color:inherit}.magicx-aia-input[data-aia-empty=true][data-placeholder]:before{content:attr(data-placeholder);color:var(--aia-color-text-muted, #c1c4cb);opacity:.7;pointer-events:none}.magicx-aia-input[data-aia-empty=true]{display:inline-block;min-width:1px}.magicx-aia-pill-list-container{display:inline;margin-left:8px}.magicx-aia-pill-list-container:empty,.magicx-aia-pill-list-container[data-aia-pill-wrapped]{margin-left:0}.magicx-aia-submit-slot{display:contents}:where(.magicx-aia-input) strong[class~=magicx-aia-shimmer-revealed]{color:transparent;background:linear-gradient(120deg,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 0%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 44%,#b0b0b0 48%,#b0b0b0 52%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 56%,var(--aia-written-text-color, var(--aia-color-text-default, #fff)) 100%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text}:where(.magicx-aia-input) strong[class~=magicx-aia-shimmer-sweep]{animation:aiaTextShimmer .65s ease-out forwards}@keyframes aiaTextShimmer{0%{background-position:100% 0}to{background-position:-50% 0}}\n"] }]
|
|
1237
1423
|
}], propDecorators: { apiConfig: [{
|
|
1238
1424
|
type: Input
|
|
1239
1425
|
}], optionOverrides: [{
|