@agentsmith.bgd/as-components 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# AsComponents
|
|
2
|
+
|
|
3
|
+
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
ng generate component component-name
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ng generate --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Building
|
|
20
|
+
|
|
21
|
+
To build the library, run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ng build as-components
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
|
|
28
|
+
|
|
29
|
+
### Publishing the Library
|
|
30
|
+
|
|
31
|
+
Once the project is built, you can publish your library by following these steps:
|
|
32
|
+
|
|
33
|
+
1. Navigate to the `dist` directory:
|
|
34
|
+
```bash
|
|
35
|
+
cd dist/as-components
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. Run the `npm publish` command to publish your library to the npm registry:
|
|
39
|
+
```bash
|
|
40
|
+
npm publish
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Running unit tests
|
|
44
|
+
|
|
45
|
+
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ng test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Running end-to-end tests
|
|
52
|
+
|
|
53
|
+
For end-to-end (e2e) testing, run:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ng e2e
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
60
|
+
|
|
61
|
+
## Additional Resources
|
|
62
|
+
|
|
63
|
+
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, signal, EventEmitter, ViewContainerRef, Output, ViewChild, ChangeDetectionStrategy, createComponent, Injectable, inject, Injector, ElementRef, input, computed, HostListener, Directive, output, effect } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { Subject } from 'rxjs';
|
|
6
|
+
import { Overlay } from '@angular/cdk/overlay';
|
|
7
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
8
|
+
|
|
9
|
+
class AsComponents {
|
|
10
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AsComponents, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: AsComponents, isStandalone: true, selector: "lib-as-components", ngImport: i0, template: `
|
|
12
|
+
<p>
|
|
13
|
+
as-components works!
|
|
14
|
+
</p>
|
|
15
|
+
`, isInline: true, styles: [""] });
|
|
16
|
+
}
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AsComponents, decorators: [{
|
|
18
|
+
type: Component,
|
|
19
|
+
args: [{ selector: 'lib-as-components', imports: [], template: `
|
|
20
|
+
<p>
|
|
21
|
+
as-components works!
|
|
22
|
+
</p>
|
|
23
|
+
` }]
|
|
24
|
+
}] });
|
|
25
|
+
|
|
26
|
+
// TypeScript
|
|
27
|
+
class ModalContainerComponent {
|
|
28
|
+
contentHost;
|
|
29
|
+
// signal-based inputs
|
|
30
|
+
title = signal(undefined, ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
31
|
+
size = signal('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
32
|
+
showClose = signal(true, ...(ngDevMode ? [{ debugName: "showClose" }] : []));
|
|
33
|
+
closed = new EventEmitter();
|
|
34
|
+
get sizeClass() {
|
|
35
|
+
return this.size(); // template uses size() directly; keep helper for compatibility if needed
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a component inside the container and set inputs.
|
|
39
|
+
* Supports:
|
|
40
|
+
* - assigning to writable signals (calls `.set(...)`)
|
|
41
|
+
* - assigning to plain properties
|
|
42
|
+
* Also handles primitive `inputs` mapping to common names.
|
|
43
|
+
*/
|
|
44
|
+
loadComponent(component, inputs) {
|
|
45
|
+
const compRef = this.contentHost.createComponent(component);
|
|
46
|
+
if (inputs !== undefined && inputs !== null) {
|
|
47
|
+
if (typeof inputs === 'object' && !Array.isArray(inputs)) {
|
|
48
|
+
for (const key of Object.keys(inputs)) {
|
|
49
|
+
this.setInput(compRef.instance, key, inputs[key]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// primitive mapping
|
|
54
|
+
const inst = compRef.instance;
|
|
55
|
+
if ('message' in inst)
|
|
56
|
+
this.setInput(inst, 'message', inputs);
|
|
57
|
+
else if ('data' in inst)
|
|
58
|
+
this.setInput(inst, 'data', inputs);
|
|
59
|
+
else
|
|
60
|
+
this.setInput(inst, 'value', inputs);
|
|
61
|
+
}
|
|
62
|
+
// ensure rendering for OnPush / signal changes
|
|
63
|
+
compRef.changeDetectorRef?.detectChanges();
|
|
64
|
+
}
|
|
65
|
+
return compRef;
|
|
66
|
+
}
|
|
67
|
+
setInput(targetInstance, key, value) {
|
|
68
|
+
const target = targetInstance[key];
|
|
69
|
+
// writable signal: function with 'set'
|
|
70
|
+
if (typeof target === 'function' && target && 'set' in target && typeof target.set === 'function') {
|
|
71
|
+
target.set(value);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
targetInstance[key] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
backdropClick() {
|
|
78
|
+
this.close();
|
|
79
|
+
}
|
|
80
|
+
close(result) {
|
|
81
|
+
this.closed.emit(result);
|
|
82
|
+
}
|
|
83
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModalContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
84
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: ModalContainerComponent, isStandalone: true, selector: "as-modal-container", outputs: { closed: "closed" }, viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
|
|
85
|
+
<div class="as-modal-backdrop" (click)="backdropClick()"></div>
|
|
86
|
+
<div class="as-modal" [ngClass]="size()" role="dialog" aria-modal="true">
|
|
87
|
+
<div class="as-modal-header" *ngIf="title() || showClose()">
|
|
88
|
+
<h3 class="as-modal-title">{{ title() }}</h3>
|
|
89
|
+
<button *ngIf="showClose()" class="as-modal-close" (click)="close()">×</button>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="as-modal-body">
|
|
92
|
+
<ng-template #contentHost></ng-template>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
`, isInline: true, styles: [".as-modal-backdrop{position:fixed;inset:0;background:#00000080;z-index:1000}\n", ".as-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1001;background:#fff;border-radius:4px;max-width:90%}\n", ".as-modal.sm{width:300px}\n", ".as-modal.md{width:600px}\n", ".as-modal.lg{width:900px}\n", ".as-modal-header{display:flex;justify-content:space-between;align-items:center;padding:12px;border-bottom:1px solid #eee}\n", ".as-modal-body{padding:12px}\n", ".as-modal-close{background:none;border:0;font-size:20px;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
96
|
+
}
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModalContainerComponent, decorators: [{
|
|
98
|
+
type: Component,
|
|
99
|
+
args: [{ selector: 'as-modal-container', template: `
|
|
100
|
+
<div class="as-modal-backdrop" (click)="backdropClick()"></div>
|
|
101
|
+
<div class="as-modal" [ngClass]="size()" role="dialog" aria-modal="true">
|
|
102
|
+
<div class="as-modal-header" *ngIf="title() || showClose()">
|
|
103
|
+
<h3 class="as-modal-title">{{ title() }}</h3>
|
|
104
|
+
<button *ngIf="showClose()" class="as-modal-close" (click)="close()">×</button>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="as-modal-body">
|
|
107
|
+
<ng-template #contentHost></ng-template>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
`, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, styles: [".as-modal-backdrop{position:fixed;inset:0;background:#00000080;z-index:1000}\n", ".as-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1001;background:#fff;border-radius:4px;max-width:90%}\n", ".as-modal.sm{width:300px}\n", ".as-modal.md{width:600px}\n", ".as-modal.lg{width:900px}\n", ".as-modal-header{display:flex;justify-content:space-between;align-items:center;padding:12px;border-bottom:1px solid #eee}\n", ".as-modal-body{padding:12px}\n", ".as-modal-close{background:none;border:0;font-size:20px;cursor:pointer}\n"] }]
|
|
111
|
+
}], propDecorators: { contentHost: [{
|
|
112
|
+
type: ViewChild,
|
|
113
|
+
args: ['contentHost', { read: ViewContainerRef, static: true }]
|
|
114
|
+
}], closed: [{
|
|
115
|
+
type: Output
|
|
116
|
+
}] } });
|
|
117
|
+
|
|
118
|
+
class ModalRef {
|
|
119
|
+
componentRef;
|
|
120
|
+
hostElement;
|
|
121
|
+
_onClose = new Subject();
|
|
122
|
+
onClose = this._onClose.asObservable();
|
|
123
|
+
constructor(componentRef, hostElement) {
|
|
124
|
+
this.componentRef = componentRef;
|
|
125
|
+
this.hostElement = hostElement;
|
|
126
|
+
}
|
|
127
|
+
close(result) {
|
|
128
|
+
this._onClose.next(result);
|
|
129
|
+
this._onClose.complete();
|
|
130
|
+
this.destroy();
|
|
131
|
+
}
|
|
132
|
+
destroy() {
|
|
133
|
+
try {
|
|
134
|
+
if (this.componentRef) {
|
|
135
|
+
this.componentRef.destroy();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
if (this.hostElement && this.hostElement.parentNode) {
|
|
140
|
+
this.hostElement.parentNode.removeChild(this.hostElement);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// TypeScript
|
|
147
|
+
class ModalService {
|
|
148
|
+
injector;
|
|
149
|
+
appRef;
|
|
150
|
+
envInjector;
|
|
151
|
+
constructor(injector, appRef, envInjector) {
|
|
152
|
+
this.injector = injector;
|
|
153
|
+
this.appRef = appRef;
|
|
154
|
+
this.envInjector = envInjector;
|
|
155
|
+
}
|
|
156
|
+
show(component, config = {}) {
|
|
157
|
+
const hostEl = document.createElement('div');
|
|
158
|
+
document.body.appendChild(hostEl);
|
|
159
|
+
const compRef = createComponent(ModalContainerComponent, {
|
|
160
|
+
environmentInjector: this.envInjector
|
|
161
|
+
});
|
|
162
|
+
// set container inputs using signal-aware helper
|
|
163
|
+
this.setInput(compRef.instance, 'title', config.title);
|
|
164
|
+
this.setInput(compRef.instance, 'size', config.size ?? 'md');
|
|
165
|
+
this.setInput(compRef.instance, 'showClose', config.showClose !== false);
|
|
166
|
+
this.appRef.attachView(compRef.hostView);
|
|
167
|
+
hostEl.appendChild(compRef.hostView.rootNodes[0]);
|
|
168
|
+
// the container's loadComponent handles assigning inputs (including signals) to the child
|
|
169
|
+
const childRef = compRef.instance.loadComponent(component, config.data);
|
|
170
|
+
const modalRef = new ModalRef(compRef, hostEl);
|
|
171
|
+
compRef.instance.closed.subscribe((result) => {
|
|
172
|
+
modalRef.close(result);
|
|
173
|
+
});
|
|
174
|
+
const maybeEmitter = childRef.instance.onClose;
|
|
175
|
+
if (maybeEmitter && typeof maybeEmitter.subscribe === 'function') {
|
|
176
|
+
maybeEmitter.subscribe((res) => modalRef.close(res));
|
|
177
|
+
}
|
|
178
|
+
return modalRef;
|
|
179
|
+
}
|
|
180
|
+
setInput(targetInstance, key, value) {
|
|
181
|
+
const target = targetInstance[key];
|
|
182
|
+
if (typeof target === 'function' && target && 'set' in target && typeof target.set === 'function') {
|
|
183
|
+
target.set(value);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
targetInstance[key] = value;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModalService, deps: [{ token: i0.Injector }, { token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
190
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModalService, providedIn: 'root' });
|
|
191
|
+
}
|
|
192
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ModalService, decorators: [{
|
|
193
|
+
type: Injectable,
|
|
194
|
+
args: [{ providedIn: 'root' }]
|
|
195
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
|
|
196
|
+
|
|
197
|
+
class TooltipComponent {
|
|
198
|
+
id = signal(`as-tooltip-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
199
|
+
// Writable text so directive can update via `.set(...)`
|
|
200
|
+
text = signal(null, ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
201
|
+
// Placement signal — set by directive to switch arrow orientation
|
|
202
|
+
placement = signal('bottom', ...(ngDevMode ? [{ debugName: "placement" }] : []));
|
|
203
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
204
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: TooltipComponent, isStandalone: true, selector: "as-tooltip", ngImport: i0, template: `
|
|
205
|
+
<div
|
|
206
|
+
class="as-tooltip"
|
|
207
|
+
[class.as-placement-top]="placement() === 'bottom'"
|
|
208
|
+
[class.as-placement-bottom]="placement() === 'top'"
|
|
209
|
+
[class.as-placement-left]="placement() === 'right'"
|
|
210
|
+
[class.as-placement-right]="placement() === 'left'"
|
|
211
|
+
[attr.id]="id()"
|
|
212
|
+
role="tooltip"
|
|
213
|
+
[attr.aria-hidden]="!text()"
|
|
214
|
+
>
|
|
215
|
+
{{ text() }}
|
|
216
|
+
<span class="as-tooltip-arrow" aria-hidden="true"></span>
|
|
217
|
+
</div>
|
|
218
|
+
`, isInline: true, styles: [":host{display:block}.as-tooltip{position:relative;display:inline-block;background:#616161f2;color:#fff;padding:6px 10px;border-radius:4px;font-size:12px;max-width:240px;box-shadow:0 2px 10px #0003;line-height:1.2}.as-tooltip-arrow{position:absolute;width:0;height:0}.as-placement-bottom .as-tooltip-arrow{left:50%;transform:translate(-50%);top:100%;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid rgba(97,97,97,.95)}.as-placement-top .as-tooltip-arrow{left:50%;transform:translate(-50%);bottom:100%;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid rgba(97,97,97,.95)}.as-placement-left .as-tooltip-arrow{top:50%;transform:translateY(-50%);right:100%;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid rgba(97,97,97,.95)}.as-placement-right .as-tooltip-arrow{top:50%;transform:translateY(-50%);left:100%;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid rgba(97,97,97,.95)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
219
|
+
}
|
|
220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TooltipComponent, decorators: [{
|
|
221
|
+
type: Component,
|
|
222
|
+
args: [{ selector: 'as-tooltip', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
223
|
+
<div
|
|
224
|
+
class="as-tooltip"
|
|
225
|
+
[class.as-placement-top]="placement() === 'bottom'"
|
|
226
|
+
[class.as-placement-bottom]="placement() === 'top'"
|
|
227
|
+
[class.as-placement-left]="placement() === 'right'"
|
|
228
|
+
[class.as-placement-right]="placement() === 'left'"
|
|
229
|
+
[attr.id]="id()"
|
|
230
|
+
role="tooltip"
|
|
231
|
+
[attr.aria-hidden]="!text()"
|
|
232
|
+
>
|
|
233
|
+
{{ text() }}
|
|
234
|
+
<span class="as-tooltip-arrow" aria-hidden="true"></span>
|
|
235
|
+
</div>
|
|
236
|
+
`, styles: [":host{display:block}.as-tooltip{position:relative;display:inline-block;background:#616161f2;color:#fff;padding:6px 10px;border-radius:4px;font-size:12px;max-width:240px;box-shadow:0 2px 10px #0003;line-height:1.2}.as-tooltip-arrow{position:absolute;width:0;height:0}.as-placement-bottom .as-tooltip-arrow{left:50%;transform:translate(-50%);top:100%;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid rgba(97,97,97,.95)}.as-placement-top .as-tooltip-arrow{left:50%;transform:translate(-50%);bottom:100%;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid rgba(97,97,97,.95)}.as-placement-left .as-tooltip-arrow{top:50%;transform:translateY(-50%);right:100%;border-top:6px solid transparent;border-bottom:6px solid transparent;border-right:6px solid rgba(97,97,97,.95)}.as-placement-right .as-tooltip-arrow{top:50%;transform:translateY(-50%);left:100%;border-top:6px solid transparent;border-bottom:6px solid transparent;border-left:6px solid rgba(97,97,97,.95)}\n"] }]
|
|
237
|
+
}] });
|
|
238
|
+
|
|
239
|
+
class TooltipDirective {
|
|
240
|
+
overlay = inject(Overlay);
|
|
241
|
+
injector = inject(Injector);
|
|
242
|
+
host = inject((ElementRef));
|
|
243
|
+
asTooltip = input(null, ...(ngDevMode ? [{ debugName: "asTooltip" }] : []));
|
|
244
|
+
asTooltipPlacement = input('auto', ...(ngDevMode ? [{ debugName: "asTooltipPlacement" }] : []));
|
|
245
|
+
overlayRef = null;
|
|
246
|
+
strategy = null;
|
|
247
|
+
posSub = null;
|
|
248
|
+
positions = computed(() => this.buildPositions(this.asTooltipPlacement()), ...(ngDevMode ? [{ debugName: "positions" }] : []));
|
|
249
|
+
show() {
|
|
250
|
+
const text = this.asTooltip();
|
|
251
|
+
if (!text)
|
|
252
|
+
return;
|
|
253
|
+
if (!this.overlayRef) {
|
|
254
|
+
this.createOverlay();
|
|
255
|
+
}
|
|
256
|
+
if (!this.overlayRef.hasAttached()) {
|
|
257
|
+
const portal = new ComponentPortal(TooltipComponent);
|
|
258
|
+
const compRef = this.overlayRef.attach(portal);
|
|
259
|
+
compRef.instance.text.set(text);
|
|
260
|
+
// set aria-describedby
|
|
261
|
+
const id = compRef.instance.id();
|
|
262
|
+
this.host.nativeElement.setAttribute('aria-describedby', id);
|
|
263
|
+
// subscribe to CDK's chosen position and write to tooltip placement signal
|
|
264
|
+
if (this.strategy && !this.posSub) {
|
|
265
|
+
this.posSub = this.strategy.positionChanges.subscribe((change) => {
|
|
266
|
+
// `change` may contain different property names across CDK versions;
|
|
267
|
+
// try common locations for the resolved connected position.
|
|
268
|
+
const pos = change?.connectionPair ?? change?.connectedPosition ?? change?.lastConnectedPosition ?? change;
|
|
269
|
+
if (pos) {
|
|
270
|
+
const placement = this.mapPositionToPlacement(pos);
|
|
271
|
+
compRef.instance.placement.set(placement);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// initial placement hint: map the first position we provided
|
|
276
|
+
const initial = this.positions()[0];
|
|
277
|
+
compRef.instance.placement.set(this.mapPositionToPlacement(initial));
|
|
278
|
+
this.overlayRef.updatePosition();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
hide() {
|
|
282
|
+
this.detachOverlay();
|
|
283
|
+
}
|
|
284
|
+
ngOnDestroy() {
|
|
285
|
+
this.detachOverlay(true);
|
|
286
|
+
}
|
|
287
|
+
createOverlay() {
|
|
288
|
+
const strategy = this.overlay.position()
|
|
289
|
+
.flexibleConnectedTo(this.host)
|
|
290
|
+
.withPositions(this.positions())
|
|
291
|
+
.withPush(true);
|
|
292
|
+
// store strategy so we can watch positionChanges
|
|
293
|
+
this.strategy = strategy;
|
|
294
|
+
strategy.withDefaultOffsetY(8);
|
|
295
|
+
strategy.withDefaultOffsetX(8);
|
|
296
|
+
this.overlayRef = this.overlay.create({
|
|
297
|
+
positionStrategy: strategy,
|
|
298
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
299
|
+
panelClass: 'as-tooltip-panel',
|
|
300
|
+
hasBackdrop: false,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
detachOverlay(dispose = false) {
|
|
304
|
+
if (!this.overlayRef)
|
|
305
|
+
return;
|
|
306
|
+
if (this.overlayRef.hasAttached()) {
|
|
307
|
+
const hostEl = this.host.nativeElement;
|
|
308
|
+
if (hostEl.getAttribute('aria-describedby')) {
|
|
309
|
+
hostEl.removeAttribute('aria-describedby');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
this.overlayRef.detach();
|
|
313
|
+
if (this.posSub) {
|
|
314
|
+
this.posSub.unsubscribe();
|
|
315
|
+
this.posSub = null;
|
|
316
|
+
}
|
|
317
|
+
if (dispose) {
|
|
318
|
+
this.overlayRef.dispose();
|
|
319
|
+
this.overlayRef = null;
|
|
320
|
+
this.strategy = null;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
buildPositions(preferred) {
|
|
324
|
+
const top = {
|
|
325
|
+
originX: 'center', originY: 'top',
|
|
326
|
+
overlayX: 'center', overlayY: 'bottom',
|
|
327
|
+
offsetY: -8
|
|
328
|
+
};
|
|
329
|
+
const bottom = {
|
|
330
|
+
originX: 'center', originY: 'bottom',
|
|
331
|
+
overlayX: 'center', overlayY: 'top',
|
|
332
|
+
offsetY: 8
|
|
333
|
+
};
|
|
334
|
+
const left = {
|
|
335
|
+
originX: 'start', originY: 'center',
|
|
336
|
+
overlayX: 'end', overlayY: 'center',
|
|
337
|
+
offsetX: -8
|
|
338
|
+
};
|
|
339
|
+
const right = {
|
|
340
|
+
originX: 'end', originY: 'center',
|
|
341
|
+
overlayX: 'start', overlayY: 'center',
|
|
342
|
+
offsetX: 8
|
|
343
|
+
};
|
|
344
|
+
if (preferred === 'auto') {
|
|
345
|
+
return [bottom, top, right, left];
|
|
346
|
+
}
|
|
347
|
+
switch (preferred) {
|
|
348
|
+
case 'top': return [top, bottom, right, left];
|
|
349
|
+
case 'bottom': return [bottom, top, right, left];
|
|
350
|
+
case 'left': return [left, right, bottom, top];
|
|
351
|
+
case 'right': return [right, left, bottom, top];
|
|
352
|
+
default: return [bottom, top, right, left];
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
mapPositionToPlacement(pos) {
|
|
356
|
+
// Determine placement by comparing origin/overlay alignment used by CDK
|
|
357
|
+
if (pos.originY === 'top' && pos.overlayY === 'bottom')
|
|
358
|
+
return 'top';
|
|
359
|
+
if (pos.originY === 'bottom' && pos.overlayY === 'top')
|
|
360
|
+
return 'bottom';
|
|
361
|
+
if (pos.originX === 'start' && pos.overlayX === 'end')
|
|
362
|
+
return 'left';
|
|
363
|
+
if (pos.originX === 'end' && pos.overlayX === 'start')
|
|
364
|
+
return 'right';
|
|
365
|
+
// fallback
|
|
366
|
+
return 'bottom';
|
|
367
|
+
}
|
|
368
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
369
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: TooltipDirective, isStandalone: true, selector: "[asTooltip]", inputs: { asTooltip: { classPropertyName: "asTooltip", publicName: "asTooltip", isSignal: true, isRequired: false, transformFunction: null }, asTooltipPlacement: { classPropertyName: "asTooltipPlacement", publicName: "asTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "show()", "mouseleave": "hide()" } }, ngImport: i0 });
|
|
370
|
+
}
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TooltipDirective, decorators: [{
|
|
372
|
+
type: Directive,
|
|
373
|
+
args: [{
|
|
374
|
+
selector: '[asTooltip]',
|
|
375
|
+
standalone: true,
|
|
376
|
+
}]
|
|
377
|
+
}], propDecorators: { asTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "asTooltip", required: false }] }], asTooltipPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "asTooltipPlacement", required: false }] }], show: [{
|
|
378
|
+
type: HostListener,
|
|
379
|
+
args: ['mouseenter']
|
|
380
|
+
}], hide: [{
|
|
381
|
+
type: HostListener,
|
|
382
|
+
args: ['mouseleave']
|
|
383
|
+
}] } });
|
|
384
|
+
|
|
385
|
+
// typescript
|
|
386
|
+
class TypeaheadPanelComponent {
|
|
387
|
+
id = signal(`as-typeahead-panel-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
388
|
+
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
389
|
+
// default shows the `value` field
|
|
390
|
+
displayWith = signal((i) => String(i?.value ?? ''), ...(ngDevMode ? [{ debugName: "displayWith" }] : []));
|
|
391
|
+
activeIndex = signal(null, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
|
|
392
|
+
// visual config: how many items visible before scrollbar (set by directive)
|
|
393
|
+
visibleCount = signal(5, ...(ngDevMode ? [{ debugName: "visibleCount" }] : []));
|
|
394
|
+
itemHeight = 40; // px - used to compute maxHeight
|
|
395
|
+
// optional custom template & callback (set by directive)
|
|
396
|
+
optionTemplate = null;
|
|
397
|
+
onSelect = null;
|
|
398
|
+
optionId(i) {
|
|
399
|
+
return `${this.id()}-option-${i}`;
|
|
400
|
+
}
|
|
401
|
+
setActive(i) {
|
|
402
|
+
this.activeIndex.set(i);
|
|
403
|
+
}
|
|
404
|
+
select(i) {
|
|
405
|
+
const items = this.items();
|
|
406
|
+
if (i == null || i < 0 || i >= items.length)
|
|
407
|
+
return;
|
|
408
|
+
const item = items[i];
|
|
409
|
+
if (this.onSelect)
|
|
410
|
+
this.onSelect(item);
|
|
411
|
+
}
|
|
412
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TypeaheadPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
413
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TypeaheadPanelComponent, isStandalone: true, selector: "as-typeahead-panel", ngImport: i0, template: `
|
|
414
|
+
<div
|
|
415
|
+
class="as-typeahead-panel"
|
|
416
|
+
role="listbox"
|
|
417
|
+
[attr.id]="id()"
|
|
418
|
+
[class.as-empty]="items().length === 0"
|
|
419
|
+
[style.max-height.px]="visibleCount() * itemHeight"
|
|
420
|
+
>
|
|
421
|
+
@for (item of items(); track item.key) {
|
|
422
|
+
<div
|
|
423
|
+
role="option"
|
|
424
|
+
[attr.id]="optionId($index)"
|
|
425
|
+
[attr.aria-selected]="$index === activeIndex()"
|
|
426
|
+
class="as-typeahead-option"
|
|
427
|
+
[class.as-active]="$index === activeIndex()"
|
|
428
|
+
(mouseenter)="setActive($index)"
|
|
429
|
+
(mousemove)="setActive($index)"
|
|
430
|
+
(click)="select($index)"
|
|
431
|
+
>
|
|
432
|
+
@if (optionTemplate) {
|
|
433
|
+
<ng-container
|
|
434
|
+
*ngTemplateOutlet="optionTemplate; context: { $implicit: items()[$index] }"
|
|
435
|
+
></ng-container>
|
|
436
|
+
}
|
|
437
|
+
@else {
|
|
438
|
+
{{ displayWith()(item) }}
|
|
439
|
+
}
|
|
440
|
+
</div>
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@if (items().length === 0) {
|
|
444
|
+
<div class="as-no-results">No results</div>
|
|
445
|
+
}
|
|
446
|
+
</div>
|
|
447
|
+
`, isInline: true, styles: [":host{display:block}.as-typeahead-panel{min-width:160px;overflow:scroll;background:#fff;border:1px solid rgba(0,0,0,.12);box-shadow:0 4px 10px #0000001f;border-radius:4px;padding:4px 0;box-sizing:border-box}.as-typeahead-option{padding:8px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;color:#222;display:block}.as-typeahead-option.as-active{background:#f1f1f1}.as-no-results{padding:8px 12px;color:#00000080}.as-empty{min-width:120px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
448
|
+
}
|
|
449
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TypeaheadPanelComponent, decorators: [{
|
|
450
|
+
type: Component,
|
|
451
|
+
args: [{ selector: 'as-typeahead-panel', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
452
|
+
<div
|
|
453
|
+
class="as-typeahead-panel"
|
|
454
|
+
role="listbox"
|
|
455
|
+
[attr.id]="id()"
|
|
456
|
+
[class.as-empty]="items().length === 0"
|
|
457
|
+
[style.max-height.px]="visibleCount() * itemHeight"
|
|
458
|
+
>
|
|
459
|
+
@for (item of items(); track item.key) {
|
|
460
|
+
<div
|
|
461
|
+
role="option"
|
|
462
|
+
[attr.id]="optionId($index)"
|
|
463
|
+
[attr.aria-selected]="$index === activeIndex()"
|
|
464
|
+
class="as-typeahead-option"
|
|
465
|
+
[class.as-active]="$index === activeIndex()"
|
|
466
|
+
(mouseenter)="setActive($index)"
|
|
467
|
+
(mousemove)="setActive($index)"
|
|
468
|
+
(click)="select($index)"
|
|
469
|
+
>
|
|
470
|
+
@if (optionTemplate) {
|
|
471
|
+
<ng-container
|
|
472
|
+
*ngTemplateOutlet="optionTemplate; context: { $implicit: items()[$index] }"
|
|
473
|
+
></ng-container>
|
|
474
|
+
}
|
|
475
|
+
@else {
|
|
476
|
+
{{ displayWith()(item) }}
|
|
477
|
+
}
|
|
478
|
+
</div>
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
@if (items().length === 0) {
|
|
482
|
+
<div class="as-no-results">No results</div>
|
|
483
|
+
}
|
|
484
|
+
</div>
|
|
485
|
+
`, styles: [":host{display:block}.as-typeahead-panel{min-width:160px;overflow:scroll;background:#fff;border:1px solid rgba(0,0,0,.12);box-shadow:0 4px 10px #0000001f;border-radius:4px;padding:4px 0;box-sizing:border-box}.as-typeahead-option{padding:8px 12px;cursor:pointer;-webkit-user-select:none;user-select:none;color:#222;display:block}.as-typeahead-option.as-active{background:#f1f1f1}.as-no-results{padding:8px 12px;color:#00000080}.as-empty{min-width:120px}\n"] }]
|
|
486
|
+
}] });
|
|
487
|
+
|
|
488
|
+
// typescript
|
|
489
|
+
class TypeaheadDirective {
|
|
490
|
+
overlay = inject(Overlay);
|
|
491
|
+
host = inject((ElementRef));
|
|
492
|
+
vcr = inject(ViewContainerRef);
|
|
493
|
+
// data source: predefined Option[] (no async required)
|
|
494
|
+
options = input(null, ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
495
|
+
// display function (default -> show value)
|
|
496
|
+
displayWith = input((it) => String(it?.value ?? ''), ...(ngDevMode ? [{ debugName: "displayWith" }] : []));
|
|
497
|
+
// when typing, filter by 'key' or 'value'
|
|
498
|
+
filterBy = input('value', ...(ngDevMode ? [{ debugName: "filterBy" }] : []));
|
|
499
|
+
// visible items count (controls panel height / scrollbar)
|
|
500
|
+
visibleCount = input(5, ...(ngDevMode ? [{ debugName: "visibleCount" }] : []));
|
|
501
|
+
// if true user must choose from list; otherwise free text allowed (creates custom option with key = '__custom__')
|
|
502
|
+
restrictToList = input(false, ...(ngDevMode ? [{ debugName: "restrictToList" }] : []));
|
|
503
|
+
// outputs as signals
|
|
504
|
+
selectedChange = signal(null, ...(ngDevMode ? [{ debugName: "selectedChange" }] : []));
|
|
505
|
+
blurEvent = signal(null, ...(ngDevMode ? [{ debugName: "blurEvent" }] : []));
|
|
506
|
+
openedChange = signal(false, ...(ngDevMode ? [{ debugName: "openedChange" }] : []));
|
|
507
|
+
// optional custom template
|
|
508
|
+
asTypeaheadTemplate = input(null, ...(ngDevMode ? [{ debugName: "asTypeaheadTemplate" }] : []));
|
|
509
|
+
// convenience disabled getter (signal input optional)
|
|
510
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
511
|
+
enableLog = input(false, ...(ngDevMode ? [{ debugName: "enableLog" }] : []));
|
|
512
|
+
overlayRef = null;
|
|
513
|
+
panelRefInst = null;
|
|
514
|
+
destroyed = false;
|
|
515
|
+
typeaheadOnSelect = output();
|
|
516
|
+
positions = computed(() => this.buildPositions(), ...(ngDevMode ? [{ debugName: "positions" }] : []));
|
|
517
|
+
_lastEmitted = null;
|
|
518
|
+
constructor() {
|
|
519
|
+
effect(() => {
|
|
520
|
+
const value = this.selectedChange();
|
|
521
|
+
if (value !== this._lastEmitted) {
|
|
522
|
+
this.typeaheadOnSelect.emit(value);
|
|
523
|
+
this._lastEmitted = value;
|
|
524
|
+
this.log('selectedChange', value);
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
effect(() => {
|
|
528
|
+
this.log('init', this.options(), this.filterBy(), this.visibleCount(), this.restrictToList(), this.disabled());
|
|
529
|
+
// this.open()
|
|
530
|
+
// this.showAllOptions();
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
ngOnDestroy() {
|
|
534
|
+
this.destroyed = true;
|
|
535
|
+
this.detach(true);
|
|
536
|
+
}
|
|
537
|
+
// open on focus/click and show full list initially
|
|
538
|
+
onFocusOrClick() {
|
|
539
|
+
if (this.disabled())
|
|
540
|
+
return;
|
|
541
|
+
this.open();
|
|
542
|
+
this.showAllOptions();
|
|
543
|
+
}
|
|
544
|
+
onInput(e) {
|
|
545
|
+
if (this.disabled())
|
|
546
|
+
return;
|
|
547
|
+
const value = e.target.value;
|
|
548
|
+
if (value === '') {
|
|
549
|
+
// empty -> show all
|
|
550
|
+
this.showAllOptions();
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
this.filterAndShow(value);
|
|
554
|
+
}
|
|
555
|
+
onKeydown(e) {
|
|
556
|
+
if (this.disabled())
|
|
557
|
+
return;
|
|
558
|
+
// open on ArrowDown if closed
|
|
559
|
+
if ((!this.overlayRef || !this.overlayRef.hasAttached()) && e.key === 'ArrowDown') {
|
|
560
|
+
this.open();
|
|
561
|
+
this.showAllOptions();
|
|
562
|
+
e.preventDefault();
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
if (!this.overlayRef || !this.overlayRef.hasAttached())
|
|
566
|
+
return;
|
|
567
|
+
const panel = this.panelRefInst;
|
|
568
|
+
const items = panel?.items?.() ?? [];
|
|
569
|
+
switch (e.key) {
|
|
570
|
+
case 'ArrowDown':
|
|
571
|
+
e.preventDefault();
|
|
572
|
+
if (items.length === 0)
|
|
573
|
+
return;
|
|
574
|
+
const next = (panel.activeIndex() == null) ? 0 : Math.min(items.length - 1, panel.activeIndex() + 1);
|
|
575
|
+
panel.activeIndex.set(next);
|
|
576
|
+
this.scrollToActive();
|
|
577
|
+
break;
|
|
578
|
+
case 'ArrowUp':
|
|
579
|
+
e.preventDefault();
|
|
580
|
+
if (items.length === 0)
|
|
581
|
+
return;
|
|
582
|
+
const prev = (panel.activeIndex() == null) ? items.length - 1 : Math.max(0, panel.activeIndex() - 1);
|
|
583
|
+
panel.activeIndex.set(prev);
|
|
584
|
+
this.scrollToActive();
|
|
585
|
+
break;
|
|
586
|
+
case 'Enter':
|
|
587
|
+
e.preventDefault();
|
|
588
|
+
if (panel.activeIndex() != null) {
|
|
589
|
+
const i = panel.activeIndex();
|
|
590
|
+
const it = items[i];
|
|
591
|
+
this.select(it);
|
|
592
|
+
}
|
|
593
|
+
break;
|
|
594
|
+
case 'Escape':
|
|
595
|
+
e.preventDefault();
|
|
596
|
+
this.close();
|
|
597
|
+
break;
|
|
598
|
+
default:
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
onBlur() {
|
|
603
|
+
// delay to allow click handlers on overlay to run
|
|
604
|
+
setTimeout(() => {
|
|
605
|
+
if (this.destroyed)
|
|
606
|
+
return;
|
|
607
|
+
const text = this.host.nativeElement.value?.toString() ?? '';
|
|
608
|
+
const match = this.findMatchingOption(text);
|
|
609
|
+
if (this.restrictToList() && !match) {
|
|
610
|
+
// must choose from list -> clear input and selection
|
|
611
|
+
this.selectedChange.set(null);
|
|
612
|
+
this.host.nativeElement.value = '';
|
|
613
|
+
}
|
|
614
|
+
else if (match) {
|
|
615
|
+
// matched an option -> set selection
|
|
616
|
+
this.selectedChange.set(match);
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
// no match and free text allowed -> keep input text but do NOT create a custom Option
|
|
620
|
+
this.selectedChange.set(null);
|
|
621
|
+
}
|
|
622
|
+
this.blurEvent.set(text || null);
|
|
623
|
+
this.close();
|
|
624
|
+
}, 150);
|
|
625
|
+
}
|
|
626
|
+
// helper to create overlay and attach panel
|
|
627
|
+
open() {
|
|
628
|
+
if (this.disabled())
|
|
629
|
+
return;
|
|
630
|
+
if (!this.overlayRef)
|
|
631
|
+
this.createOverlay();
|
|
632
|
+
if (!this.overlayRef.hasAttached()) {
|
|
633
|
+
const portal = new ComponentPortal(TypeaheadPanelComponent, this.vcr);
|
|
634
|
+
const compRef = this.overlayRef.attach(portal);
|
|
635
|
+
this.panelRefInst = compRef.instance;
|
|
636
|
+
this.panelRefInst.displayWith.set(this.displayWith());
|
|
637
|
+
this.panelRefInst.optionTemplate = this.asTypeaheadTemplate();
|
|
638
|
+
this.panelRefInst.visibleCount.set(this.visibleCount());
|
|
639
|
+
this.panelRefInst.onSelect = (item) => this.select(item);
|
|
640
|
+
const el = this.host.nativeElement;
|
|
641
|
+
el.setAttribute('role', 'combobox');
|
|
642
|
+
el.setAttribute('aria-autocomplete', 'list');
|
|
643
|
+
el.setAttribute('aria-expanded', 'true');
|
|
644
|
+
el.setAttribute('aria-controls', this.panelRefInst.id());
|
|
645
|
+
this.openedChange.set(true);
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
this.overlayRef.updatePosition();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
close() {
|
|
652
|
+
this.detach();
|
|
653
|
+
this.openedChange.set(false);
|
|
654
|
+
}
|
|
655
|
+
detach(dispose = false) {
|
|
656
|
+
if (!this.overlayRef)
|
|
657
|
+
return;
|
|
658
|
+
if (this.overlayRef.hasAttached()) {
|
|
659
|
+
this.overlayRef.detach();
|
|
660
|
+
const el = this.host.nativeElement;
|
|
661
|
+
el.removeAttribute('aria-controls');
|
|
662
|
+
el.setAttribute('aria-expanded', 'false');
|
|
663
|
+
el.removeAttribute('aria-activedescendant');
|
|
664
|
+
}
|
|
665
|
+
if (dispose) {
|
|
666
|
+
this.overlayRef.dispose();
|
|
667
|
+
this.overlayRef = null;
|
|
668
|
+
this.panelRefInst = null;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
createOverlay() {
|
|
672
|
+
const strategy = this.overlay.position()
|
|
673
|
+
.flexibleConnectedTo(this.host)
|
|
674
|
+
.withPositions(this.positions())
|
|
675
|
+
.withPush(true);
|
|
676
|
+
strategy.withDefaultOffsetY(4);
|
|
677
|
+
strategy.withDefaultOffsetX(0);
|
|
678
|
+
this.overlayRef = this.overlay.create({
|
|
679
|
+
positionStrategy: strategy,
|
|
680
|
+
hasBackdrop: false,
|
|
681
|
+
panelClass: undefined,
|
|
682
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
683
|
+
});
|
|
684
|
+
// reposition on strategy changes
|
|
685
|
+
strategy.positionChanges.subscribe(() => {
|
|
686
|
+
setTimeout(() => this.overlayRef?.updatePosition(), 0);
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
showAllOptions() {
|
|
690
|
+
const list = this.options() ?? [];
|
|
691
|
+
if (!this.overlayRef || !this.overlayRef.hasAttached()) {
|
|
692
|
+
this.open();
|
|
693
|
+
}
|
|
694
|
+
if (this.panelRefInst) {
|
|
695
|
+
this.panelRefInst.items.set(list);
|
|
696
|
+
this.panelRefInst.activeIndex.set(null);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
filterAndShow(q) {
|
|
700
|
+
const list = this.options() ?? [];
|
|
701
|
+
const key = q.toLowerCase();
|
|
702
|
+
const filtered = list.filter(it => {
|
|
703
|
+
if (!it)
|
|
704
|
+
return false;
|
|
705
|
+
const target = this.filterBy() === 'key' ? String(it.key) : String(it.value);
|
|
706
|
+
return target.toLowerCase().includes(key);
|
|
707
|
+
});
|
|
708
|
+
if (!this.overlayRef || !this.overlayRef.hasAttached())
|
|
709
|
+
this.open();
|
|
710
|
+
if (this.panelRefInst) {
|
|
711
|
+
this.panelRefInst.items.set(filtered);
|
|
712
|
+
if (filtered.length > 0) {
|
|
713
|
+
this.panelRefInst.activeIndex.set(0);
|
|
714
|
+
this.scrollToActive();
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
this.panelRefInst.activeIndex.set(null);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
select(item) {
|
|
722
|
+
this.selectedChange.set(item);
|
|
723
|
+
try {
|
|
724
|
+
this.host.nativeElement.value = this.displayWith()(item);
|
|
725
|
+
}
|
|
726
|
+
catch { /* ignore */ }
|
|
727
|
+
this.close();
|
|
728
|
+
this.host.nativeElement.focus();
|
|
729
|
+
}
|
|
730
|
+
scrollToActive() {
|
|
731
|
+
const panelEl = this.overlayRef?.overlayElement;
|
|
732
|
+
if (!panelEl || !this.panelRefInst)
|
|
733
|
+
return;
|
|
734
|
+
const idx = this.panelRefInst.activeIndex();
|
|
735
|
+
if (idx == null)
|
|
736
|
+
return;
|
|
737
|
+
const optionEl = panelEl.querySelector(`#${this.panelRefInst.optionId(idx)}`);
|
|
738
|
+
if (optionEl) {
|
|
739
|
+
const panelRect = panelEl.getBoundingClientRect();
|
|
740
|
+
const optRect = optionEl.getBoundingClientRect();
|
|
741
|
+
if (optRect.top < panelRect.top) {
|
|
742
|
+
panelEl.scrollTop -= (panelRect.top - optRect.top);
|
|
743
|
+
}
|
|
744
|
+
else if (optRect.bottom > panelRect.bottom) {
|
|
745
|
+
panelEl.scrollTop += (optRect.bottom - panelRect.bottom);
|
|
746
|
+
}
|
|
747
|
+
this.host.nativeElement.setAttribute('aria-activedescendant', optionEl.id);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
findMatchingOption(text) {
|
|
751
|
+
const list = this.options() ?? [];
|
|
752
|
+
if (!text)
|
|
753
|
+
return null;
|
|
754
|
+
const t = text.toLowerCase();
|
|
755
|
+
for (const it of list) {
|
|
756
|
+
if (this.displayWith()(it).toLowerCase() === t)
|
|
757
|
+
return it;
|
|
758
|
+
if (String(it.key).toLowerCase() === t)
|
|
759
|
+
return it;
|
|
760
|
+
}
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
buildPositions() {
|
|
764
|
+
const bottomStart = {
|
|
765
|
+
originX: 'start', originY: 'bottom',
|
|
766
|
+
overlayX: 'start', overlayY: 'top',
|
|
767
|
+
offsetY: 4
|
|
768
|
+
};
|
|
769
|
+
const topStart = {
|
|
770
|
+
originX: 'start', originY: 'top',
|
|
771
|
+
overlayX: 'start', overlayY: 'bottom',
|
|
772
|
+
offsetY: -4
|
|
773
|
+
};
|
|
774
|
+
return [bottomStart, topStart];
|
|
775
|
+
}
|
|
776
|
+
log(value, ...rest) {
|
|
777
|
+
if (this.enableLog() || localStorage.getItem('loggerEnable')) {
|
|
778
|
+
console.log('%c DEBUG ', 'background: gray; color: white; font-weight: bold;', `AS Components -> ${value}`, ...rest);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TypeaheadDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
782
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: TypeaheadDirective, isStandalone: true, selector: "[asTypeahead]", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, visibleCount: { classPropertyName: "visibleCount", publicName: "visibleCount", isSignal: true, isRequired: false, transformFunction: null }, restrictToList: { classPropertyName: "restrictToList", publicName: "restrictToList", isSignal: true, isRequired: false, transformFunction: null }, asTypeaheadTemplate: { classPropertyName: "asTypeaheadTemplate", publicName: "asTypeaheadTemplate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, enableLog: { classPropertyName: "enableLog", publicName: "enableLog", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { typeaheadOnSelect: "typeaheadOnSelect" }, host: { listeners: { "focus": "onFocusOrClick()", "click": "onFocusOrClick()", "input": "onInput($event)", "keydown": "onKeydown($event)", "blur": "onBlur()" } }, ngImport: i0 });
|
|
783
|
+
}
|
|
784
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TypeaheadDirective, decorators: [{
|
|
785
|
+
type: Directive,
|
|
786
|
+
args: [{
|
|
787
|
+
selector: '[asTypeahead]',
|
|
788
|
+
standalone: true,
|
|
789
|
+
}]
|
|
790
|
+
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], filterBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterBy", required: false }] }], visibleCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleCount", required: false }] }], restrictToList: [{ type: i0.Input, args: [{ isSignal: true, alias: "restrictToList", required: false }] }], asTypeaheadTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "asTypeaheadTemplate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], enableLog: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableLog", required: false }] }], typeaheadOnSelect: [{ type: i0.Output, args: ["typeaheadOnSelect"] }], onFocusOrClick: [{
|
|
791
|
+
type: HostListener,
|
|
792
|
+
args: ['focus']
|
|
793
|
+
}, {
|
|
794
|
+
type: HostListener,
|
|
795
|
+
args: ['click']
|
|
796
|
+
}], onInput: [{
|
|
797
|
+
type: HostListener,
|
|
798
|
+
args: ['input', ['$event']]
|
|
799
|
+
}], onKeydown: [{
|
|
800
|
+
type: HostListener,
|
|
801
|
+
args: ['keydown', ['$event']]
|
|
802
|
+
}], onBlur: [{
|
|
803
|
+
type: HostListener,
|
|
804
|
+
args: ['blur']
|
|
805
|
+
}] } });
|
|
806
|
+
|
|
807
|
+
/*
|
|
808
|
+
* Public API Surface of as-components
|
|
809
|
+
*/
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Generated bundle index. Do not edit.
|
|
813
|
+
*/
|
|
814
|
+
|
|
815
|
+
export { AsComponents, ModalContainerComponent, ModalRef, ModalService, TooltipComponent, TooltipDirective, TypeaheadDirective, TypeaheadPanelComponent };
|
|
816
|
+
//# sourceMappingURL=agentsmith.bgd-as-components.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentsmith.bgd-as-components.mjs","sources":["../../../projects/as-components/src/lib/as-components.ts","../../../projects/as-components/src/lib/modal-container/modal-container.component.ts","../../../projects/as-components/src/lib/services/modal-ref.ts","../../../projects/as-components/src/lib/services/modal.service.ts","../../../projects/as-components/src/lib/tooltip/tooltip.component.ts","../../../projects/as-components/src/lib/tooltip/tooltip.directive.ts","../../../projects/as-components/src/lib/typeahead/typeahead-panel.component.ts","../../../projects/as-components/src/lib/typeahead/typeahead.directive.ts","../../../projects/as-components/src/public-api.ts","../../../projects/as-components/src/agentsmith.bgd-as-components.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 'lib-as-components',\n imports: [],\n template: `\n <p>\n as-components works!\n </p>\n `,\n styles: ``,\n})\nexport class AsComponents {\n\n}\n","// TypeScript\nimport {\n Component,\n EventEmitter,\n signal,\n WritableSignal,\n Input as _DeprecatedInput,\n Output,\n ViewChild,\n ViewContainerRef,\n Type,\n ComponentRef,\n ChangeDetectionStrategy\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'as-modal-container',\n template: `\n <div class=\"as-modal-backdrop\" (click)=\"backdropClick()\"></div>\n <div class=\"as-modal\" [ngClass]=\"size()\" role=\"dialog\" aria-modal=\"true\">\n <div class=\"as-modal-header\" *ngIf=\"title() || showClose()\">\n <h3 class=\"as-modal-title\">{{ title() }}</h3>\n <button *ngIf=\"showClose()\" class=\"as-modal-close\" (click)=\"close()\">×</button>\n </div>\n <div class=\"as-modal-body\">\n <ng-template #contentHost></ng-template>\n </div>\n </div>\n `,\n styles: [\n `.as-modal-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1000}`,\n `.as-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:1001;background:#fff;border-radius:4px;max-width:90%}`,\n `.as-modal.sm{width:300px}`, `.as-modal.md{width:600px}`, `.as-modal.lg{width:900px}`,\n `.as-modal-header{display:flex;justify-content:space-between;align-items:center;padding:12px;border-bottom:1px solid #eee}`,\n `.as-modal-body{padding:12px}`,\n `.as-modal-close{background:none;border:0;font-size:20px;cursor:pointer}`\n ],\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true\n})\nexport class ModalContainerComponent {\n @ViewChild('contentHost', { read: ViewContainerRef, static: true }) contentHost!: ViewContainerRef;\n\n // signal-based inputs\n title: WritableSignal<string | undefined> = signal<string | undefined>(undefined);\n size: WritableSignal<'sm' | 'md' | 'lg'> = signal<'sm' | 'md' | 'lg'>('md');\n showClose: WritableSignal<boolean> = signal<boolean>(true);\n\n @Output() closed = new EventEmitter<any>();\n\n get sizeClass() {\n return this.size(); // template uses size() directly; keep helper for compatibility if needed\n }\n\n /**\n * Create a component inside the container and set inputs.\n * Supports:\n * - assigning to writable signals (calls `.set(...)`)\n * - assigning to plain properties\n * Also handles primitive `inputs` mapping to common names.\n */\n loadComponent<T>(component: Type<T>, inputs?: Partial<T> | any): ComponentRef<T> {\n const compRef = this.contentHost.createComponent<T>(component);\n\n if (inputs !== undefined && inputs !== null) {\n if (typeof inputs === 'object' && !Array.isArray(inputs)) {\n for (const key of Object.keys(inputs)) {\n this.setInput(compRef.instance as any, key, (inputs as any)[key]);\n }\n } else {\n // primitive mapping\n const inst = compRef.instance as any;\n if ('message' in inst) this.setInput(inst, 'message', inputs);\n else if ('data' in inst) this.setInput(inst, 'data', inputs);\n else this.setInput(inst, 'value', inputs);\n }\n\n // ensure rendering for OnPush / signal changes\n compRef.changeDetectorRef?.detectChanges();\n }\n\n return compRef;\n }\n\n private setInput(targetInstance: any, key: string, value: any) {\n const target = targetInstance[key];\n // writable signal: function with 'set'\n if (typeof target === 'function' && target && 'set' in target && typeof (target as any).set === 'function') {\n (target as WritableSignal<any>).set(value);\n } else {\n targetInstance[key] = value;\n }\n }\n\n backdropClick() {\n this.close();\n }\n\n close(result?: any) {\n this.closed.emit(result);\n }\n}\n","// TypeScript\nimport { ComponentRef } from '@angular/core';\nimport { Subject, Observable } from 'rxjs';\n\nexport class ModalRef {\n private _onClose = new Subject<any>();\n onClose: Observable<any> = this._onClose.asObservable();\n\n constructor(private componentRef: ComponentRef<any>, private hostElement: HTMLElement) {}\n\n close(result?: any) {\n this._onClose.next(result);\n this._onClose.complete();\n this.destroy();\n }\n\n private destroy() {\n try {\n if (this.componentRef) {\n this.componentRef.destroy();\n }\n } finally {\n if (this.hostElement && this.hostElement.parentNode) {\n this.hostElement.parentNode.removeChild(this.hostElement);\n }\n }\n }\n}\n","// TypeScript\nimport { Injectable, ApplicationRef, Injector, Type, ComponentRef, createComponent, EnvironmentInjector } from '@angular/core';\nimport { ModalRef } from './modal-ref';\nimport { ModalContainerComponent } from '../modal-container/modal-container.component';\n\nexport interface ModalConfig {\n id?: string;\n size?: 'sm' | 'md' | 'lg';\n title?: string;\n showClose?: boolean;\n data?: any;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ModalService {\n constructor(\n private injector: Injector,\n private appRef: ApplicationRef,\n private envInjector: EnvironmentInjector\n ) {}\n\n show<T>(component: Type<T>, config: ModalConfig = {}): ModalRef {\n const hostEl = document.createElement('div');\n document.body.appendChild(hostEl);\n\n const compRef: ComponentRef<ModalContainerComponent> = createComponent(ModalContainerComponent, {\n environmentInjector: this.envInjector\n });\n\n // set container inputs using signal-aware helper\n this.setInput(compRef.instance as any, 'title', config.title);\n this.setInput(compRef.instance as any, 'size', config.size ?? 'md');\n this.setInput(compRef.instance as any, 'showClose', config.showClose !== false);\n\n this.appRef.attachView(compRef.hostView);\n hostEl.appendChild((compRef.hostView as any).rootNodes[0] as HTMLElement);\n\n // the container's loadComponent handles assigning inputs (including signals) to the child\n const childRef: ComponentRef<T> = compRef.instance.loadComponent(component, config.data);\n\n const modalRef = new ModalRef(compRef as any, hostEl);\n\n compRef.instance.closed.subscribe((result?: any) => {\n modalRef.close(result);\n });\n\n const maybeEmitter = (childRef.instance as any).onClose;\n if (maybeEmitter && typeof maybeEmitter.subscribe === 'function') {\n maybeEmitter.subscribe((res: any) => modalRef.close(res));\n }\n\n return modalRef;\n }\n\n private setInput(targetInstance: any, key: string, value: any) {\n const target = targetInstance[key];\n if (typeof target === 'function' && target && 'set' in target && typeof (target as any).set === 'function') {\n (target as any).set(value);\n } else {\n targetInstance[key] = value;\n }\n }\n}\n","\nimport { Component, signal, WritableSignal, ChangeDetectionStrategy } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'as-tooltip',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n class=\"as-tooltip\"\n [class.as-placement-top]=\"placement() === 'bottom'\"\n [class.as-placement-bottom]=\"placement() === 'top'\"\n [class.as-placement-left]=\"placement() === 'right'\"\n [class.as-placement-right]=\"placement() === 'left'\"\n [attr.id]=\"id()\"\n role=\"tooltip\"\n [attr.aria-hidden]=\"!text()\"\n >\n {{ text() }}\n <span class=\"as-tooltip-arrow\" aria-hidden=\"true\"></span>\n </div>\n `,\n styles: [\n `\n :host { display: block; }\n\n .as-tooltip {\n position: relative;\n display: inline-block;\n background: rgba(97, 97, 97, 0.95);\n color: #fff;\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 12px;\n max-width: 240px;\n box-shadow: 0 2px 10px rgba(0,0,0,0.2);\n line-height: 1.2;\n }\n\n /* Arrow base: zero-sized element using borders to form a triangle */\n .as-tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n }\n\n /* Bottom placement: tooltip sits above origin, arrow points downwards (at bottom of tooltip) */\n .as-placement-bottom .as-tooltip-arrow {\n left: 50%;\n transform: translateX(-50%);\n top: 100%;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-top: 6px solid rgba(97, 97, 97, 0.95);\n }\n\n /* Top placement: tooltip sits below origin, arrow points upwards (at top of tooltip) */\n .as-placement-top .as-tooltip-arrow {\n left: 50%;\n transform: translateX(-50%);\n bottom: 100%;\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid rgba(97, 97, 97, 0.95);\n }\n\n /* Left placement: tooltip sits to the right of origin, arrow points left (at left edge) */\n .as-placement-left .as-tooltip-arrow {\n top: 50%;\n transform: translateY(-50%);\n right: 100%;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-right: 6px solid rgba(97, 97, 97, 0.95);\n }\n\n /* Right placement: tooltip sits to the left of origin, arrow points right (at right edge) */\n .as-placement-right .as-tooltip-arrow {\n top: 50%;\n transform: translateY(-50%);\n left: 100%;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n border-left: 6px solid rgba(97, 97, 97, 0.95);\n }\n `\n ]\n})\nexport class TooltipComponent {\n readonly id: WritableSignal<string> = signal(`as-tooltip-${Math.random().toString(36).slice(2, 9)}`);\n\n // Writable text so directive can update via `.set(...)`\n readonly text: WritableSignal<string | null> = signal<string | null>(null);\n\n // Placement signal — set by directive to switch arrow orientation\n readonly placement: WritableSignal<'top' | 'bottom' | 'left' | 'right'> =\n signal<'top' | 'bottom' | 'left' | 'right'>('bottom');\n}\n","import {\n Directive,\n ElementRef,\n HostListener,\n inject,\n input,\n signal,\n computed,\n OnDestroy,\n WritableSignal,\n Injector\n} from '@angular/core';\nimport { Overlay, OverlayRef, FlexibleConnectedPositionStrategy, ConnectedPosition } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { Subscription } from 'rxjs';\nimport { TooltipComponent } from './tooltip.component';\n\n@Directive({\n selector: '[asTooltip]',\n standalone: true,\n})\nexport class TooltipDirective implements OnDestroy {\n private readonly overlay = inject(Overlay);\n private readonly injector = inject(Injector);\n private readonly host = inject(ElementRef<HTMLElement>);\n\n readonly asTooltip = input<string | null>(null);\n readonly asTooltipPlacement= input<'top' | 'bottom' | 'left' | 'right' | 'auto'>('auto');\n\n private overlayRef: OverlayRef | null = null;\n private strategy: FlexibleConnectedPositionStrategy | null = null;\n private posSub: Subscription | null = null;\n\n private readonly positions = computed(() => this.buildPositions(this.asTooltipPlacement()));\n\n @HostListener('mouseenter')\n show(): void {\n const text = this.asTooltip();\n if (!text) return;\n\n if (!this.overlayRef) {\n this.createOverlay();\n }\n\n if (!this.overlayRef!.hasAttached()) {\n const portal = new ComponentPortal(TooltipComponent);\n const compRef = this.overlayRef!.attach(portal);\n\n compRef.instance.text.set(text);\n\n // set aria-describedby\n const id = compRef.instance.id();\n this.host.nativeElement.setAttribute('aria-describedby', id);\n\n // subscribe to CDK's chosen position and write to tooltip placement signal\n if (this.strategy && !this.posSub) {\n this.posSub = this.strategy.positionChanges.subscribe((change: any) => {\n // `change` may contain different property names across CDK versions;\n // try common locations for the resolved connected position.\n const pos: ConnectedPosition | undefined =\n change?.connectionPair ?? change?.connectedPosition ?? change?.lastConnectedPosition ?? change;\n\n if (pos) {\n const placement = this.mapPositionToPlacement(pos);\n compRef.instance.placement.set(placement);\n }\n });\n }\n\n // initial placement hint: map the first position we provided\n const initial = this.positions()[0];\n compRef.instance.placement.set(this.mapPositionToPlacement(initial));\n\n this.overlayRef!.updatePosition();\n }\n }\n\n @HostListener('mouseleave')\n hide(): void {\n this.detachOverlay();\n }\n\n ngOnDestroy(): void {\n this.detachOverlay(true);\n }\n\n private createOverlay(): void {\n const strategy = this.overlay.position()\n .flexibleConnectedTo(this.host)\n .withPositions(this.positions())\n .withPush(true) as FlexibleConnectedPositionStrategy;\n\n // store strategy so we can watch positionChanges\n this.strategy = strategy;\n\n strategy.withDefaultOffsetY(8);\n strategy.withDefaultOffsetX(8);\n\n this.overlayRef = this.overlay.create({\n positionStrategy: strategy,\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\n panelClass: 'as-tooltip-panel',\n hasBackdrop: false,\n });\n }\n\n private detachOverlay(dispose = false): void {\n if (!this.overlayRef) return;\n\n if (this.overlayRef.hasAttached()) {\n const hostEl = this.host.nativeElement;\n if (hostEl.getAttribute('aria-describedby')) {\n hostEl.removeAttribute('aria-describedby');\n }\n }\n\n this.overlayRef.detach();\n\n if (this.posSub) {\n this.posSub.unsubscribe();\n this.posSub = null;\n }\n\n if (dispose) {\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.strategy = null;\n }\n }\n\n private buildPositions(preferred: 'top' | 'bottom' | 'left' | 'right' | 'auto'): ConnectedPosition[] {\n const top: ConnectedPosition = {\n originX: 'center', originY: 'top',\n overlayX: 'center', overlayY: 'bottom',\n offsetY: -8\n };\n const bottom: ConnectedPosition = {\n originX: 'center', originY: 'bottom',\n overlayX: 'center', overlayY: 'top',\n offsetY: 8\n };\n const left: ConnectedPosition = {\n originX: 'start', originY: 'center',\n overlayX: 'end', overlayY: 'center',\n offsetX: -8\n };\n const right: ConnectedPosition = {\n originX: 'end', originY: 'center',\n overlayX: 'start', overlayY: 'center',\n offsetX: 8\n };\n\n if (preferred === 'auto') {\n return [bottom, top, right, left];\n }\n\n switch (preferred) {\n case 'top': return [top, bottom, right, left];\n case 'bottom': return [bottom, top, right, left];\n case 'left': return [left, right, bottom, top];\n case 'right': return [right, left, bottom, top];\n default: return [bottom, top, right, left];\n }\n }\n\n private mapPositionToPlacement(pos: ConnectedPosition): 'top' | 'bottom' | 'left' | 'right' {\n // Determine placement by comparing origin/overlay alignment used by CDK\n if (pos.originY === 'top' && pos.overlayY === 'bottom') return 'top';\n if (pos.originY === 'bottom' && pos.overlayY === 'top') return 'bottom';\n if (pos.originX === 'start' && pos.overlayX === 'end') return 'left';\n if (pos.originX === 'end' && pos.overlayX === 'start') return 'right';\n // fallback\n return 'bottom';\n }\n}\n","// typescript\nimport { Component, signal, WritableSignal, ChangeDetectionStrategy, TemplateRef } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nexport interface Option {\n key: string;\n value: string;\n}\n\n@Component({\n selector: 'as-typeahead-panel',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n class=\"as-typeahead-panel\"\n role=\"listbox\"\n [attr.id]=\"id()\"\n [class.as-empty]=\"items().length === 0\"\n [style.max-height.px]=\"visibleCount() * itemHeight\"\n >\n @for (item of items(); track item.key) {\n <div\n role=\"option\"\n [attr.id]=\"optionId($index)\"\n [attr.aria-selected]=\"$index === activeIndex()\"\n class=\"as-typeahead-option\"\n [class.as-active]=\"$index === activeIndex()\"\n (mouseenter)=\"setActive($index)\"\n (mousemove)=\"setActive($index)\"\n (click)=\"select($index)\"\n >\n @if (optionTemplate) {\n <ng-container\n *ngTemplateOutlet=\"optionTemplate; context: { $implicit: items()[$index] }\"\n ></ng-container>\n }\n @else {\n {{ displayWith()(item) }}\n }\n </div>\n }\n\n @if (items().length === 0) {\n <div class=\"as-no-results\">No results</div>\n }\n </div>\n `,\n styles: [\n `\n :host { display:block; }\n .as-typeahead-panel {\n min-width: 160px;\n overflow: scroll;\n background: #fff;\n border: 1px solid rgba(0,0,0,0.12);\n box-shadow: 0 4px 10px rgba(0,0,0,0.12);\n border-radius: 4px;\n padding: 4px 0;\n box-sizing: border-box;\n }\n .as-typeahead-option {\n padding: 8px 12px;\n cursor: pointer;\n user-select: none;\n color: #222;\n display: block;\n }\n .as-typeahead-option.as-active {\n background: #f1f1f1;\n }\n .as-no-results {\n padding: 8px 12px;\n color: rgba(0,0,0,0.5);\n }\n .as-empty { min-width: 120px; }\n `\n ]\n})\nexport class TypeaheadPanelComponent {\n readonly id: WritableSignal<string> = signal(`as-typeahead-panel-${Math.random().toString(36).slice(2,9)}`);\n\n readonly items: WritableSignal<Option[]> = signal<Option[]>([]);\n // default shows the `value` field\n readonly displayWith: WritableSignal<(item: Option) => string> =\n signal<(item: Option) => string>((i: Option) => String(i?.value ?? ''));\n\n readonly activeIndex: WritableSignal<number | null> = signal<number | null>(null);\n\n // visual config: how many items visible before scrollbar (set by directive)\n readonly visibleCount: WritableSignal<number> = signal<number>(5);\n readonly itemHeight = 40; // px - used to compute maxHeight\n\n // optional custom template & callback (set by directive)\n optionTemplate: TemplateRef<any> | null = null;\n onSelect: ((item: Option) => void) | null = null;\n\n optionId(i: number) {\n return `${this.id()}-option-${i}`;\n }\n\n setActive(i: number | null) {\n this.activeIndex.set(i);\n }\n\n select(i: number) {\n const items = this.items();\n if (i == null || i < 0 || i >= items.length) return;\n const item = items[i];\n if (this.onSelect) this.onSelect(item);\n }\n}\n","// typescript\nimport {\n Directive,\n ElementRef,\n HostListener,\n inject,\n input,\n signal,\n WritableSignal,\n computed,\n OnDestroy,\n TemplateRef,\n ViewContainerRef, effect, output\n} from '@angular/core';\nimport { Overlay, OverlayRef, FlexibleConnectedPositionStrategy, ConnectedPosition } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { TypeaheadPanelComponent, Option } from './typeahead-panel.component';\n\n@Directive({\n selector: '[asTypeahead]',\n standalone: true,\n})\nexport class TypeaheadDirective implements OnDestroy {\n private readonly overlay = inject(Overlay);\n private readonly host = inject(ElementRef<HTMLInputElement>);\n private readonly vcr = inject(ViewContainerRef);\n\n // data source: predefined Option[] (no async required)\n readonly options = input<Option[] | null>(null);\n\n // display function (default -> show value)\n readonly displayWith =\n input<(item: Option) => string>((it: Option) => String(it?.value ?? ''));\n\n // when typing, filter by 'key' or 'value'\n readonly filterBy = input<'key' | 'value'>('value');\n\n // visible items count (controls panel height / scrollbar)\n readonly visibleCount = input<number>(5);\n\n // if true user must choose from list; otherwise free text allowed (creates custom option with key = '__custom__')\n readonly restrictToList = input<boolean>(false);\n\n // outputs as signals\n readonly selectedChange = signal<Option | null>(null);\n readonly blurEvent = signal<string | null>(null);\n readonly openedChange = signal<boolean>(false);\n\n // optional custom template\n readonly asTypeaheadTemplate = input<TemplateRef<any> | null>(null);\n\n // convenience disabled getter (signal input optional)\n readonly disabled = input<boolean>(false);\n\n readonly enableLog = input<boolean>(false);\n\n private overlayRef: OverlayRef | null = null;\n private panelRefInst: TypeaheadPanelComponent | null = null;\n private destroyed = false;\n\n typeaheadOnSelect = output<Option | null>()\n\n private readonly positions = computed(() => this.buildPositions());\n private _lastEmitted: Option | null = null;\n\n constructor() {\n effect(() => {\n const value = this.selectedChange();\n if (value !== this._lastEmitted) {\n this.typeaheadOnSelect.emit(value);\n this._lastEmitted = value;\n this.log('selectedChange', value);\n }\n });\n\n effect(() => {\n this.log('init', this.options(), this.filterBy(), this.visibleCount(), this.restrictToList(), this.disabled());\n // this.open()\n // this.showAllOptions();\n });\n\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n this.detach(true);\n }\n\n // open on focus/click and show full list initially\n @HostListener('focus')\n @HostListener('click')\n onFocusOrClick() {\n if (this.disabled()) return;\n this.open();\n this.showAllOptions();\n }\n\n @HostListener('input', ['$event'])\n onInput(e: Event) {\n if (this.disabled()) return;\n const value = (e.target as HTMLInputElement).value;\n if (value === '') {\n // empty -> show all\n this.showAllOptions();\n return;\n }\n this.filterAndShow(value);\n }\n\n @HostListener('keydown', ['$event'])\n onKeydown(e: KeyboardEvent) {\n if (this.disabled()) return;\n\n // open on ArrowDown if closed\n if ((!this.overlayRef || !this.overlayRef.hasAttached()) && e.key === 'ArrowDown') {\n this.open();\n this.showAllOptions();\n e.preventDefault();\n return;\n }\n\n if (!this.overlayRef || !this.overlayRef.hasAttached()) return;\n\n const panel = this.panelRefInst!;\n const items = panel?.items?.() ?? [];\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (items.length === 0) return;\n const next = (panel.activeIndex() == null) ? 0 : Math.min(items.length - 1, panel.activeIndex()! + 1);\n panel.activeIndex.set(next);\n this.scrollToActive();\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (items.length === 0) return;\n const prev = (panel.activeIndex() == null) ? items.length - 1 : Math.max(0, panel.activeIndex()! - 1);\n panel.activeIndex.set(prev);\n this.scrollToActive();\n break;\n case 'Enter':\n e.preventDefault();\n if (panel.activeIndex() != null) {\n const i = panel.activeIndex()!;\n const it = items[i];\n this.select(it);\n }\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n break;\n default:\n break;\n }\n }\n\n @HostListener('blur')\n onBlur() {\n // delay to allow click handlers on overlay to run\n setTimeout(() => {\n if (this.destroyed) return;\n const text = this.host.nativeElement.value?.toString() ?? '';\n const match = this.findMatchingOption(text);\n\n if (this.restrictToList() && !match) {\n // must choose from list -> clear input and selection\n this.selectedChange.set(null);\n this.host.nativeElement.value = '';\n } else if (match) {\n // matched an option -> set selection\n this.selectedChange.set(match);\n } else {\n // no match and free text allowed -> keep input text but do NOT create a custom Option\n this.selectedChange.set(null);\n }\n\n this.blurEvent.set(text || null);\n this.close();\n }, 150);\n }\n\n // helper to create overlay and attach panel\n open() {\n if (this.disabled()) return;\n if (!this.overlayRef) this.createOverlay();\n if (!this.overlayRef!.hasAttached()) {\n const portal = new ComponentPortal(TypeaheadPanelComponent, this.vcr);\n const compRef = this.overlayRef!.attach(portal);\n this.panelRefInst = compRef.instance as TypeaheadPanelComponent;\n\n this.panelRefInst.displayWith.set(this.displayWith());\n this.panelRefInst.optionTemplate = this.asTypeaheadTemplate();\n this.panelRefInst.visibleCount.set(this.visibleCount());\n this.panelRefInst.onSelect = (item: Option) => this.select(item);\n\n const el = this.host.nativeElement;\n el.setAttribute('role', 'combobox');\n el.setAttribute('aria-autocomplete', 'list');\n el.setAttribute('aria-expanded', 'true');\n el.setAttribute('aria-controls', this.panelRefInst.id());\n\n this.openedChange.set(true);\n } else {\n this.overlayRef!.updatePosition();\n }\n }\n\n close() {\n this.detach();\n this.openedChange.set(false);\n }\n\n private detach(dispose = false) {\n if (!this.overlayRef) return;\n if (this.overlayRef.hasAttached()) {\n this.overlayRef.detach();\n const el = this.host.nativeElement;\n el.removeAttribute('aria-controls');\n el.setAttribute('aria-expanded', 'false');\n el.removeAttribute('aria-activedescendant');\n }\n if (dispose) {\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.panelRefInst = null;\n }\n }\n\n private createOverlay() {\n const strategy = this.overlay.position()\n .flexibleConnectedTo(this.host)\n .withPositions(this.positions())\n .withPush(true) as FlexibleConnectedPositionStrategy;\n\n strategy.withDefaultOffsetY(4);\n strategy.withDefaultOffsetX(0);\n\n this.overlayRef = this.overlay.create({\n positionStrategy: strategy,\n hasBackdrop: false,\n panelClass: undefined,\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\n });\n\n // reposition on strategy changes\n strategy.positionChanges.subscribe(() => {\n setTimeout(() => this.overlayRef?.updatePosition(), 0);\n });\n }\n\n private showAllOptions() {\n const list = this.options() ?? [];\n if (!this.overlayRef || !this.overlayRef.hasAttached()) {\n this.open();\n }\n if (this.panelRefInst) {\n this.panelRefInst.items.set(list);\n this.panelRefInst.activeIndex.set(null);\n }\n }\n\n private filterAndShow(q: string) {\n const list = this.options() ?? [];\n const key = q.toLowerCase();\n const filtered = list.filter(it => {\n if (!it) return false;\n const target = this.filterBy() === 'key' ? String(it.key) : String(it.value);\n return target.toLowerCase().includes(key);\n });\n if (!this.overlayRef || !this.overlayRef.hasAttached()) this.open();\n if (this.panelRefInst) {\n this.panelRefInst.items.set(filtered);\n if (filtered.length > 0) {\n this.panelRefInst.activeIndex.set(0);\n this.scrollToActive();\n } else {\n this.panelRefInst.activeIndex.set(null);\n }\n }\n }\n\n private select(item: Option) {\n this.selectedChange.set(item);\n try {\n this.host.nativeElement.value = this.displayWith()(item);\n } catch { /* ignore */ }\n this.close();\n this.host.nativeElement.focus();\n }\n\n private scrollToActive() {\n const panelEl = this.overlayRef?.overlayElement;\n if (!panelEl || !this.panelRefInst) return;\n const idx = this.panelRefInst.activeIndex();\n if (idx == null) return;\n const optionEl = panelEl.querySelector(`#${this.panelRefInst.optionId(idx)}`) as HTMLElement | null;\n if (optionEl) {\n const panelRect = panelEl.getBoundingClientRect();\n const optRect = optionEl.getBoundingClientRect();\n if (optRect.top < panelRect.top) {\n panelEl.scrollTop -= (panelRect.top - optRect.top);\n } else if (optRect.bottom > panelRect.bottom) {\n panelEl.scrollTop += (optRect.bottom - panelRect.bottom);\n }\n this.host.nativeElement.setAttribute('aria-activedescendant', optionEl.id);\n }\n }\n\n private findMatchingOption(text: string): Option | null {\n const list = this.options() ?? [];\n if (!text) return null;\n const t = text.toLowerCase();\n for (const it of list) {\n if (this.displayWith()(it).toLowerCase() === t) return it;\n if (String(it.key).toLowerCase() === t) return it;\n }\n return null;\n }\n\n private buildPositions(): ConnectedPosition[] {\n const bottomStart: ConnectedPosition = {\n originX: 'start', originY: 'bottom',\n overlayX: 'start', overlayY: 'top',\n offsetY: 4\n };\n const topStart: ConnectedPosition = {\n originX: 'start', originY: 'top',\n overlayX: 'start', overlayY: 'bottom',\n offsetY: -4\n };\n return [bottomStart, topStart];\n }\n\n log(value: any, ...rest: any[]): void {\n if (this.enableLog() || localStorage.getItem('loggerEnable')) {\n console.log('%c DEBUG ', 'background: gray; color: white; font-weight: bold;', `AS Components -> ${value}`, ...rest);\n }\n }\n}\n","/*\n * Public API Surface of as-components\n */\n\nexport * from './lib/as-components';\nexport * from './lib/modal-container/modal-container.component';\nexport * from './lib/services/modal-ref';\nexport * from './lib/services/modal.service';\nexport * from './lib/tooltip/tooltip.directive';\nexport * from './lib/tooltip/tooltip.component';\nexport * from './lib/typeahead/typeahead.directive';\nexport * from './lib/typeahead/typeahead-panel.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentsmith.bgd/as-components",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/cdk": "^21.1.0",
|
|
6
|
+
"@angular/common": "^21.1.0",
|
|
7
|
+
"@angular/core": "^21.1.0"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"tslib": "^2.3.0"
|
|
11
|
+
},
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"module": "fesm2022/agentsmith.bgd-as-components.mjs",
|
|
14
|
+
"typings": "types/agentsmith.bgd-as-components.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
"./package.json": {
|
|
17
|
+
"default": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./types/agentsmith.bgd-as-components.d.ts",
|
|
21
|
+
"default": "./fesm2022/agentsmith.bgd-as-components.mjs"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { ViewContainerRef, WritableSignal, EventEmitter, Type, ComponentRef, Injector, ApplicationRef, EnvironmentInjector, OnDestroy, TemplateRef } from '@angular/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
declare class AsComponents {
|
|
6
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AsComponents, never>;
|
|
7
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AsComponents, "lib-as-components", never, {}, {}, never, never, true, never>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare class ModalContainerComponent {
|
|
11
|
+
contentHost: ViewContainerRef;
|
|
12
|
+
title: WritableSignal<string | undefined>;
|
|
13
|
+
size: WritableSignal<'sm' | 'md' | 'lg'>;
|
|
14
|
+
showClose: WritableSignal<boolean>;
|
|
15
|
+
closed: EventEmitter<any>;
|
|
16
|
+
get sizeClass(): "sm" | "md" | "lg";
|
|
17
|
+
/**
|
|
18
|
+
* Create a component inside the container and set inputs.
|
|
19
|
+
* Supports:
|
|
20
|
+
* - assigning to writable signals (calls `.set(...)`)
|
|
21
|
+
* - assigning to plain properties
|
|
22
|
+
* Also handles primitive `inputs` mapping to common names.
|
|
23
|
+
*/
|
|
24
|
+
loadComponent<T>(component: Type<T>, inputs?: Partial<T> | any): ComponentRef<T>;
|
|
25
|
+
private setInput;
|
|
26
|
+
backdropClick(): void;
|
|
27
|
+
close(result?: any): void;
|
|
28
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ModalContainerComponent, never>;
|
|
29
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ModalContainerComponent, "as-modal-container", never, {}, { "closed": "closed"; }, never, never, true, never>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class ModalRef {
|
|
33
|
+
private componentRef;
|
|
34
|
+
private hostElement;
|
|
35
|
+
private _onClose;
|
|
36
|
+
onClose: Observable<any>;
|
|
37
|
+
constructor(componentRef: ComponentRef<any>, hostElement: HTMLElement);
|
|
38
|
+
close(result?: any): void;
|
|
39
|
+
private destroy;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ModalConfig {
|
|
43
|
+
id?: string;
|
|
44
|
+
size?: 'sm' | 'md' | 'lg';
|
|
45
|
+
title?: string;
|
|
46
|
+
showClose?: boolean;
|
|
47
|
+
data?: any;
|
|
48
|
+
}
|
|
49
|
+
declare class ModalService {
|
|
50
|
+
private injector;
|
|
51
|
+
private appRef;
|
|
52
|
+
private envInjector;
|
|
53
|
+
constructor(injector: Injector, appRef: ApplicationRef, envInjector: EnvironmentInjector);
|
|
54
|
+
show<T>(component: Type<T>, config?: ModalConfig): ModalRef;
|
|
55
|
+
private setInput;
|
|
56
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ModalService, never>;
|
|
57
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ModalService>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare class TooltipDirective implements OnDestroy {
|
|
61
|
+
private readonly overlay;
|
|
62
|
+
private readonly injector;
|
|
63
|
+
private readonly host;
|
|
64
|
+
readonly asTooltip: i0.InputSignal<string | null>;
|
|
65
|
+
readonly asTooltipPlacement: i0.InputSignal<"top" | "bottom" | "left" | "right" | "auto">;
|
|
66
|
+
private overlayRef;
|
|
67
|
+
private strategy;
|
|
68
|
+
private posSub;
|
|
69
|
+
private readonly positions;
|
|
70
|
+
show(): void;
|
|
71
|
+
hide(): void;
|
|
72
|
+
ngOnDestroy(): void;
|
|
73
|
+
private createOverlay;
|
|
74
|
+
private detachOverlay;
|
|
75
|
+
private buildPositions;
|
|
76
|
+
private mapPositionToPlacement;
|
|
77
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TooltipDirective, never>;
|
|
78
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<TooltipDirective, "[asTooltip]", never, { "asTooltip": { "alias": "asTooltip"; "required": false; "isSignal": true; }; "asTooltipPlacement": { "alias": "asTooltipPlacement"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare class TooltipComponent {
|
|
82
|
+
readonly id: WritableSignal<string>;
|
|
83
|
+
readonly text: WritableSignal<string | null>;
|
|
84
|
+
readonly placement: WritableSignal<'top' | 'bottom' | 'left' | 'right'>;
|
|
85
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TooltipComponent, never>;
|
|
86
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TooltipComponent, "as-tooltip", never, {}, {}, never, never, true, never>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface Option {
|
|
90
|
+
key: string;
|
|
91
|
+
value: string;
|
|
92
|
+
}
|
|
93
|
+
declare class TypeaheadPanelComponent {
|
|
94
|
+
readonly id: WritableSignal<string>;
|
|
95
|
+
readonly items: WritableSignal<Option[]>;
|
|
96
|
+
readonly displayWith: WritableSignal<(item: Option) => string>;
|
|
97
|
+
readonly activeIndex: WritableSignal<number | null>;
|
|
98
|
+
readonly visibleCount: WritableSignal<number>;
|
|
99
|
+
readonly itemHeight = 40;
|
|
100
|
+
optionTemplate: TemplateRef<any> | null;
|
|
101
|
+
onSelect: ((item: Option) => void) | null;
|
|
102
|
+
optionId(i: number): string;
|
|
103
|
+
setActive(i: number | null): void;
|
|
104
|
+
select(i: number): void;
|
|
105
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TypeaheadPanelComponent, never>;
|
|
106
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TypeaheadPanelComponent, "as-typeahead-panel", never, {}, {}, never, never, true, never>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
declare class TypeaheadDirective implements OnDestroy {
|
|
110
|
+
private readonly overlay;
|
|
111
|
+
private readonly host;
|
|
112
|
+
private readonly vcr;
|
|
113
|
+
readonly options: i0.InputSignal<Option[] | null>;
|
|
114
|
+
readonly displayWith: i0.InputSignal<(item: Option) => string>;
|
|
115
|
+
readonly filterBy: i0.InputSignal<"value" | "key">;
|
|
116
|
+
readonly visibleCount: i0.InputSignal<number>;
|
|
117
|
+
readonly restrictToList: i0.InputSignal<boolean>;
|
|
118
|
+
readonly selectedChange: WritableSignal<Option | null>;
|
|
119
|
+
readonly blurEvent: WritableSignal<string | null>;
|
|
120
|
+
readonly openedChange: WritableSignal<boolean>;
|
|
121
|
+
readonly asTypeaheadTemplate: i0.InputSignal<TemplateRef<any> | null>;
|
|
122
|
+
readonly disabled: i0.InputSignal<boolean>;
|
|
123
|
+
readonly enableLog: i0.InputSignal<boolean>;
|
|
124
|
+
private overlayRef;
|
|
125
|
+
private panelRefInst;
|
|
126
|
+
private destroyed;
|
|
127
|
+
typeaheadOnSelect: i0.OutputEmitterRef<Option | null>;
|
|
128
|
+
private readonly positions;
|
|
129
|
+
private _lastEmitted;
|
|
130
|
+
constructor();
|
|
131
|
+
ngOnDestroy(): void;
|
|
132
|
+
onFocusOrClick(): void;
|
|
133
|
+
onInput(e: Event): void;
|
|
134
|
+
onKeydown(e: KeyboardEvent): void;
|
|
135
|
+
onBlur(): void;
|
|
136
|
+
open(): void;
|
|
137
|
+
close(): void;
|
|
138
|
+
private detach;
|
|
139
|
+
private createOverlay;
|
|
140
|
+
private showAllOptions;
|
|
141
|
+
private filterAndShow;
|
|
142
|
+
private select;
|
|
143
|
+
private scrollToActive;
|
|
144
|
+
private findMatchingOption;
|
|
145
|
+
private buildPositions;
|
|
146
|
+
log(value: any, ...rest: any[]): void;
|
|
147
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TypeaheadDirective, never>;
|
|
148
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<TypeaheadDirective, "[asTypeahead]", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "filterBy": { "alias": "filterBy"; "required": false; "isSignal": true; }; "visibleCount": { "alias": "visibleCount"; "required": false; "isSignal": true; }; "restrictToList": { "alias": "restrictToList"; "required": false; "isSignal": true; }; "asTypeaheadTemplate": { "alias": "asTypeaheadTemplate"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "enableLog": { "alias": "enableLog"; "required": false; "isSignal": true; }; }, { "typeaheadOnSelect": "typeaheadOnSelect"; }, never, never, true, never>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { AsComponents, ModalContainerComponent, ModalRef, ModalService, TooltipComponent, TooltipDirective, TypeaheadDirective, TypeaheadPanelComponent };
|
|
152
|
+
export type { ModalConfig, Option };
|