@tolle_/tolle-ui 0.0.1-beta
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 +35 -0
- package/esm2022/lib/accordion-item.component.mjs +78 -0
- package/esm2022/lib/accordion.component.mjs +60 -0
- package/esm2022/lib/badge.component.mjs +76 -0
- package/esm2022/lib/button-group.component.mjs +25 -0
- package/esm2022/lib/button.component.mjs +70 -0
- package/esm2022/lib/calendar.component.mjs +315 -0
- package/esm2022/lib/card.component.mjs +94 -0
- package/esm2022/lib/checkbox.component.mjs +100 -0
- package/esm2022/lib/data-table.component.mjs +332 -0
- package/esm2022/lib/date-picker.component.mjs +232 -0
- package/esm2022/lib/date-range-picker.component.mjs +208 -0
- package/esm2022/lib/input.component.mjs +134 -0
- package/esm2022/lib/masked-input.component.mjs +179 -0
- package/esm2022/lib/modal-ref.mjs +31 -0
- package/esm2022/lib/modal-stack.service.mjs +26 -0
- package/esm2022/lib/modal.component.mjs +98 -0
- package/esm2022/lib/modal.mjs +27 -0
- package/esm2022/lib/modal.service.mjs +65 -0
- package/esm2022/lib/multi-select.component.mjs +231 -0
- package/esm2022/lib/pagination.component.mjs +279 -0
- package/esm2022/lib/range-calendar.component.mjs +285 -0
- package/esm2022/lib/select-group.component.mjs +28 -0
- package/esm2022/lib/select-item.component.mjs +84 -0
- package/esm2022/lib/select-separator.component.mjs +24 -0
- package/esm2022/lib/select.component.mjs +261 -0
- package/esm2022/lib/select.service.mjs +21 -0
- package/esm2022/lib/skeleton.component.mjs +34 -0
- package/esm2022/lib/switch.component.mjs +133 -0
- package/esm2022/lib/toast.service.mjs +59 -0
- package/esm2022/lib/tolle-cell.directive.mjs +22 -0
- package/esm2022/lib/tolle-config.mjs +11 -0
- package/esm2022/lib/tooltip.directive.mjs +71 -0
- package/esm2022/lib/types/date-range.mjs +2 -0
- package/esm2022/lib/utils/cn.mjs +6 -0
- package/esm2022/public-api.mjs +36 -0
- package/esm2022/tolle_-tolle-ui.mjs +5 -0
- package/fesm2022/tolle_-tolle-ui.mjs +3553 -0
- package/fesm2022/tolle_-tolle-ui.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/accordion-item.component.d.ts +13 -0
- package/lib/accordion.component.d.ts +14 -0
- package/lib/badge.component.d.ts +14 -0
- package/lib/button-group.component.d.ts +8 -0
- package/lib/button.component.d.ts +16 -0
- package/lib/calendar.component.d.ts +35 -0
- package/lib/card.component.d.ts +32 -0
- package/lib/checkbox.component.d.ts +23 -0
- package/lib/data-table.component.d.ts +45 -0
- package/lib/date-picker.component.d.ts +35 -0
- package/lib/date-range-picker.component.d.ts +36 -0
- package/lib/input.component.d.ts +27 -0
- package/lib/masked-input.component.d.ts +36 -0
- package/lib/modal-ref.d.ts +16 -0
- package/lib/modal-stack.service.d.ts +12 -0
- package/lib/modal.component.d.ts +19 -0
- package/lib/modal.d.ts +29 -0
- package/lib/modal.service.d.ts +18 -0
- package/lib/multi-select.component.d.ts +47 -0
- package/lib/pagination.component.d.ts +36 -0
- package/lib/range-calendar.component.d.ts +37 -0
- package/lib/select-group.component.d.ts +8 -0
- package/lib/select-item.component.d.ts +18 -0
- package/lib/select-separator.component.d.ts +8 -0
- package/lib/select.component.d.ts +45 -0
- package/lib/select.service.d.ts +10 -0
- package/lib/skeleton.component.d.ts +10 -0
- package/lib/switch.component.d.ts +39 -0
- package/lib/toast.service.d.ts +24 -0
- package/lib/tolle-cell.directive.d.ts +9 -0
- package/lib/tolle-config.d.ts +9 -0
- package/lib/tooltip.directive.d.ts +15 -0
- package/lib/types/date-range.d.ts +4 -0
- package/lib/utils/cn.d.ts +2 -0
- package/package.json +32 -0
- package/public-api.d.ts +32 -0
- package/theme.css +211 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Component, TemplateRef } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { cn } from './utils/cn';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "./modal-ref";
|
|
6
|
+
import * as i2 from "@angular/common";
|
|
7
|
+
export class ModalComponent {
|
|
8
|
+
ref;
|
|
9
|
+
contentType = 'string';
|
|
10
|
+
content;
|
|
11
|
+
modalClasses = '';
|
|
12
|
+
constructor(ref) {
|
|
13
|
+
this.ref = ref;
|
|
14
|
+
}
|
|
15
|
+
ngOnInit() {
|
|
16
|
+
this.content = this.ref.modal.content;
|
|
17
|
+
this.modalClasses = this.getModalSizeCss();
|
|
18
|
+
this.determineContentType();
|
|
19
|
+
}
|
|
20
|
+
getModalSizeCss() {
|
|
21
|
+
const { size } = this.ref.modal;
|
|
22
|
+
return cn(
|
|
23
|
+
// Base classes: Added 'w-full' and 'mx-auto'
|
|
24
|
+
'bg-background border border-border shadow-lg relative flex flex-col w-full mx-auto overflow-hidden', size === 'fullscreen' ? 'h-screen w-screen rounded-none' : 'rounded-lg',
|
|
25
|
+
// Sizing scale with explicit max-widths
|
|
26
|
+
size === 'xs' && 'max-w-[320px]', size === 'sm' && 'max-w-[425px]', size === 'default' && 'max-w-[544px]', size === 'lg' && 'max-w-[1024px]');
|
|
27
|
+
}
|
|
28
|
+
determineContentType() {
|
|
29
|
+
if (typeof this.content === 'string')
|
|
30
|
+
this.contentType = 'string';
|
|
31
|
+
else if (this.content instanceof TemplateRef)
|
|
32
|
+
this.contentType = 'template';
|
|
33
|
+
else
|
|
34
|
+
this.contentType = 'component';
|
|
35
|
+
}
|
|
36
|
+
get asTemplate() { return this.content; }
|
|
37
|
+
get asComponent() { return this.content; }
|
|
38
|
+
cn = cn;
|
|
39
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalComponent, deps: [{ token: i1.ModalRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
40
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ModalComponent, isStandalone: true, selector: "tolle-modal", ngImport: i0, template: `
|
|
41
|
+
<div [class]="modalClasses" class="pointer-events-auto" (mousedown)="$event.stopPropagation()">
|
|
42
|
+
|
|
43
|
+
<div class="flex items-center justify-between p-6 border-b border-border">
|
|
44
|
+
<h3 *ngIf="ref.modal.title" class="text-lg font-semibold text-foreground tracking-tight">
|
|
45
|
+
{{ ref.modal.title }}
|
|
46
|
+
</h3>
|
|
47
|
+
<button (click)="ref.close()" class="ml-auto p-1 text-muted-foreground hover:text-foreground hover:bg-accent rounded-md transition-colors">
|
|
48
|
+
<i class="ri-close-line text-2xl"></i>
|
|
49
|
+
</button>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="p-6 overflow-y-auto max-h-[80vh] text-foreground">
|
|
53
|
+
<ng-container [ngSwitch]="contentType">
|
|
54
|
+
<div *ngSwitchCase="'string'">{{ content }}</div>
|
|
55
|
+
|
|
56
|
+
<ng-container *ngSwitchCase="'template'">
|
|
57
|
+
<ng-container *ngTemplateOutlet="asTemplate; context: ref.modal.context"></ng-container>
|
|
58
|
+
</ng-container>
|
|
59
|
+
|
|
60
|
+
<ng-container *ngSwitchCase="'component'">
|
|
61
|
+
<ng-container *ngComponentOutlet="asComponent"></ng-container>
|
|
62
|
+
</ng-container>
|
|
63
|
+
</ng-container>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
`, isInline: true, styles: [":host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }] });
|
|
67
|
+
}
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalComponent, decorators: [{
|
|
69
|
+
type: Component,
|
|
70
|
+
args: [{ selector: 'tolle-modal', standalone: true, imports: [CommonModule], template: `
|
|
71
|
+
<div [class]="modalClasses" class="pointer-events-auto" (mousedown)="$event.stopPropagation()">
|
|
72
|
+
|
|
73
|
+
<div class="flex items-center justify-between p-6 border-b border-border">
|
|
74
|
+
<h3 *ngIf="ref.modal.title" class="text-lg font-semibold text-foreground tracking-tight">
|
|
75
|
+
{{ ref.modal.title }}
|
|
76
|
+
</h3>
|
|
77
|
+
<button (click)="ref.close()" class="ml-auto p-1 text-muted-foreground hover:text-foreground hover:bg-accent rounded-md transition-colors">
|
|
78
|
+
<i class="ri-close-line text-2xl"></i>
|
|
79
|
+
</button>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="p-6 overflow-y-auto max-h-[80vh] text-foreground">
|
|
83
|
+
<ng-container [ngSwitch]="contentType">
|
|
84
|
+
<div *ngSwitchCase="'string'">{{ content }}</div>
|
|
85
|
+
|
|
86
|
+
<ng-container *ngSwitchCase="'template'">
|
|
87
|
+
<ng-container *ngTemplateOutlet="asTemplate; context: ref.modal.context"></ng-container>
|
|
88
|
+
</ng-container>
|
|
89
|
+
|
|
90
|
+
<ng-container *ngSwitchCase="'component'">
|
|
91
|
+
<ng-container *ngComponentOutlet="asComponent"></ng-container>
|
|
92
|
+
</ng-container>
|
|
93
|
+
</ng-container>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
`, styles: [":host{display:contents}\n"] }]
|
|
97
|
+
}], ctorParameters: () => [{ type: i1.ModalRef }] });
|
|
98
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9tb2RhbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxXQUFXLEVBQVEsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRS9DLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxZQUFZLENBQUM7Ozs7QUF1Q2hDLE1BQU0sT0FBTyxjQUFjO0lBS047SUFKbkIsV0FBVyxHQUF3QyxRQUFRLENBQUM7SUFDNUQsT0FBTyxDQUFNO0lBQ2IsWUFBWSxHQUFHLEVBQUUsQ0FBQztJQUVsQixZQUFtQixHQUFhO1FBQWIsUUFBRyxHQUFILEdBQUcsQ0FBVTtJQUFHLENBQUM7SUFFcEMsUUFBUTtRQUNOLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFTyxlQUFlO1FBQ3JCLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUVoQyxPQUFPLEVBQUU7UUFDUCw2Q0FBNkM7UUFDN0Msb0dBQW9HLEVBRXBHLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLGdDQUFnQyxDQUFDLENBQUMsQ0FBQyxZQUFZO1FBRXZFLHdDQUF3QztRQUN4QyxJQUFJLEtBQUssSUFBSSxJQUFJLGVBQWUsRUFDaEMsSUFBSSxLQUFLLElBQUksSUFBSSxlQUFlLEVBQ2hDLElBQUksS0FBSyxTQUFTLElBQUksZUFBZSxFQUNyQyxJQUFJLEtBQUssSUFBSSxJQUFJLGdCQUFnQixDQUNsQyxDQUFDO0lBQ0osQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sS0FBSyxRQUFRO1lBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUM7YUFDN0QsSUFBSSxJQUFJLENBQUMsT0FBTyxZQUFZLFdBQVc7WUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQzs7WUFDdkUsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQUksVUFBVSxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQTJCLENBQUMsQ0FBQyxDQUFDO0lBQzdELElBQUksV0FBVyxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQW9CLENBQUMsQ0FBQyxDQUFDO0lBQzdDLEVBQUUsR0FBRyxFQUFFLENBQUM7d0dBdENQLGNBQWM7NEZBQWQsY0FBYyx1RUFqQ2Y7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJULGtHQTNCUyxZQUFZOzs0RkFrQ1gsY0FBYztrQkFyQzFCLFNBQVM7K0JBQ0UsYUFBYSxjQUNYLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxZQUNiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBUZW1wbGF0ZVJlZiwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1vZGFsUmVmIH0gZnJvbSAnLi9tb2RhbC1yZWYnO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJtb2RhbENsYXNzZXNcIiBjbGFzcz1cInBvaW50ZXItZXZlbnRzLWF1dG9cIiAobW91c2Vkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIHAtNiBib3JkZXItYiBib3JkZXItYm9yZGVyXCI+XG4gICAgICAgIDxoMyAqbmdJZj1cInJlZi5tb2RhbC50aXRsZVwiIGNsYXNzPVwidGV4dC1sZyBmb250LXNlbWlib2xkIHRleHQtZm9yZWdyb3VuZCB0cmFja2luZy10aWdodFwiPlxuICAgICAgICAgIHt7IHJlZi5tb2RhbC50aXRsZSB9fVxuICAgICAgICA8L2gzPlxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJyZWYuY2xvc2UoKVwiIGNsYXNzPVwibWwtYXV0byBwLTEgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kIGhvdmVyOnRleHQtZm9yZWdyb3VuZCBob3ZlcjpiZy1hY2NlbnQgcm91bmRlZC1tZCB0cmFuc2l0aW9uLWNvbG9yc1wiPlxuICAgICAgICAgIDxpIGNsYXNzPVwicmktY2xvc2UtbGluZSB0ZXh0LTJ4bFwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInAtNiBvdmVyZmxvdy15LWF1dG8gbWF4LWgtWzgwdmhdIHRleHQtZm9yZWdyb3VuZFwiPlxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJjb250ZW50VHlwZVwiPlxuICAgICAgICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIidzdHJpbmcnXCI+e3sgY29udGVudCB9fTwvZGl2PlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3RlbXBsYXRlJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImFzVGVtcGxhdGU7IGNvbnRleHQ6IHJlZi5tb2RhbC5jb250ZXh0XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInY29tcG9uZW50J1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdDb21wb25lbnRPdXRsZXQ9XCJhc0NvbXBvbmVudFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgOmhvc3Qge1xuICAgICAgZGlzcGxheTogY29udGVudHM7IC8qIFRoaXMgbWFrZXMgdGhlIGhvc3QgXCJkaXNhcHBlYXJcIiBzbyB0aGUgZGl2IHRhcmdldHMgdGhlIG92ZXJsYXkgcGFuZSBkaXJlY3RseSAqL1xuICAgIH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgTW9kYWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBjb250ZW50VHlwZTogJ3RlbXBsYXRlJyB8ICdzdHJpbmcnIHwgJ2NvbXBvbmVudCcgPSAnc3RyaW5nJztcbiAgY29udGVudDogYW55O1xuICBtb2RhbENsYXNzZXMgPSAnJztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVmOiBNb2RhbFJlZikge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbnRlbnQgPSB0aGlzLnJlZi5tb2RhbC5jb250ZW50O1xuICAgIHRoaXMubW9kYWxDbGFzc2VzID0gdGhpcy5nZXRNb2RhbFNpemVDc3MoKTtcbiAgICB0aGlzLmRldGVybWluZUNvbnRlbnRUeXBlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldE1vZGFsU2l6ZUNzcygpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgc2l6ZSB9ID0gdGhpcy5yZWYubW9kYWw7XG5cbiAgICByZXR1cm4gY24oXG4gICAgICAvLyBCYXNlIGNsYXNzZXM6IEFkZGVkICd3LWZ1bGwnIGFuZCAnbXgtYXV0bydcbiAgICAgICdiZy1iYWNrZ3JvdW5kIGJvcmRlciBib3JkZXItYm9yZGVyIHNoYWRvdy1sZyByZWxhdGl2ZSBmbGV4IGZsZXgtY29sIHctZnVsbCBteC1hdXRvIG92ZXJmbG93LWhpZGRlbicsXG5cbiAgICAgIHNpemUgPT09ICdmdWxsc2NyZWVuJyA/ICdoLXNjcmVlbiB3LXNjcmVlbiByb3VuZGVkLW5vbmUnIDogJ3JvdW5kZWQtbGcnLFxuXG4gICAgICAvLyBTaXppbmcgc2NhbGUgd2l0aCBleHBsaWNpdCBtYXgtd2lkdGhzXG4gICAgICBzaXplID09PSAneHMnICYmICdtYXgtdy1bMzIwcHhdJyxcbiAgICAgIHNpemUgPT09ICdzbScgJiYgJ21heC13LVs0MjVweF0nLFxuICAgICAgc2l6ZSA9PT0gJ2RlZmF1bHQnICYmICdtYXgtdy1bNTQ0cHhdJyxcbiAgICAgIHNpemUgPT09ICdsZycgJiYgJ21heC13LVsxMDI0cHhdJ1xuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGRldGVybWluZUNvbnRlbnRUeXBlKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5jb250ZW50ID09PSAnc3RyaW5nJykgdGhpcy5jb250ZW50VHlwZSA9ICdzdHJpbmcnO1xuICAgIGVsc2UgaWYgKHRoaXMuY29udGVudCBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmKSB0aGlzLmNvbnRlbnRUeXBlID0gJ3RlbXBsYXRlJztcbiAgICBlbHNlIHRoaXMuY29udGVudFR5cGUgPSAnY29tcG9uZW50JztcbiAgfVxuXG4gIGdldCBhc1RlbXBsYXRlKCkgeyByZXR1cm4gdGhpcy5jb250ZW50IGFzIFRlbXBsYXRlUmVmPGFueT47IH1cbiAgZ2V0IGFzQ29tcG9uZW50KCkgeyByZXR1cm4gdGhpcy5jb250ZW50IGFzIFR5cGU8YW55PjsgfVxuICBwcm90ZWN0ZWQgY24gPSBjbjtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class Modal {
|
|
2
|
+
/** The content to display (String, Component, or Template) */
|
|
3
|
+
content;
|
|
4
|
+
/** Optional title for the standard header */
|
|
5
|
+
title;
|
|
6
|
+
/** * Predefined size scale.
|
|
7
|
+
* - xs: 320px (Mobile alerts)
|
|
8
|
+
* - sm: 425px (Standard dialogs)
|
|
9
|
+
* - default: 544px (Forms)
|
|
10
|
+
* - lg: 90% / 1024px (Data tables)
|
|
11
|
+
* - fullscreen: 100vw/100vh (Complex workflows)
|
|
12
|
+
*/
|
|
13
|
+
size = 'default';
|
|
14
|
+
/** * If true (default), clicking the backdrop closes the modal.
|
|
15
|
+
* Set to false for "blocking" modals (e.g., Terms of Service).
|
|
16
|
+
*/
|
|
17
|
+
backdropClose = true;
|
|
18
|
+
/** * Data to pass to a Component content.
|
|
19
|
+
* Accessed via @Input() in the child component.
|
|
20
|
+
*/
|
|
21
|
+
data;
|
|
22
|
+
/** * Context to pass to a TemplateRef content.
|
|
23
|
+
* Accessed via `let-val` in the HTML.
|
|
24
|
+
*/
|
|
25
|
+
context;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy90b2xsZS9zcmMvbGliL21vZGFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE1BQU0sT0FBTyxLQUFLO0lBQ2hCLDhEQUE4RDtJQUM5RCxPQUFPLENBQXlDO0lBRWhELDZDQUE2QztJQUM3QyxLQUFLLENBQVU7SUFFZjs7Ozs7O09BTUc7SUFDSCxJQUFJLEdBQW1ELFNBQVMsQ0FBQztJQUVqRTs7T0FFRztJQUNILGFBQWEsR0FBYSxJQUFJLENBQUM7SUFFL0I7O09BRUc7SUFDSCxJQUFJLENBQTBCO0lBRTlCOztPQUVHO0lBQ0gsT0FBTyxDQUFLO0NBQ2IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZW1wbGF0ZVJlZiwgVHlwZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmV4cG9ydCBjbGFzcyBNb2RhbDxUID0gYW55PiB7XG4gIC8qKiBUaGUgY29udGVudCB0byBkaXNwbGF5IChTdHJpbmcsIENvbXBvbmVudCwgb3IgVGVtcGxhdGUpICovXG4gIGNvbnRlbnQhOiBzdHJpbmcgfCBUeXBlPGFueT4gfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIC8qKiBPcHRpb25hbCB0aXRsZSBmb3IgdGhlIHN0YW5kYXJkIGhlYWRlciAqL1xuICB0aXRsZT86IHN0cmluZztcblxuICAvKiogKiBQcmVkZWZpbmVkIHNpemUgc2NhbGUuXG4gICAqIC0geHM6IDMyMHB4IChNb2JpbGUgYWxlcnRzKVxuICAgKiAtIHNtOiA0MjVweCAoU3RhbmRhcmQgZGlhbG9ncylcbiAgICogLSBkZWZhdWx0OiA1NDRweCAoRm9ybXMpXG4gICAqIC0gbGc6IDkwJSAvIDEwMjRweCAoRGF0YSB0YWJsZXMpXG4gICAqIC0gZnVsbHNjcmVlbjogMTAwdncvMTAwdmggKENvbXBsZXggd29ya2Zsb3dzKVxuICAgKi9cbiAgc2l6ZT86ICd4cycgfCAnc20nIHwgJ2RlZmF1bHQnIHwgJ2xnJyB8ICdmdWxsc2NyZWVuJyA9ICdkZWZhdWx0JztcblxuICAvKiogKiBJZiB0cnVlIChkZWZhdWx0KSwgY2xpY2tpbmcgdGhlIGJhY2tkcm9wIGNsb3NlcyB0aGUgbW9kYWwuXG4gICAqIFNldCB0byBmYWxzZSBmb3IgXCJibG9ja2luZ1wiIG1vZGFscyAoZS5nLiwgVGVybXMgb2YgU2VydmljZSkuXG4gICAqL1xuICBiYWNrZHJvcENsb3NlPzogYm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqICogRGF0YSB0byBwYXNzIHRvIGEgQ29tcG9uZW50IGNvbnRlbnQuXG4gICAqIEFjY2Vzc2VkIHZpYSBASW5wdXQoKSBpbiB0aGUgY2hpbGQgY29tcG9uZW50LlxuICAgKi9cbiAgZGF0YT86IHsgW2tleTogc3RyaW5nXTogYW55IH07XG5cbiAgLyoqICogQ29udGV4dCB0byBwYXNzIHRvIGEgVGVtcGxhdGVSZWYgY29udGVudC5cbiAgICogQWNjZXNzZWQgdmlhIGBsZXQtdmFsYCBpbiB0aGUgSFRNTC5cbiAgICovXG4gIGNvbnRleHQ/OiBUO1xufVxuIl19
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Injectable, Injector } from '@angular/core';
|
|
2
|
+
import { OverlayConfig } from '@angular/cdk/overlay';
|
|
3
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
4
|
+
import { ModalRef } from './modal-ref';
|
|
5
|
+
import { ModalComponent } from './modal.component';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/cdk/overlay";
|
|
8
|
+
import * as i2 from "./modal-stack.service";
|
|
9
|
+
export class ModalService {
|
|
10
|
+
overlay;
|
|
11
|
+
injector;
|
|
12
|
+
stack;
|
|
13
|
+
constructor(overlay, injector, stack) {
|
|
14
|
+
this.overlay = overlay;
|
|
15
|
+
this.injector = injector;
|
|
16
|
+
this.stack = stack;
|
|
17
|
+
}
|
|
18
|
+
open(config) {
|
|
19
|
+
// 1. Create the Overlay (DOM placeholder)
|
|
20
|
+
const overlayRef = this.createOverlay();
|
|
21
|
+
// 2. Create the Controller (Ref)
|
|
22
|
+
const modalRef = new ModalRef(overlayRef, config, this.stack);
|
|
23
|
+
// 3. Create Injector to allow the Component to access the Ref
|
|
24
|
+
const injector = Injector.create({
|
|
25
|
+
parent: this.injector,
|
|
26
|
+
providers: [{ provide: ModalRef, useValue: modalRef }]
|
|
27
|
+
});
|
|
28
|
+
// 4. Attach the UI Component to the Overlay
|
|
29
|
+
const portal = new ComponentPortal(ModalComponent, null, injector);
|
|
30
|
+
overlayRef.attach(portal);
|
|
31
|
+
return modalRef;
|
|
32
|
+
}
|
|
33
|
+
/** Global helper to close everything */
|
|
34
|
+
closeAll() {
|
|
35
|
+
this.stack.closeAll();
|
|
36
|
+
}
|
|
37
|
+
// modal.service.ts
|
|
38
|
+
createOverlay() {
|
|
39
|
+
const config = new OverlayConfig({
|
|
40
|
+
hasBackdrop: true,
|
|
41
|
+
backdropClass: ['cdk-overlay-backdrop', 'bg-black/80', 'backdrop-blur-sm'],
|
|
42
|
+
panelClass: [
|
|
43
|
+
'w-full',
|
|
44
|
+
'h-full',
|
|
45
|
+
'flex',
|
|
46
|
+
'items-center',
|
|
47
|
+
'justify-center',
|
|
48
|
+
'pointer-events-none'
|
|
49
|
+
],
|
|
50
|
+
scrollStrategy: this.overlay.scrollStrategies.block(),
|
|
51
|
+
positionStrategy: this.overlay.position()
|
|
52
|
+
.global()
|
|
53
|
+
.centerHorizontally()
|
|
54
|
+
.centerVertically()
|
|
55
|
+
});
|
|
56
|
+
return this.overlay.create(config);
|
|
57
|
+
}
|
|
58
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalService, deps: [{ token: i1.Overlay }, { token: i0.Injector }, { token: i2.ModalStackService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
59
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalService, providedIn: 'root' });
|
|
60
|
+
}
|
|
61
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ModalService, decorators: [{
|
|
62
|
+
type: Injectable,
|
|
63
|
+
args: [{ providedIn: 'root' }]
|
|
64
|
+
}], ctorParameters: () => [{ type: i1.Overlay }, { type: i0.Injector }, { type: i2.ModalStackService }] });
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvbW9kYWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRCxPQUFPLEVBQVcsYUFBYSxFQUFjLE1BQU0sc0JBQXNCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7O0FBSW5ELE1BQU0sT0FBTyxZQUFZO0lBRWI7SUFDQTtJQUNBO0lBSFYsWUFDVSxPQUFnQixFQUNoQixRQUFrQixFQUNsQixLQUF3QjtRQUZ4QixZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ2hCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsVUFBSyxHQUFMLEtBQUssQ0FBbUI7SUFDL0IsQ0FBQztJQUVKLElBQUksQ0FBVSxNQUFhO1FBQ3pCLDBDQUEwQztRQUMxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFeEMsaUNBQWlDO1FBQ2pDLE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxDQUFJLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWpFLDhEQUE4RDtRQUM5RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQy9CLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUTtZQUNyQixTQUFTLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQ3ZELENBQUMsQ0FBQztRQUVILDRDQUE0QztRQUM1QyxNQUFNLE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ25FLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFMUIsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELHdDQUF3QztJQUN4QyxRQUFRO1FBQ04sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsbUJBQW1CO0lBQ1gsYUFBYTtRQUNuQixNQUFNLE1BQU0sR0FBRyxJQUFJLGFBQWEsQ0FBQztZQUMvQixXQUFXLEVBQUUsSUFBSTtZQUNqQixhQUFhLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLENBQUM7WUFDMUUsVUFBVSxFQUFFO2dCQUNWLFFBQVE7Z0JBQ1IsUUFBUTtnQkFDUixNQUFNO2dCQUNOLGNBQWM7Z0JBQ2QsZ0JBQWdCO2dCQUNoQixxQkFBcUI7YUFDdEI7WUFDRCxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUU7WUFDckQsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7aUJBQ3RDLE1BQU0sRUFBRTtpQkFDUixrQkFBa0IsRUFBRTtpQkFDcEIsZ0JBQWdCLEVBQUU7U0FDdEIsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyQyxDQUFDO3dHQXJEVSxZQUFZOzRHQUFaLFlBQVksY0FEQyxNQUFNOzs0RkFDbkIsWUFBWTtrQkFEeEIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3ZlcmxheSwgT3ZlcmxheUNvbmZpZywgT3ZlcmxheVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgTW9kYWwgfSBmcm9tICcuL21vZGFsJztcbmltcG9ydCB7IE1vZGFsUmVmIH0gZnJvbSAnLi9tb2RhbC1yZWYnO1xuaW1wb3J0IHsgTW9kYWxDb21wb25lbnQgfSBmcm9tICcuL21vZGFsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNb2RhbFN0YWNrU2VydmljZSB9IGZyb20gJy4vbW9kYWwtc3RhY2suc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgTW9kYWxTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBvdmVybGF5OiBPdmVybGF5LFxuICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByaXZhdGUgc3RhY2s6IE1vZGFsU3RhY2tTZXJ2aWNlXG4gICkge31cblxuICBvcGVuPFIgPSBhbnk+KGNvbmZpZzogTW9kYWwpOiBNb2RhbFJlZjxSPiB7XG4gICAgLy8gMS4gQ3JlYXRlIHRoZSBPdmVybGF5IChET00gcGxhY2Vob2xkZXIpXG4gICAgY29uc3Qgb3ZlcmxheVJlZiA9IHRoaXMuY3JlYXRlT3ZlcmxheSgpO1xuXG4gICAgLy8gMi4gQ3JlYXRlIHRoZSBDb250cm9sbGVyIChSZWYpXG4gICAgY29uc3QgbW9kYWxSZWYgPSBuZXcgTW9kYWxSZWY8Uj4ob3ZlcmxheVJlZiwgY29uZmlnLCB0aGlzLnN0YWNrKTtcblxuICAgIC8vIDMuIENyZWF0ZSBJbmplY3RvciB0byBhbGxvdyB0aGUgQ29tcG9uZW50IHRvIGFjY2VzcyB0aGUgUmVmXG4gICAgY29uc3QgaW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUoe1xuICAgICAgcGFyZW50OiB0aGlzLmluamVjdG9yLFxuICAgICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBNb2RhbFJlZiwgdXNlVmFsdWU6IG1vZGFsUmVmIH1dXG4gICAgfSk7XG5cbiAgICAvLyA0LiBBdHRhY2ggdGhlIFVJIENvbXBvbmVudCB0byB0aGUgT3ZlcmxheVxuICAgIGNvbnN0IHBvcnRhbCA9IG5ldyBDb21wb25lbnRQb3J0YWwoTW9kYWxDb21wb25lbnQsIG51bGwsIGluamVjdG9yKTtcbiAgICBvdmVybGF5UmVmLmF0dGFjaChwb3J0YWwpO1xuXG4gICAgcmV0dXJuIG1vZGFsUmVmO1xuICB9XG5cbiAgLyoqIEdsb2JhbCBoZWxwZXIgdG8gY2xvc2UgZXZlcnl0aGluZyAqL1xuICBjbG9zZUFsbCgpIHtcbiAgICB0aGlzLnN0YWNrLmNsb3NlQWxsKCk7XG4gIH1cblxuICAvLyBtb2RhbC5zZXJ2aWNlLnRzXG4gIHByaXZhdGUgY3JlYXRlT3ZlcmxheSgpOiBPdmVybGF5UmVmIHtcbiAgICBjb25zdCBjb25maWcgPSBuZXcgT3ZlcmxheUNvbmZpZyh7XG4gICAgICBoYXNCYWNrZHJvcDogdHJ1ZSxcbiAgICAgIGJhY2tkcm9wQ2xhc3M6IFsnY2RrLW92ZXJsYXktYmFja2Ryb3AnLCAnYmctYmxhY2svODAnLCAnYmFja2Ryb3AtYmx1ci1zbSddLFxuICAgICAgcGFuZWxDbGFzczogW1xuICAgICAgICAndy1mdWxsJyxcbiAgICAgICAgJ2gtZnVsbCcsXG4gICAgICAgICdmbGV4JyxcbiAgICAgICAgJ2l0ZW1zLWNlbnRlcicsXG4gICAgICAgICdqdXN0aWZ5LWNlbnRlcicsXG4gICAgICAgICdwb2ludGVyLWV2ZW50cy1ub25lJ1xuICAgICAgXSxcbiAgICAgIHNjcm9sbFN0cmF0ZWd5OiB0aGlzLm92ZXJsYXkuc2Nyb2xsU3RyYXRlZ2llcy5ibG9jaygpLFxuICAgICAgcG9zaXRpb25TdHJhdGVneTogdGhpcy5vdmVybGF5LnBvc2l0aW9uKClcbiAgICAgICAgLmdsb2JhbCgpXG4gICAgICAgIC5jZW50ZXJIb3Jpem9udGFsbHkoKVxuICAgICAgICAuY2VudGVyVmVydGljYWxseSgpXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5vdmVybGF5LmNyZWF0ZShjb25maWcpO1xuICB9XG5cblxufVxuIl19
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { Component, Input, ContentChildren, ViewChild, HostListener } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
4
|
+
import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/dom';
|
|
5
|
+
import { SelectItemComponent } from './select-item.component';
|
|
6
|
+
import { SelectService } from './select.service';
|
|
7
|
+
import { cn } from './utils/cn';
|
|
8
|
+
import { BadgeComponent } from '@tolle/ui/badge.component';
|
|
9
|
+
import { InputComponent } from '@tolle/ui/input.component';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "./select.service";
|
|
12
|
+
import * as i2 from "@angular/common";
|
|
13
|
+
import * as i3 from "@angular/forms";
|
|
14
|
+
export class MultiSelectComponent {
|
|
15
|
+
selectService;
|
|
16
|
+
placeholder = 'Select options...';
|
|
17
|
+
size = 'default';
|
|
18
|
+
searchable = false;
|
|
19
|
+
disabled = false;
|
|
20
|
+
class = '';
|
|
21
|
+
trigger;
|
|
22
|
+
popover;
|
|
23
|
+
items;
|
|
24
|
+
value = [];
|
|
25
|
+
selectedItems = [];
|
|
26
|
+
isOpen = false;
|
|
27
|
+
searchQuery = '';
|
|
28
|
+
noResults = false;
|
|
29
|
+
cleanup;
|
|
30
|
+
constructor(selectService) {
|
|
31
|
+
this.selectService = selectService;
|
|
32
|
+
this.selectService.selectedValue$.subscribe(val => {
|
|
33
|
+
if (val !== undefined && this.isOpen)
|
|
34
|
+
this.toggleValue(val);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
ngAfterContentInit() {
|
|
38
|
+
this.syncItems();
|
|
39
|
+
this.items.changes.subscribe(() => this.syncItems());
|
|
40
|
+
}
|
|
41
|
+
toggle() {
|
|
42
|
+
if (this.disabled)
|
|
43
|
+
return;
|
|
44
|
+
this.isOpen ? this.close() : this.open();
|
|
45
|
+
}
|
|
46
|
+
open() {
|
|
47
|
+
this.isOpen = true;
|
|
48
|
+
setTimeout(() => this.updatePosition());
|
|
49
|
+
}
|
|
50
|
+
close() {
|
|
51
|
+
this.isOpen = false;
|
|
52
|
+
if (this.cleanup)
|
|
53
|
+
this.cleanup();
|
|
54
|
+
}
|
|
55
|
+
updatePosition() {
|
|
56
|
+
this.cleanup = autoUpdate(this.trigger.nativeElement, this.popover.nativeElement, () => {
|
|
57
|
+
computePosition(this.trigger.nativeElement, this.popover.nativeElement, {
|
|
58
|
+
placement: 'bottom-start',
|
|
59
|
+
middleware: [offset(4), flip(), shift({ padding: 8 })],
|
|
60
|
+
}).then(({ x, y }) => {
|
|
61
|
+
Object.assign(this.popover.nativeElement.style, {
|
|
62
|
+
left: `${x}px`,
|
|
63
|
+
top: `${y}px`,
|
|
64
|
+
visibility: 'visible',
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
toggleValue(val) {
|
|
70
|
+
const index = this.value.indexOf(val);
|
|
71
|
+
index > -1 ? this.value.splice(index, 1) : this.value.push(val);
|
|
72
|
+
this.syncItems();
|
|
73
|
+
this.onChange([...this.value]); // Return new array reference for Change Detection
|
|
74
|
+
}
|
|
75
|
+
selectAll() {
|
|
76
|
+
this.value = this.items.map(i => i.value);
|
|
77
|
+
this.syncItems();
|
|
78
|
+
this.onChange([...this.value]);
|
|
79
|
+
}
|
|
80
|
+
clearAll() {
|
|
81
|
+
this.value = [];
|
|
82
|
+
this.syncItems();
|
|
83
|
+
this.onChange([]);
|
|
84
|
+
}
|
|
85
|
+
removeValue(event, val) {
|
|
86
|
+
event.stopPropagation();
|
|
87
|
+
this.toggleValue(val);
|
|
88
|
+
}
|
|
89
|
+
syncItems() {
|
|
90
|
+
if (!this.items)
|
|
91
|
+
return;
|
|
92
|
+
this.selectedItems = [];
|
|
93
|
+
this.items.forEach(item => {
|
|
94
|
+
item.selected = this.value.includes(item.value);
|
|
95
|
+
if (item.selected)
|
|
96
|
+
this.selectedItems.push({ label: item.getLabel(), value: item.value });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
onSearchChange(q) {
|
|
100
|
+
const filter = (q || '').toLowerCase();
|
|
101
|
+
let visibleCount = 0;
|
|
102
|
+
this.items.forEach(item => {
|
|
103
|
+
const isVisible = item.getLabel().toLowerCase().includes(filter);
|
|
104
|
+
item.hidden = !isVisible;
|
|
105
|
+
if (isVisible)
|
|
106
|
+
visibleCount++;
|
|
107
|
+
});
|
|
108
|
+
this.noResults = visibleCount === 0 && filter !== '';
|
|
109
|
+
}
|
|
110
|
+
onClickOutside(event) {
|
|
111
|
+
if (this.isOpen && !this.trigger.nativeElement.contains(event.target) && !this.popover?.nativeElement.contains(event.target)) {
|
|
112
|
+
this.close();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ControlValueAccessor
|
|
116
|
+
onChange = () => { };
|
|
117
|
+
onTouched = () => { };
|
|
118
|
+
writeValue(v) { this.value = Array.isArray(v) ? v : []; this.syncItems(); }
|
|
119
|
+
registerOnChange(fn) { this.onChange = fn; }
|
|
120
|
+
registerOnTouched(fn) { this.onTouched = fn; }
|
|
121
|
+
cn = cn;
|
|
122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectComponent, deps: [{ token: i1.SelectService }], target: i0.ɵɵFactoryTarget.Component });
|
|
123
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MultiSelectComponent, isStandalone: true, selector: "tolle-multi-select", inputs: { placeholder: "placeholder", size: "size", searchable: "searchable", disabled: "disabled", class: "class" }, host: { listeners: { "document:mousedown": "onClickOutside($event)" } }, providers: [
|
|
124
|
+
SelectService,
|
|
125
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: MultiSelectComponent, multi: true }
|
|
126
|
+
], queries: [{ propertyName: "items", predicate: SelectItemComponent, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true }], ngImport: i0, template: `
|
|
127
|
+
<div [class]="cn('relative w-full', 'size-' + size)" #container>
|
|
128
|
+
<button #trigger type="button" (click)="toggle()" [disabled]="disabled"
|
|
129
|
+
[class]="cn('flex min-h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm focus:ring-2 focus:ring-ring focus:ring-offset-2 transition-all h-auto', class)">
|
|
130
|
+
<div class="flex flex-wrap gap-1 items-center max-w-[95%]">
|
|
131
|
+
<ng-container *ngIf="value?.length; else placeholderTpl">
|
|
132
|
+
<tolle-badge *ngFor="let item of selectedItems" size="xs" variant="secondary" [removable]="true" (onRemove)="removeValue($event, item.value)">
|
|
133
|
+
{{ item.label }}
|
|
134
|
+
</tolle-badge>
|
|
135
|
+
</ng-container>
|
|
136
|
+
<ng-template #placeholderTpl><span class="text-muted-foreground">{{ placeholder }}</span></ng-template>
|
|
137
|
+
</div>
|
|
138
|
+
<i [class]="cn('ri-arrow-down-s-line text-muted-foreground ml-2 transition-transform', isOpen ? 'rotate-180' : '')"></i>
|
|
139
|
+
</button>
|
|
140
|
+
|
|
141
|
+
<div #popover *ngIf="isOpen" class="absolute bg-popover z-50 min-w-full rounded-md border border-border shadow-md overflow-hidden" style="visibility: hidden;">
|
|
142
|
+
|
|
143
|
+
<div class="p-2 border-b border-border space-y-2 bg-popover">
|
|
144
|
+
<tolle-input *ngIf="searchable" size="xs" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="onSearchChange($event)">
|
|
145
|
+
<i prefix class="ri-search-line"></i>
|
|
146
|
+
</tolle-input>
|
|
147
|
+
|
|
148
|
+
<div class="flex items-center justify-between px-1">
|
|
149
|
+
<button type="button" (click)="selectAll()" class="text-[10px] font-bold uppercase text-primary hover:underline">Select All</button>
|
|
150
|
+
<button type="button" (click)="clearAll()" class="text-[10px] font-bold uppercase text-muted-foreground hover:underline">Clear</button>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<div class="p-1 max-h-60 overflow-y-auto">
|
|
155
|
+
<ng-content></ng-content>
|
|
156
|
+
<div *ngIf="noResults" class="py-4 text-center text-xs text-muted-foreground">No results found for "{{searchQuery}}"</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BadgeComponent, selector: "tolle-badge", inputs: ["variant", "size", "removable", "class"], outputs: ["onRemove"] }, { kind: "component", type: InputComponent, selector: "tolle-input", inputs: ["type", "placeholder", "disabled", "error", "size", "containerClass", "class"] }] });
|
|
161
|
+
}
|
|
162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MultiSelectComponent, decorators: [{
|
|
163
|
+
type: Component,
|
|
164
|
+
args: [{
|
|
165
|
+
selector: 'tolle-multi-select',
|
|
166
|
+
standalone: true,
|
|
167
|
+
imports: [CommonModule, FormsModule, BadgeComponent, InputComponent],
|
|
168
|
+
providers: [
|
|
169
|
+
SelectService,
|
|
170
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: MultiSelectComponent, multi: true }
|
|
171
|
+
],
|
|
172
|
+
template: `
|
|
173
|
+
<div [class]="cn('relative w-full', 'size-' + size)" #container>
|
|
174
|
+
<button #trigger type="button" (click)="toggle()" [disabled]="disabled"
|
|
175
|
+
[class]="cn('flex min-h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm focus:ring-2 focus:ring-ring focus:ring-offset-2 transition-all h-auto', class)">
|
|
176
|
+
<div class="flex flex-wrap gap-1 items-center max-w-[95%]">
|
|
177
|
+
<ng-container *ngIf="value?.length; else placeholderTpl">
|
|
178
|
+
<tolle-badge *ngFor="let item of selectedItems" size="xs" variant="secondary" [removable]="true" (onRemove)="removeValue($event, item.value)">
|
|
179
|
+
{{ item.label }}
|
|
180
|
+
</tolle-badge>
|
|
181
|
+
</ng-container>
|
|
182
|
+
<ng-template #placeholderTpl><span class="text-muted-foreground">{{ placeholder }}</span></ng-template>
|
|
183
|
+
</div>
|
|
184
|
+
<i [class]="cn('ri-arrow-down-s-line text-muted-foreground ml-2 transition-transform', isOpen ? 'rotate-180' : '')"></i>
|
|
185
|
+
</button>
|
|
186
|
+
|
|
187
|
+
<div #popover *ngIf="isOpen" class="absolute bg-popover z-50 min-w-full rounded-md border border-border shadow-md overflow-hidden" style="visibility: hidden;">
|
|
188
|
+
|
|
189
|
+
<div class="p-2 border-b border-border space-y-2 bg-popover">
|
|
190
|
+
<tolle-input *ngIf="searchable" size="xs" placeholder="Search..." [(ngModel)]="searchQuery" (ngModelChange)="onSearchChange($event)">
|
|
191
|
+
<i prefix class="ri-search-line"></i>
|
|
192
|
+
</tolle-input>
|
|
193
|
+
|
|
194
|
+
<div class="flex items-center justify-between px-1">
|
|
195
|
+
<button type="button" (click)="selectAll()" class="text-[10px] font-bold uppercase text-primary hover:underline">Select All</button>
|
|
196
|
+
<button type="button" (click)="clearAll()" class="text-[10px] font-bold uppercase text-muted-foreground hover:underline">Clear</button>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div class="p-1 max-h-60 overflow-y-auto">
|
|
201
|
+
<ng-content></ng-content>
|
|
202
|
+
<div *ngIf="noResults" class="py-4 text-center text-xs text-muted-foreground">No results found for "{{searchQuery}}"</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`
|
|
207
|
+
}]
|
|
208
|
+
}], ctorParameters: () => [{ type: i1.SelectService }], propDecorators: { placeholder: [{
|
|
209
|
+
type: Input
|
|
210
|
+
}], size: [{
|
|
211
|
+
type: Input
|
|
212
|
+
}], searchable: [{
|
|
213
|
+
type: Input
|
|
214
|
+
}], disabled: [{
|
|
215
|
+
type: Input
|
|
216
|
+
}], class: [{
|
|
217
|
+
type: Input
|
|
218
|
+
}], trigger: [{
|
|
219
|
+
type: ViewChild,
|
|
220
|
+
args: ['trigger']
|
|
221
|
+
}], popover: [{
|
|
222
|
+
type: ViewChild,
|
|
223
|
+
args: ['popover']
|
|
224
|
+
}], items: [{
|
|
225
|
+
type: ContentChildren,
|
|
226
|
+
args: [SelectItemComponent, { descendants: true }]
|
|
227
|
+
}], onClickOutside: [{
|
|
228
|
+
type: HostListener,
|
|
229
|
+
args: ['document:mousedown', ['$event']]
|
|
230
|
+
}] } });
|
|
231
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvbXVsdGktc2VsZWN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQTJDLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDcEksT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakQsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNoQyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLDJCQUEyQixDQUFDOzs7OztBQThDekQsTUFBTSxPQUFPLG9CQUFvQjtJQWtCWDtJQWpCWCxXQUFXLEdBQUcsbUJBQW1CLENBQUM7SUFDbEMsSUFBSSxHQUFtQyxTQUFTLENBQUM7SUFDakQsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUNuQixRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQ2pCLEtBQUssR0FBRyxFQUFFLENBQUM7SUFFRSxPQUFPLENBQWM7SUFDckIsT0FBTyxDQUFjO0lBQ2tCLEtBQUssQ0FBa0M7SUFFcEcsS0FBSyxHQUFVLEVBQUUsQ0FBQztJQUNsQixhQUFhLEdBQWtDLEVB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QUFlO3VCQUFDLG1CQUFtQixFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtnQkErRjNELGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIENvbnRlbnRDaGlsZHJlbiwgUXVlcnlMaXN0LCBBZnRlckNvbnRlbnRJbml0LCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIEhvc3RMaXN0ZW5lciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiwgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBjb21wdXRlUG9zaXRpb24sIGZsaXAsIHNoaWZ0LCBvZmZzZXQsIGF1dG9VcGRhdGUgfSBmcm9tICdAZmxvYXRpbmctdWkvZG9tJztcbmltcG9ydCB7IFNlbGVjdEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL3NlbGVjdC1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWxlY3RTZXJ2aWNlIH0gZnJvbSAnLi9zZWxlY3Quc2VydmljZSc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuaW1wb3J0IHtCYWRnZUNvbXBvbmVudH0gZnJvbSAnQHRvbGxlL3VpL2JhZGdlLmNvbXBvbmVudCc7XG5pbXBvcnQge0lucHV0Q29tcG9uZW50fSBmcm9tICdAdG9sbGUvdWkvaW5wdXQuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtbXVsdGktc2VsZWN0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIEJhZGdlQ29tcG9uZW50LCBJbnB1dENvbXBvbmVudF0sXG4gIHByb3ZpZGVyczogW1xuICAgIFNlbGVjdFNlcnZpY2UsXG4gICAgeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IE11bHRpU2VsZWN0Q29tcG9uZW50LCBtdWx0aTogdHJ1ZSB9XG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY24oJ3JlbGF0aXZlIHctZnVsbCcsICdzaXplLScgKyBzaXplKVwiICNjb250YWluZXI+XG4gICAgICA8YnV0dG9uICN0cmlnZ2VyIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwidG9nZ2xlKClcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICAgICBbY2xhc3NdPVwiY24oJ2ZsZXggbWluLWgtMTAgdy1mdWxsIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gcm91bmRlZC1tZCBib3JkZXIgYm9yZGVyLWlucHV0IGJnLWJhY2tncm91bmQgcHgtMyBweS0yIHRleHQtc20gZm9jdXM6cmluZy0yIGZvY3VzOnJpbmctcmluZyBmb2N1czpyaW5nLW9mZnNldC0yIHRyYW5zaXRpb24tYWxsIGgtYXV0bycsIGNsYXNzKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXAgZ2FwLTEgaXRlbXMtY2VudGVyIG1heC13LVs5NSVdXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInZhbHVlPy5sZW5ndGg7IGVsc2UgcGxhY2Vob2xkZXJUcGxcIj5cbiAgICAgICAgICAgIDx0b2xsZS1iYWRnZSAqbmdGb3I9XCJsZXQgaXRlbSBvZiBzZWxlY3RlZEl0ZW1zXCIgc2l6ZT1cInhzXCIgdmFyaWFudD1cInNlY29uZGFyeVwiIFtyZW1vdmFibGVdPVwidHJ1ZVwiIChvblJlbW92ZSk9XCJyZW1vdmVWYWx1ZSgkZXZlbnQsIGl0ZW0udmFsdWUpXCI+XG4gICAgICAgICAgICAgIHt7IGl0ZW0ubGFiZWwgfX1cbiAgICAgICAgICAgIDwvdG9sbGUtYmFkZ2U+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNwbGFjZWhvbGRlclRwbD48c3BhbiBjbGFzcz1cInRleHQtbXV0ZWQtZm9yZWdyb3VuZFwiPnt7IHBsYWNlaG9sZGVyIH19PC9zcGFuPjwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8aSBbY2xhc3NdPVwiY24oJ3JpLWFycm93LWRvd24tcy1saW5lIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCBtbC0yIHRyYW5zaXRpb24tdHJhbnNmb3JtJywgaXNPcGVuID8gJ3JvdGF0ZS0xODAnIDogJycpXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG5cbiAgICAgIDxkaXYgI3BvcG92ZXIgKm5nSWY9XCJpc09wZW5cIiBjbGFzcz1cImFic29sdXRlIGJnLXBvcG92ZXIgei01MCBtaW4tdy1mdWxsIHJvdW5kZWQtbWQgYm9yZGVyIGJvcmRlci1ib3JkZXIgc2hhZG93LW1kIG92ZXJmbG93LWhpZGRlblwiIHN0eWxlPVwidmlzaWJpbGl0eTogaGlkZGVuO1wiPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwLTIgYm9yZGVyLWIgYm9yZGVyLWJvcmRlciBzcGFjZS15LTIgYmctcG9wb3ZlclwiPlxuICAgICAgICAgIDx0b2xsZS1pbnB1dCAqbmdJZj1cInNlYXJjaGFibGVcIiBzaXplPVwieHNcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiIFsobmdNb2RlbCldPVwic2VhcmNoUXVlcnlcIiAobmdNb2RlbENoYW5nZSk9XCJvblNlYXJjaENoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8aSBwcmVmaXggY2xhc3M9XCJyaS1zZWFyY2gtbGluZVwiPjwvaT5cbiAgICAgICAgICA8L3RvbGxlLWlucHV0PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlbiBweC0xXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwic2VsZWN0QWxsKClcIiBjbGFzcz1cInRleHQtWzEwcHhdIGZvbnQtYm9sZCB1cHBlcmNhc2UgdGV4dC1wcmltYXJ5IGhvdmVyOnVuZGVybGluZVwiPlNlbGVjdCBBbGw8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjbGVhckFsbCgpXCIgY2xhc3M9XCJ0ZXh0LVsxMHB4XSBmb250LWJvbGQgdXBwZXJjYXNlIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCBob3Zlcjp1bmRlcmxpbmVcIj5DbGVhcjwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwicC0xIG1heC1oLTYwIG92ZXJmbG93LXktYXV0b1wiPlxuICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwibm9SZXN1bHRzXCIgY2xhc3M9XCJweS00IHRleHQtY2VudGVyIHRleHQteHMgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCI+Tm8gcmVzdWx0cyBmb3VuZCBmb3IgXCJ7e3NlYXJjaFF1ZXJ5fX1cIjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIE11bHRpU2VsZWN0Q29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEFmdGVyQ29udGVudEluaXQge1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdTZWxlY3Qgb3B0aW9ucy4uLic7XG4gIEBJbnB1dCgpIHNpemU6ICd4cycgfCAnc20nIHwgJ2RlZmF1bHQnIHwgJ2xnJyA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgc2VhcmNoYWJsZSA9IGZhbHNlO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBjbGFzcyA9ICcnO1xuXG4gIEBWaWV3Q2hpbGQoJ3RyaWdnZXInKSB0cmlnZ2VyITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgncG9wb3ZlcicpIHBvcG92ZXIhOiBFbGVtZW50UmVmO1xuICBAQ29udGVudENoaWxkcmVuKFNlbGVjdEl0ZW1Db21wb25lbnQsIHsgZGVzY2VuZGFudHM6IHRydWUgfSkgaXRlbXMhOiBRdWVyeUxpc3Q8U2VsZWN0SXRlbUNvbXBvbmVudD47XG5cbiAgdmFsdWU6IGFueVtdID0gW107XG4gIHNlbGVjdGVkSXRlbXM6IHtsYWJlbDogc3RyaW5nLCB2YWx1ZTogYW55fVtdID0gW107XG4gIGlzT3BlbiA9IGZhbHNlO1xuICBzZWFyY2hRdWVyeSA9ICcnO1xuICBub1Jlc3VsdHMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBjbGVhbnVwPzogKCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlbGVjdFNlcnZpY2U6IFNlbGVjdFNlcnZpY2UpIHtcbiAgICB0aGlzLnNlbGVjdFNlcnZpY2Uuc2VsZWN0ZWRWYWx1ZSQuc3Vic2NyaWJlKHZhbCA9PiB7XG4gICAgICBpZiAodmFsICE9PSB1bmRlZmluZWQgJiYgdGhpcy5pc09wZW4pIHRoaXMudG9nZ2xlVmFsdWUodmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLnN5bmNJdGVtcygpO1xuICAgIHRoaXMuaXRlbXMuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zeW5jSXRlbXMoKSk7XG4gIH1cblxuICB0b2dnbGUoKSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHJldHVybjtcbiAgICB0aGlzLmlzT3BlbiA/IHRoaXMuY2xvc2UoKSA6IHRoaXMub3BlbigpO1xuICB9XG5cbiAgb3BlbigpIHtcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnVwZGF0ZVBvc2l0aW9uKCkpO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICBpZiAodGhpcy5jbGVhbnVwKSB0aGlzLmNsZWFudXAoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9zaXRpb24oKSB7XG4gICAgdGhpcy5jbGVhbnVwID0gYXV0b1VwZGF0ZSh0aGlzLnRyaWdnZXIubmF0aXZlRWxlbWVudCwgdGhpcy5wb3BvdmVyLm5hdGl2ZUVsZW1lbnQsICgpID0+IHtcbiAgICAgIGNvbXB1dGVQb3NpdGlvbih0aGlzLnRyaWdnZXIubmF0aXZlRWxlbWVudCwgdGhpcy5wb3BvdmVyLm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgICAgcGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcbiAgICAgICAgbWlkZGxld2FyZTogW29mZnNldCg0KSwgZmxpcCgpLCBzaGlmdCh7IHBhZGRpbmc6IDggfSldLFxuICAgICAgfSkudGhlbigoeyB4LCB5IH0pID0+IHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLnBvcG92ZXIubmF0aXZlRWxlbWVudC5zdHlsZSwge1xuICAgICAgICAgIGxlZnQ6IGAke3h9cHhgLFxuICAgICAgICAgIHRvcDogYCR7eX1weGAsXG4gICAgICAgICAgdmlzaWJpbGl0eTogJ3Zpc2libGUnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgdG9nZ2xlVmFsdWUodmFsOiBhbnkpIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMudmFsdWUuaW5kZXhPZih2YWwpO1xuICAgIGluZGV4ID4gLTEgPyB0aGlzLnZhbHVlLnNwbGljZShpbmRleCwgMSkgOiB0aGlzLnZhbHVlLnB1c2godmFsKTtcbiAgICB0aGlzLnN5bmNJdGVtcygpO1xuICAgIHRoaXMub25DaGFuZ2UoWy4uLnRoaXMudmFsdWVdKTsgLy8gUmV0dXJuIG5ldyBhcnJheSByZWZlcmVuY2UgZm9yIENoYW5nZSBEZXRlY3Rpb25cbiAgfVxuXG4gIHNlbGVjdEFsbCgpIHtcbiAgICB0aGlzLnZhbHVlID0gdGhpcy5pdGVtcy5tYXAoaSA9PiBpLnZhbHVlKTtcbiAgICB0aGlzLnN5bmNJdGVtcygpO1xuICAgIHRoaXMub25DaGFuZ2UoWy4uLnRoaXMudmFsdWVdKTtcbiAgfVxuXG4gIGNsZWFyQWxsKCkge1xuICAgIHRoaXMudmFsdWUgPSBbXTtcbiAgICB0aGlzLnN5bmNJdGVtcygpO1xuICAgIHRoaXMub25DaGFuZ2UoW10pO1xuICB9XG5cbiAgcmVtb3ZlVmFsdWUoZXZlbnQ6IE1vdXNlRXZlbnQsIHZhbDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy50b2dnbGVWYWx1ZSh2YWwpO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jSXRlbXMoKSB7XG4gICAgaWYgKCF0aGlzLml0ZW1zKSByZXR1cm47XG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zID0gW107XG4gICAgdGhpcy5pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgaXRlbS5zZWxlY3RlZCA9IHRoaXMudmFsdWUuaW5jbHVkZXMoaXRlbS52YWx1ZSk7XG4gICAgICBpZiAoaXRlbS5zZWxlY3RlZCkgdGhpcy5zZWxlY3RlZEl0ZW1zLnB1c2goeyBsYWJlbDogaXRlbS5nZXRMYWJlbCgpLCB2YWx1ZTogaXRlbS52YWx1ZSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG9uU2VhcmNoQ2hhbmdlKHE6IHN0cmluZykge1xuICAgIGNvbnN0IGZpbHRlciA9IChxIHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIGxldCB2aXNpYmxlQ291bnQgPSAwO1xuICAgIHRoaXMuaXRlbXMuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IGl0ZW0uZ2V0TGFiZWwoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGZpbHRlcik7XG4gICAgICBpdGVtLmhpZGRlbiA9ICFpc1Zpc2libGU7XG4gICAgICBpZiAoaXNWaXNpYmxlKSB2aXNpYmxlQ291bnQrKztcbiAgICB9KTtcbiAgICB0aGlzLm5vUmVzdWx0cyA9IHZpc2libGVDb3VudCA9PT0gMCAmJiBmaWx0ZXIgIT09ICcnO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vkb3duJywgWyckZXZlbnQnXSlcbiAgb25DbGlja091dHNpZGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc09wZW4gJiYgIXRoaXMudHJpZ2dlci5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgJiYgIXRoaXMucG9wb3Zlcj8ubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29udHJvbFZhbHVlQWNjZXNzb3JcbiAgb25DaGFuZ2U6IGFueSA9ICgpID0+IHt9O1xuICBvblRvdWNoZWQ6IGFueSA9ICgpID0+IHt9O1xuICB3cml0ZVZhbHVlKHY6IGFueVtdKTogdm9pZCB7IHRoaXMudmFsdWUgPSBBcnJheS5pc0FycmF5KHYpID8gdiA6IFtdOyB0aGlzLnN5bmNJdGVtcygpOyB9XG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQgeyB0aGlzLm9uQ2hhbmdlID0gZm47IH1cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQgeyB0aGlzLm9uVG91Y2hlZCA9IGZuOyB9XG4gIHByb3RlY3RlZCBjbiA9IGNuO1xufVxuIl19
|