@yoozsoft/yoozsoft-ng 5.0.2 → 5.1.0
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/assets/js/UTIF.js-master/LICENSE +21 -21
- package/assets/js/UTIF.js-master/README.md +72 -72
- package/assets/js/UTIF.js-master/UTIF.js +1762 -1762
- package/assets/js/UTIF.js-master/package-lock.json +13 -13
- package/autocomplete/index.d.ts +65 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-autocomplete.mjs +252 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-autocomplete.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-datepicker.mjs +12 -12
- package/fesm2022/yoozsoft-yoozsoft-ng-datepicker.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-file-upload.mjs +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-file-upload.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-footer.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-footer.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-loading.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-loading.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-navbar.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-navbar.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-password-strength.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-password-strength.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-select.mjs +4 -4
- package/fesm2022/yoozsoft-yoozsoft-ng-select.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-sidebar.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-sidebar.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-toast.mjs +2 -2
- package/fesm2022/yoozsoft-yoozsoft-ng-toast.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng.mjs.map +1 -1
- package/package.json +18 -13
- package/select/index.d.ts +2 -2
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "utif",
|
|
3
|
-
"version": "1.3.0",
|
|
4
|
-
"lockfileVersion": 1,
|
|
5
|
-
"requires": true,
|
|
6
|
-
"dependencies": {
|
|
7
|
-
"pako": {
|
|
8
|
-
"version": "1.0.6",
|
|
9
|
-
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
|
10
|
-
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "utif",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"lockfileVersion": 1,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"pako": {
|
|
8
|
+
"version": "1.0.6",
|
|
9
|
+
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
|
10
|
+
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { TemplateRef, EventEmitter, ElementRef } from '@angular/core';
|
|
3
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
declare class YsAutocompleteComponent implements ControlValueAccessor {
|
|
7
|
+
private elRef;
|
|
8
|
+
searchTerm: string;
|
|
9
|
+
filteredItems: any[];
|
|
10
|
+
selectedItems: any[];
|
|
11
|
+
showDropdown: boolean;
|
|
12
|
+
activeIndex: number;
|
|
13
|
+
error: string | null;
|
|
14
|
+
/** Array or async function */
|
|
15
|
+
items?: any[] | ((term: string) => Observable<any[]>);
|
|
16
|
+
/** Label display field */
|
|
17
|
+
labelField: string;
|
|
18
|
+
/** placeholder */
|
|
19
|
+
placeholder: string;
|
|
20
|
+
/** Multiple choice mode */
|
|
21
|
+
multiple: boolean;
|
|
22
|
+
/** Custom template */
|
|
23
|
+
itemTemplate?: TemplateRef<any>;
|
|
24
|
+
styleClass?: string;
|
|
25
|
+
/** Badge style class on Multiple choice mode */
|
|
26
|
+
badgeStyleClass?: string;
|
|
27
|
+
loading: boolean;
|
|
28
|
+
loadingMessage: string;
|
|
29
|
+
/** No results found message */
|
|
30
|
+
noResultMessage: string;
|
|
31
|
+
/** Infinite scroll feature enabled */
|
|
32
|
+
infiniteScroll: boolean;
|
|
33
|
+
/** Event to request more items */
|
|
34
|
+
loadMore: EventEmitter<string>;
|
|
35
|
+
/** Output selection */
|
|
36
|
+
selected: EventEmitter<any>;
|
|
37
|
+
/** Output selection after removed item */
|
|
38
|
+
removed: EventEmitter<any>;
|
|
39
|
+
private search$;
|
|
40
|
+
private onChange;
|
|
41
|
+
private onTouched;
|
|
42
|
+
inputRef: ElementRef<HTMLInputElement>;
|
|
43
|
+
get isArrayItems(): boolean;
|
|
44
|
+
get isFunctionItems(): boolean;
|
|
45
|
+
constructor(elRef: ElementRef);
|
|
46
|
+
ngOnInit(): void;
|
|
47
|
+
/** For the initial value of FormControl */
|
|
48
|
+
writeValue(value: any): void;
|
|
49
|
+
registerOnChange(fn: any): void;
|
|
50
|
+
registerOnTouched(fn: any): void;
|
|
51
|
+
setDisabledState?(isDisabled: boolean): void;
|
|
52
|
+
onSearchChange(): void;
|
|
53
|
+
getLabel(item: any): string;
|
|
54
|
+
onSelect(item: any): void;
|
|
55
|
+
removeItem(item: any): void;
|
|
56
|
+
onScroll(event: Event): void;
|
|
57
|
+
/** Keyboard control */
|
|
58
|
+
handleKeyboard(event: KeyboardEvent): void;
|
|
59
|
+
/** Close by clicking outside */
|
|
60
|
+
onClickOutside(event: MouseEvent): void;
|
|
61
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<YsAutocompleteComponent, never>;
|
|
62
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<YsAutocompleteComponent, "ys-autocomplete", never, { "items": { "alias": "items"; "required": false; }; "labelField": { "alias": "labelField"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "styleClass": { "alias": "styleClass"; "required": false; }; "badgeStyleClass": { "alias": "badgeStyleClass"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "loadingMessage": { "alias": "loadingMessage"; "required": false; }; "noResultMessage": { "alias": "noResultMessage"; "required": false; }; "infiniteScroll": { "alias": "infiniteScroll"; "required": false; }; }, { "loadMore": "loadMore"; "selected": "selected"; "removed": "removed"; }, ["itemTemplate"], never, true, never>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { YsAutocompleteComponent };
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import * as i2 from '@angular/cdk/scrolling';
|
|
2
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
3
|
+
import { NgTemplateOutlet, NgClass } from '@angular/common';
|
|
4
|
+
import * as i0 from '@angular/core';
|
|
5
|
+
import { EventEmitter, TemplateRef, forwardRef, HostListener, ViewChild, Output, Input, ContentChild, Component } from '@angular/core';
|
|
6
|
+
import * as i1 from '@angular/forms';
|
|
7
|
+
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
8
|
+
import { Subject, debounceTime, distinctUntilChanged, switchMap, catchError, of } from 'rxjs';
|
|
9
|
+
|
|
10
|
+
class YsAutocompleteComponent {
|
|
11
|
+
elRef;
|
|
12
|
+
searchTerm = '';
|
|
13
|
+
filteredItems = [];
|
|
14
|
+
selectedItems = [];
|
|
15
|
+
showDropdown = false;
|
|
16
|
+
activeIndex = -1;
|
|
17
|
+
error = null;
|
|
18
|
+
/** Array or async function */
|
|
19
|
+
items;
|
|
20
|
+
/** Label display field */
|
|
21
|
+
labelField = '';
|
|
22
|
+
/** placeholder */
|
|
23
|
+
placeholder = 'Search...';
|
|
24
|
+
/** Multiple choice mode */
|
|
25
|
+
multiple = false;
|
|
26
|
+
/** Custom template */
|
|
27
|
+
itemTemplate;
|
|
28
|
+
styleClass;
|
|
29
|
+
/** Badge style class on Multiple choice mode */
|
|
30
|
+
badgeStyleClass;
|
|
31
|
+
loading = false;
|
|
32
|
+
loadingMessage = 'Loading...';
|
|
33
|
+
/** No results found message */
|
|
34
|
+
noResultMessage = 'No results found.';
|
|
35
|
+
/** Infinite scroll feature enabled */
|
|
36
|
+
infiniteScroll = false;
|
|
37
|
+
/** Event to request more items */
|
|
38
|
+
loadMore = new EventEmitter();
|
|
39
|
+
/** Output selection */
|
|
40
|
+
selected = new EventEmitter();
|
|
41
|
+
/** Output selection after removed item */
|
|
42
|
+
removed = new EventEmitter();
|
|
43
|
+
search$ = new Subject();
|
|
44
|
+
onChange = () => { };
|
|
45
|
+
onTouched = () => { };
|
|
46
|
+
inputRef;
|
|
47
|
+
get isArrayItems() { return Array.isArray(this.items); }
|
|
48
|
+
get isFunctionItems() { return typeof this.items === 'function'; }
|
|
49
|
+
constructor(elRef) {
|
|
50
|
+
this.elRef = elRef;
|
|
51
|
+
}
|
|
52
|
+
ngOnInit() {
|
|
53
|
+
if (Array.isArray(this.items)) {
|
|
54
|
+
this.filteredItems = this.items;
|
|
55
|
+
}
|
|
56
|
+
/** Only in async function mode */
|
|
57
|
+
if (typeof this.items === 'function') {
|
|
58
|
+
const fetchFn = this.items;
|
|
59
|
+
this.search$
|
|
60
|
+
.pipe(debounceTime(300), distinctUntilChanged(), switchMap((term) => {
|
|
61
|
+
this.loading = true;
|
|
62
|
+
this.error = null;
|
|
63
|
+
return fetchFn(term).pipe(catchError((err) => {
|
|
64
|
+
this.error = 'Error receiving data!';
|
|
65
|
+
console.error(err);
|
|
66
|
+
return of([]);
|
|
67
|
+
}));
|
|
68
|
+
}))
|
|
69
|
+
.subscribe((results) => {
|
|
70
|
+
this.filteredItems = results;
|
|
71
|
+
this.loading = false;
|
|
72
|
+
this.showDropdown = true;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** For the initial value of FormControl */
|
|
77
|
+
writeValue(value) {
|
|
78
|
+
if (this.multiple) {
|
|
79
|
+
this.selectedItems = value ? [...value] : [];
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.searchTerm = value ? this.getLabel(value) : '';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
registerOnChange(fn) {
|
|
86
|
+
this.onChange = fn;
|
|
87
|
+
}
|
|
88
|
+
registerOnTouched(fn) {
|
|
89
|
+
this.onTouched = fn;
|
|
90
|
+
}
|
|
91
|
+
setDisabledState(isDisabled) {
|
|
92
|
+
if (this.inputRef) {
|
|
93
|
+
this.inputRef.nativeElement.disabled = isDisabled;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
onSearchChange() {
|
|
97
|
+
const term = this.searchTerm.trim();
|
|
98
|
+
if (Array.isArray(this.items)) {
|
|
99
|
+
const lower = term.toLowerCase();
|
|
100
|
+
this.filteredItems = this.items.filter((item) => this.getLabel(item).toLowerCase().includes(lower));
|
|
101
|
+
this.showDropdown = this.filteredItems.length >= 0;
|
|
102
|
+
}
|
|
103
|
+
else if (typeof this.items === 'function') {
|
|
104
|
+
this.search$.next(term);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getLabel(item) {
|
|
108
|
+
if (!item)
|
|
109
|
+
return '';
|
|
110
|
+
if (typeof item === 'string')
|
|
111
|
+
return item;
|
|
112
|
+
if (item && this.labelField && item[this.labelField]) {
|
|
113
|
+
return item[this.labelField];
|
|
114
|
+
}
|
|
115
|
+
return '';
|
|
116
|
+
}
|
|
117
|
+
onSelect(item) {
|
|
118
|
+
if (this.multiple) {
|
|
119
|
+
const exists = this.selectedItems.some((x) => this.getLabel(x) === this.getLabel(item));
|
|
120
|
+
if (!exists) {
|
|
121
|
+
this.selectedItems.push(item);
|
|
122
|
+
this.onChange(this.selectedItems);
|
|
123
|
+
this.selected.emit(this.selectedItems);
|
|
124
|
+
}
|
|
125
|
+
this.searchTerm = '';
|
|
126
|
+
this.showDropdown = true;
|
|
127
|
+
this.onSearchChange();
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.searchTerm = this.getLabel(item);
|
|
131
|
+
this.onChange(item);
|
|
132
|
+
this.selected.emit(item);
|
|
133
|
+
this.showDropdown = false;
|
|
134
|
+
}
|
|
135
|
+
this.activeIndex = -1;
|
|
136
|
+
}
|
|
137
|
+
removeItem(item) {
|
|
138
|
+
this.selectedItems = this.selectedItems.filter((x) => this.getLabel(x) !== this.getLabel(item));
|
|
139
|
+
this.onChange(this.selectedItems);
|
|
140
|
+
this.removed.emit(this.selectedItems);
|
|
141
|
+
}
|
|
142
|
+
onScroll(event) {
|
|
143
|
+
if (!this.infiniteScroll || this.loading)
|
|
144
|
+
return;
|
|
145
|
+
const target = event.target;
|
|
146
|
+
const nearBottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 10;
|
|
147
|
+
if (nearBottom) {
|
|
148
|
+
// Request more items
|
|
149
|
+
this.loadMore.emit(this.searchTerm);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Keyboard control */
|
|
153
|
+
handleKeyboard(event) {
|
|
154
|
+
if (!this.showDropdown || this.filteredItems.length === 0)
|
|
155
|
+
return;
|
|
156
|
+
switch (event.key) {
|
|
157
|
+
case 'ArrowDown':
|
|
158
|
+
this.activeIndex = (this.activeIndex + 1) % this.filteredItems.length;
|
|
159
|
+
event.preventDefault();
|
|
160
|
+
break;
|
|
161
|
+
case 'ArrowUp':
|
|
162
|
+
this.activeIndex =
|
|
163
|
+
(this.activeIndex - 1 + this.filteredItems.length) %
|
|
164
|
+
this.filteredItems.length;
|
|
165
|
+
event.preventDefault();
|
|
166
|
+
break;
|
|
167
|
+
case 'Enter':
|
|
168
|
+
if (this.activeIndex >= 0) {
|
|
169
|
+
this.onSelect(this.filteredItems[this.activeIndex]);
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
case 'Escape':
|
|
174
|
+
this.showDropdown = false;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Close by clicking outside */
|
|
179
|
+
onClickOutside(event) {
|
|
180
|
+
const clickedInside = this.elRef.nativeElement.contains(event.target);
|
|
181
|
+
if (!clickedInside) {
|
|
182
|
+
this.showDropdown = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: YsAutocompleteComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
186
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: YsAutocompleteComponent, isStandalone: true, selector: "ys-autocomplete", inputs: { items: "items", labelField: "labelField", placeholder: "placeholder", multiple: "multiple", styleClass: "styleClass", badgeStyleClass: "badgeStyleClass", loading: "loading", loadingMessage: "loadingMessage", noResultMessage: "noResultMessage", infiniteScroll: "infiniteScroll" }, outputs: { loadMore: "loadMore", selected: "selected", removed: "removed" }, host: { listeners: { "keydown": "handleKeyboard($event)", "document:click": "onClickOutside($event)" } }, providers: [
|
|
187
|
+
{
|
|
188
|
+
provide: NG_VALUE_ACCESSOR,
|
|
189
|
+
useExisting: forwardRef(() => YsAutocompleteComponent),
|
|
190
|
+
multi: true,
|
|
191
|
+
},
|
|
192
|
+
], queries: [{ propertyName: "itemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true }], ngImport: i0, template: "<div class=\"ys-autocomplete position-relative\">\r\n <div class=\"input-group flex-wrap\">\r\n @if (multiple && selectedItems.length > 0) {\r\n <div class=\"d-flex flex-wrap\">\r\n @for (item of selectedItems; track item) {\r\n <span class=\"badge bg-primary me-1 mb-1 p-2 d-flex align-items-center\" [ngClass]=\"badgeStyleClass\">\r\n {{ getLabel(item) }}\r\n <i class=\"fa fa-times ms-2 cursor-pointer\" (click)=\"removeItem(item)\"></i>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"input-group w-100\">\r\n <input #inputRef type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchTerm\"\r\n (input)=\"onSearchChange()\" (focus)=\"showDropdown = true\" [ngClass]=\"styleClass\" />\r\n\r\n <span class=\"input-group-text\">\r\n <i class=\"fa fa-search\"></i>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (showDropdown) {\r\n <div class=\"dropdown-container position-absolute w-100 shadow-sm bg-white border rounded\">\r\n @if (loading) {\r\n <div class=\"list-group-item text-center\">\r\n <i class=\"fa fa-spinner fa-spin me-2\"></i>{{ loadingMessage }}\r\n </div>\r\n } @else if (error) {\r\n <div class=\"list-group-item text-danger text-center\">{{ error }}</div>\r\n } @else if (filteredItems.length === 0) {\r\n <div class=\"list-group-item text-muted text-center\">\r\n {{ noResultMessage }}\r\n </div>\r\n }\r\n <!-- \u2705 \u062D\u0627\u0644\u062A Virtual Scroll \u0628\u0631\u0627\u06CC \u0644\u06CC\u0633\u062A\u200C\u0647\u0627\u06CC \u0628\u0632\u0631\u06AF -->\r\n @else if (filteredItems.length > 100) {\r\n <cdk-virtual-scroll-viewport itemSize=\"36\" class=\"list-group w-100 overflow-y-auto\">\r\n <ul class=\"list-group w-100\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </cdk-virtual-scroll-viewport>\r\n }\r\n <!-- \u2705 \u062D\u0627\u0644\u062A \u0645\u0639\u0645\u0648\u0644\u06CC \u0628\u0631\u0627\u06CC \u0644\u06CC\u0633\u062A\u200C\u0647\u0627\u06CC \u06A9\u0648\u0686\u06A9 -->\r\n @else {\r\n <ul class=\"list-group w-100 overflow-y-auto\" [class.scrollable]=\"infiniteScroll\" (scroll)=\"onScroll($event)\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".ys-autocomplete .dropdown-container,.ys-autocomplete .list-group{z-index:1000;max-height:200px}.ys-autocomplete cdk-virtual-scroll-viewport{height:200px;display:block}.ys-autocomplete .badge{font-size:.9rem;cursor:default}.ys-autocomplete .badge i{cursor:pointer;font-size:.8rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "component", type: i2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }] });
|
|
193
|
+
}
|
|
194
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: YsAutocompleteComponent, decorators: [{
|
|
195
|
+
type: Component,
|
|
196
|
+
args: [{ selector: 'ys-autocomplete', imports: [FormsModule, NgTemplateOutlet, NgClass, ScrollingModule], providers: [
|
|
197
|
+
{
|
|
198
|
+
provide: NG_VALUE_ACCESSOR,
|
|
199
|
+
useExisting: forwardRef(() => YsAutocompleteComponent),
|
|
200
|
+
multi: true,
|
|
201
|
+
},
|
|
202
|
+
], template: "<div class=\"ys-autocomplete position-relative\">\r\n <div class=\"input-group flex-wrap\">\r\n @if (multiple && selectedItems.length > 0) {\r\n <div class=\"d-flex flex-wrap\">\r\n @for (item of selectedItems; track item) {\r\n <span class=\"badge bg-primary me-1 mb-1 p-2 d-flex align-items-center\" [ngClass]=\"badgeStyleClass\">\r\n {{ getLabel(item) }}\r\n <i class=\"fa fa-times ms-2 cursor-pointer\" (click)=\"removeItem(item)\"></i>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"input-group w-100\">\r\n <input #inputRef type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchTerm\"\r\n (input)=\"onSearchChange()\" (focus)=\"showDropdown = true\" [ngClass]=\"styleClass\" />\r\n\r\n <span class=\"input-group-text\">\r\n <i class=\"fa fa-search\"></i>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (showDropdown) {\r\n <div class=\"dropdown-container position-absolute w-100 shadow-sm bg-white border rounded\">\r\n @if (loading) {\r\n <div class=\"list-group-item text-center\">\r\n <i class=\"fa fa-spinner fa-spin me-2\"></i>{{ loadingMessage }}\r\n </div>\r\n } @else if (error) {\r\n <div class=\"list-group-item text-danger text-center\">{{ error }}</div>\r\n } @else if (filteredItems.length === 0) {\r\n <div class=\"list-group-item text-muted text-center\">\r\n {{ noResultMessage }}\r\n </div>\r\n }\r\n <!-- \u2705 \u062D\u0627\u0644\u062A Virtual Scroll \u0628\u0631\u0627\u06CC \u0644\u06CC\u0633\u062A\u200C\u0647\u0627\u06CC \u0628\u0632\u0631\u06AF -->\r\n @else if (filteredItems.length > 100) {\r\n <cdk-virtual-scroll-viewport itemSize=\"36\" class=\"list-group w-100 overflow-y-auto\">\r\n <ul class=\"list-group w-100\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </cdk-virtual-scroll-viewport>\r\n }\r\n <!-- \u2705 \u062D\u0627\u0644\u062A \u0645\u0639\u0645\u0648\u0644\u06CC \u0628\u0631\u0627\u06CC \u0644\u06CC\u0633\u062A\u200C\u0647\u0627\u06CC \u06A9\u0648\u0686\u06A9 -->\r\n @else {\r\n <ul class=\"list-group w-100 overflow-y-auto\" [class.scrollable]=\"infiniteScroll\" (scroll)=\"onScroll($event)\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n\r\n</div>", styles: [".ys-autocomplete .dropdown-container,.ys-autocomplete .list-group{z-index:1000;max-height:200px}.ys-autocomplete cdk-virtual-scroll-viewport{height:200px;display:block}.ys-autocomplete .badge{font-size:.9rem;cursor:default}.ys-autocomplete .badge i{cursor:pointer;font-size:.8rem}\n"] }]
|
|
203
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { items: [{
|
|
204
|
+
type: Input
|
|
205
|
+
}], labelField: [{
|
|
206
|
+
type: Input
|
|
207
|
+
}], placeholder: [{
|
|
208
|
+
type: Input
|
|
209
|
+
}], multiple: [{
|
|
210
|
+
type: Input
|
|
211
|
+
}], itemTemplate: [{
|
|
212
|
+
type: ContentChild,
|
|
213
|
+
args: [TemplateRef]
|
|
214
|
+
}], styleClass: [{
|
|
215
|
+
type: Input
|
|
216
|
+
}], badgeStyleClass: [{
|
|
217
|
+
type: Input
|
|
218
|
+
}], loading: [{
|
|
219
|
+
type: Input
|
|
220
|
+
}], loadingMessage: [{
|
|
221
|
+
type: Input
|
|
222
|
+
}], noResultMessage: [{
|
|
223
|
+
type: Input
|
|
224
|
+
}], infiniteScroll: [{
|
|
225
|
+
type: Input
|
|
226
|
+
}], loadMore: [{
|
|
227
|
+
type: Output
|
|
228
|
+
}], selected: [{
|
|
229
|
+
type: Output
|
|
230
|
+
}], removed: [{
|
|
231
|
+
type: Output
|
|
232
|
+
}], inputRef: [{
|
|
233
|
+
type: ViewChild,
|
|
234
|
+
args: ['inputRef']
|
|
235
|
+
}], handleKeyboard: [{
|
|
236
|
+
type: HostListener,
|
|
237
|
+
args: ['keydown', ['$event']]
|
|
238
|
+
}], onClickOutside: [{
|
|
239
|
+
type: HostListener,
|
|
240
|
+
args: ['document:click', ['$event']]
|
|
241
|
+
}] } });
|
|
242
|
+
|
|
243
|
+
/*
|
|
244
|
+
* Public API Surface of ys-autocomplete
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Generated bundle index. Do not edit.
|
|
249
|
+
*/
|
|
250
|
+
|
|
251
|
+
export { YsAutocompleteComponent };
|
|
252
|
+
//# sourceMappingURL=yoozsoft-yoozsoft-ng-autocomplete.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yoozsoft-yoozsoft-ng-autocomplete.mjs","sources":["../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.component.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.component.html","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/public-api.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/yoozsoft-yoozsoft-ng-autocomplete.ts"],"sourcesContent":["import { ScrollingModule } from '@angular/cdk/scrolling';\r\nimport { NgClass, NgTemplateOutlet } from '@angular/common';\r\nimport { Component, ContentChild, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core';\r\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { catchError, debounceTime, distinctUntilChanged, Observable, of, Subject, switchMap } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'ys-autocomplete',\r\n imports: [FormsModule, NgTemplateOutlet, NgClass, ScrollingModule],\r\n templateUrl: './ys-autocomplete.component.html',\r\n styleUrl: './ys-autocomplete.component.scss',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => YsAutocompleteComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class YsAutocompleteComponent implements ControlValueAccessor {\r\n\r\n searchTerm = '';\r\n filteredItems: any[] = [];\r\n selectedItems: any[] = [];\r\n showDropdown = false;\r\n activeIndex = -1;\r\n error: string | null = null;\r\n\r\n /** Array or async function */\r\n @Input() items?: any[] | ((term: string) => Observable<any[]>);\r\n\r\n /** Label display field */\r\n @Input() labelField = '';\r\n\r\n /** placeholder */\r\n @Input() placeholder = 'Search...';\r\n\r\n /** Multiple choice mode */\r\n @Input() multiple = false;\r\n\r\n /** Custom template */\r\n @ContentChild(TemplateRef) itemTemplate?: TemplateRef<any>;\r\n\r\n @Input() styleClass?: string;\r\n /** Badge style class on Multiple choice mode */\r\n @Input() badgeStyleClass?: string;\r\n @Input() loading: boolean = false;\r\n @Input() loadingMessage: string = 'Loading...';\r\n /** No results found message */\r\n @Input() noResultMessage: string = 'No results found.';\r\n\r\n /** Infinite scroll feature enabled */\r\n @Input() infiniteScroll = false;\r\n\r\n /** Event to request more items */\r\n @Output() loadMore = new EventEmitter<string>();\r\n\r\n /** Output selection */\r\n @Output() selected = new EventEmitter<any>();\r\n /** Output selection after removed item */\r\n @Output() removed = new EventEmitter<any>();\r\n\r\n private search$ = new Subject<string>();\r\n private onChange: (value: any) => void = () => { };\r\n private onTouched: () => void = () => { };\r\n\r\n @ViewChild('inputRef') inputRef!: ElementRef<HTMLInputElement>;\r\n\r\n get isArrayItems(): boolean { return Array.isArray(this.items); }\r\n get isFunctionItems(): boolean { return typeof this.items === 'function'; }\r\n\r\n constructor(private elRef: ElementRef) { }\r\n\r\n ngOnInit() {\r\n if (Array.isArray(this.items)) {\r\n this.filteredItems = this.items;\r\n }\r\n\r\n /** Only in async function mode */\r\n if (typeof this.items === 'function') {\r\n const fetchFn = this.items as (term: string) => Observable<any[]>;\r\n this.search$\r\n .pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((term) => {\r\n this.loading = true;\r\n this.error = null;\r\n return fetchFn(term).pipe(\r\n catchError((err) => {\r\n this.error = 'Error receiving data!';\r\n console.error(err);\r\n return of([]);\r\n })\r\n );\r\n })\r\n )\r\n .subscribe((results) => {\r\n this.filteredItems = results;\r\n this.loading = false;\r\n this.showDropdown = true;\r\n });\r\n }\r\n\r\n }\r\n\r\n /** For the initial value of FormControl */\r\n writeValue(value: any): void {\r\n if (this.multiple) {\r\n this.selectedItems = value ? [...value] : [];\r\n } else {\r\n this.searchTerm = value ? this.getLabel(value) : '';\r\n }\r\n }\r\n\r\n registerOnChange(fn: any): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState?(isDisabled: boolean): void {\r\n if (this.inputRef) {\r\n this.inputRef.nativeElement.disabled = isDisabled;\r\n }\r\n }\r\n\r\n onSearchChange() {\r\n const term = this.searchTerm.trim();\r\n\r\n if (Array.isArray(this.items)) {\r\n const lower = term.toLowerCase();\r\n this.filteredItems = this.items.filter((item) =>\r\n this.getLabel(item).toLowerCase().includes(lower)\r\n );\r\n this.showDropdown = this.filteredItems.length >= 0;\r\n } else if (typeof this.items === 'function') {\r\n this.search$.next(term);\r\n }\r\n }\r\n\r\n getLabel(item: any): string {\r\n if (!item) return '';\r\n if (typeof item === 'string') return item;\r\n if (item && this.labelField && item[this.labelField]) {\r\n return item[this.labelField];\r\n }\r\n return '';\r\n }\r\n\r\n onSelect(item: any) {\r\n if (this.multiple) {\r\n const exists = this.selectedItems.some(\r\n (x) => this.getLabel(x) === this.getLabel(item)\r\n );\r\n if (!exists) {\r\n this.selectedItems.push(item);\r\n this.onChange(this.selectedItems);\r\n this.selected.emit(this.selectedItems);\r\n }\r\n this.searchTerm = '';\r\n this.showDropdown = true;\r\n this.onSearchChange();\r\n } else {\r\n this.searchTerm = this.getLabel(item);\r\n this.onChange(item);\r\n this.selected.emit(item);\r\n this.showDropdown = false;\r\n }\r\n\r\n this.activeIndex = -1;\r\n }\r\n\r\n removeItem(item: any) {\r\n this.selectedItems = this.selectedItems.filter(\r\n (x) => this.getLabel(x) !== this.getLabel(item)\r\n );\r\n this.onChange(this.selectedItems);\r\n this.removed.emit(this.selectedItems);\r\n }\r\n\r\n onScroll(event: Event) {\r\n if (!this.infiniteScroll || this.loading) return;\r\n\r\n const target = event.target as HTMLElement;\r\n const nearBottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 10;\r\n\r\n if (nearBottom) {\r\n // Request more items\r\n this.loadMore.emit(this.searchTerm);\r\n }\r\n }\r\n\r\n /** Keyboard control */\r\n @HostListener('keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent) {\r\n if (!this.showDropdown || this.filteredItems.length === 0) return;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n this.activeIndex = (this.activeIndex + 1) % this.filteredItems.length;\r\n event.preventDefault();\r\n break;\r\n case 'ArrowUp':\r\n this.activeIndex =\r\n (this.activeIndex - 1 + this.filteredItems.length) %\r\n this.filteredItems.length;\r\n event.preventDefault();\r\n break;\r\n case 'Enter':\r\n if (this.activeIndex >= 0) {\r\n this.onSelect(this.filteredItems[this.activeIndex]);\r\n event.preventDefault();\r\n }\r\n break;\r\n case 'Escape':\r\n this.showDropdown = false;\r\n break;\r\n }\r\n }\r\n\r\n /** Close by clicking outside */\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const clickedInside = this.elRef.nativeElement.contains(event.target);\r\n if (!clickedInside) {\r\n this.showDropdown = false;\r\n }\r\n }\r\n\r\n}\r\n","<div class=\"ys-autocomplete position-relative\">\r\n <div class=\"input-group flex-wrap\">\r\n @if (multiple && selectedItems.length > 0) {\r\n <div class=\"d-flex flex-wrap\">\r\n @for (item of selectedItems; track item) {\r\n <span class=\"badge bg-primary me-1 mb-1 p-2 d-flex align-items-center\" [ngClass]=\"badgeStyleClass\">\r\n {{ getLabel(item) }}\r\n <i class=\"fa fa-times ms-2 cursor-pointer\" (click)=\"removeItem(item)\"></i>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"input-group w-100\">\r\n <input #inputRef type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchTerm\"\r\n (input)=\"onSearchChange()\" (focus)=\"showDropdown = true\" [ngClass]=\"styleClass\" />\r\n\r\n <span class=\"input-group-text\">\r\n <i class=\"fa fa-search\"></i>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (showDropdown) {\r\n <div class=\"dropdown-container position-absolute w-100 shadow-sm bg-white border rounded\">\r\n @if (loading) {\r\n <div class=\"list-group-item text-center\">\r\n <i class=\"fa fa-spinner fa-spin me-2\"></i>{{ loadingMessage }}\r\n </div>\r\n } @else if (error) {\r\n <div class=\"list-group-item text-danger text-center\">{{ error }}</div>\r\n } @else if (filteredItems.length === 0) {\r\n <div class=\"list-group-item text-muted text-center\">\r\n {{ noResultMessage }}\r\n </div>\r\n }\r\n <!-- ✅ حالت Virtual Scroll برای لیستهای بزرگ -->\r\n @else if (filteredItems.length > 100) {\r\n <cdk-virtual-scroll-viewport itemSize=\"36\" class=\"list-group w-100 overflow-y-auto\">\r\n <ul class=\"list-group w-100\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </cdk-virtual-scroll-viewport>\r\n }\r\n <!-- ✅ حالت معمولی برای لیستهای کوچک -->\r\n @else {\r\n <ul class=\"list-group w-100 overflow-y-auto\" [class.scrollable]=\"infiniteScroll\" (scroll)=\"onScroll($event)\">\r\n @for (item of filteredItems; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n\r\n</div>","/*\r\n * Public API Surface of ys-autocomplete\r\n */\r\n\r\nexport * from './src/ys-autocomplete/ys-autocomplete.component';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|