@bootkit/ng0 0.0.0-alpha.21 → 0.0.0-alpha.23
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/common/index.d.ts +125 -7
- package/components/dropdown/index.d.ts +87 -25
- package/components/list/index.d.ts +138 -45
- package/components/select/index.d.ts +32 -25
- package/data/index.d.ts +25 -122
- package/fesm2022/bootkit-ng0-common.mjs +145 -11
- package/fesm2022/bootkit-ng0-common.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-components-dropdown.mjs +208 -95
- package/fesm2022/bootkit-ng0-components-dropdown.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-components-list.mjs +287 -144
- package/fesm2022/bootkit-ng0-components-list.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-components-select.mjs +168 -236
- package/fesm2022/bootkit-ng0-components-select.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-data.mjs +49 -114
- package/fesm2022/bootkit-ng0-data.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-localization-locales.mjs +2 -16
- package/fesm2022/bootkit-ng0-localization-locales.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-localization.mjs +42 -44
- package/fesm2022/bootkit-ng0-localization.mjs.map +1 -1
- package/fesm2022/bootkit-ng0-routing.mjs +80 -0
- package/fesm2022/bootkit-ng0-routing.mjs.map +1 -0
- package/localization/index.d.ts +29 -23
- package/package.json +9 -5
- package/routing/index.d.ts +124 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, inject, DOCUMENT, DestroyRef, ElementRef, Renderer2, ChangeDetectorRef, input, booleanAttribute,
|
|
2
|
+
import { signal, inject, DOCUMENT, DestroyRef, ElementRef, Renderer2, ChangeDetectorRef, input, model, booleanAttribute, effect, computed, TemplateRef, forwardRef, HostListener, ContentChild, ViewChild, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
|
-
import { dataSourceAttribute,
|
|
6
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { dataSourceAttribute, DataRequest } from '@bootkit/ng0/data';
|
|
7
6
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
8
7
|
import * as i2 from '@angular/cdk/overlay';
|
|
9
8
|
import { Overlay, ViewportRuler, OverlayModule } from '@angular/cdk/overlay';
|
|
10
|
-
import { CssClassAttribute,
|
|
11
|
-
import { LocalizationService,
|
|
12
|
-
import * as i3 from '@
|
|
13
|
-
import {
|
|
9
|
+
import { defaultEqualityComparer, equalityComparerAttribute, defaultValueWriter, valueWriterAttribute, noopFilter, CssClassAttribute, sequentialIdGenerator, findValuesByComparer, findValueByComparer } from '@bootkit/ng0/common';
|
|
10
|
+
import { LocalizationService, defaultObjectFormatter, objectFormatterAttribute } from '@bootkit/ng0/localization';
|
|
11
|
+
import * as i3 from '@bootkit/ng0/components/list';
|
|
12
|
+
import { ListModule, ListComponent } from '@bootkit/ng0/components/list';
|
|
13
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Select component that allows users to choose an option from a dropdown list.
|
|
@@ -19,13 +19,13 @@ class SelectComponent {
|
|
|
19
19
|
_resizeObserver;
|
|
20
20
|
_resizeObserverInitialized = false;
|
|
21
21
|
_viewpoerRulerSubscription;
|
|
22
|
-
_cdkListboxValue = signal(undefined, ...(ngDevMode ? [{ debugName: "_cdkListboxValue" }] : []));
|
|
23
22
|
_filterElementRef;
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
_listComponent;
|
|
24
|
+
_changeCallback;
|
|
25
|
+
_touchCallback;
|
|
26
26
|
_options = signal([], ...(ngDevMode ? [{ debugName: "_options" }] : []));
|
|
27
27
|
_isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_isDisabled" }] : []));
|
|
28
|
-
_selectedOptionIndex = signal(-1
|
|
28
|
+
// protected readonly _selectedOptionIndex = signal<number>(-1);
|
|
29
29
|
_activeOptionIndex = signal(-1, ...(ngDevMode ? [{ debugName: "_activeOptionIndex" }] : []));
|
|
30
30
|
_optionTemplate;
|
|
31
31
|
_positionStrategy;
|
|
@@ -38,6 +38,7 @@ class SelectComponent {
|
|
|
38
38
|
_renderer = inject(Renderer2);
|
|
39
39
|
_viewportRuler = inject(ViewportRuler);
|
|
40
40
|
_changeDetector = inject(ChangeDetectorRef);
|
|
41
|
+
_activateSlectedItemEffectRef;
|
|
41
42
|
/**
|
|
42
43
|
* The data source for the select component.
|
|
43
44
|
* This can be an array of data, a function that returns an observable of data,
|
|
@@ -46,6 +47,10 @@ class SelectComponent {
|
|
|
46
47
|
source = input.required(...(ngDevMode ? [{ debugName: "source", transform: v => dataSourceAttribute(v) }] : [{
|
|
47
48
|
transform: v => dataSourceAttribute(v)
|
|
48
49
|
}]));
|
|
50
|
+
/**
|
|
51
|
+
* Value of the select component.
|
|
52
|
+
*/
|
|
53
|
+
value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
49
54
|
/**
|
|
50
55
|
* Indicates whether multi selection is enabled or not.
|
|
51
56
|
*/
|
|
@@ -59,24 +64,24 @@ class SelectComponent {
|
|
|
59
64
|
/**
|
|
60
65
|
* A custom comparer function or the name of a field for comparing two objects.
|
|
61
66
|
*/
|
|
62
|
-
compareBy = input(
|
|
63
|
-
transform:
|
|
67
|
+
compareBy = input(defaultEqualityComparer, ...(ngDevMode ? [{ debugName: "compareBy", transform: equalityComparerAttribute }] : [{
|
|
68
|
+
transform: equalityComparerAttribute
|
|
64
69
|
}]));
|
|
65
70
|
/**
|
|
66
71
|
* Custom format function to convert an item to a string for display.
|
|
67
72
|
* Default converts the item to a string using its toString method.
|
|
68
73
|
*/
|
|
69
|
-
formatBy = input(
|
|
70
|
-
transform:
|
|
74
|
+
formatBy = input(defaultObjectFormatter, ...(ngDevMode ? [{ debugName: "formatBy", transform: objectFormatterAttribute(this._ls.get()) }] : [{
|
|
75
|
+
transform: objectFormatterAttribute(this._ls.get())
|
|
71
76
|
}]));
|
|
72
77
|
/**
|
|
73
|
-
* Custom value
|
|
78
|
+
* Custom value writer function to extract the value of any object while writing values.
|
|
74
79
|
*/
|
|
75
|
-
writeBy = input(
|
|
76
|
-
transform:
|
|
80
|
+
writeBy = input(defaultValueWriter, ...(ngDevMode ? [{ debugName: "writeBy", transform: valueWriterAttribute }] : [{
|
|
81
|
+
transform: valueWriterAttribute
|
|
77
82
|
}]));
|
|
78
83
|
/**
|
|
79
|
-
* Indicates whether the
|
|
84
|
+
* Indicates whether the select component is filterable.
|
|
80
85
|
*/
|
|
81
86
|
filterable = input(false, ...(ngDevMode ? [{ debugName: "filterable", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
82
87
|
/**
|
|
@@ -87,248 +92,96 @@ class SelectComponent {
|
|
|
87
92
|
* Custom filter function to filter items based on a filter value.
|
|
88
93
|
* Default checks if the item contains the filter value (case-insensitive).
|
|
89
94
|
*/
|
|
90
|
-
filterBy = input(
|
|
95
|
+
filterBy = input(noopFilter, ...(ngDevMode ? [{ debugName: "filterBy" }] : []));
|
|
91
96
|
/**
|
|
92
|
-
* CSS class or classes to apply to the
|
|
97
|
+
* CSS class or classes to apply to the items.
|
|
93
98
|
*/
|
|
94
99
|
itemClass = input((item) => undefined, ...(ngDevMode ? [{ debugName: "itemClass", transform: CssClassAttribute }] : [{
|
|
95
100
|
transform: CssClassAttribute
|
|
96
101
|
}]));
|
|
102
|
+
/**
|
|
103
|
+
* Custom id generator function to generate unique ids for each item.
|
|
104
|
+
* Default generates sequential ids with the prefix 'ng0-select-item-'.
|
|
105
|
+
* If set to undefined, no ids will be generated.
|
|
106
|
+
*/
|
|
107
|
+
idGenerator = input(sequentialIdGenerator('ng0-select-item-'), ...(ngDevMode ? [{ debugName: "idGenerator" }] : []));
|
|
97
108
|
constructor() {
|
|
98
109
|
this._renderer.addClass(this._el.nativeElement, 'form-select');
|
|
99
110
|
this._renderer.setAttribute(this._el.nativeElement, 'tabindex', '0');
|
|
100
111
|
this._scrollStrategy = this._overlay.scrollStrategies.block();
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this._handleDataSourceChange();
|
|
105
|
-
}
|
|
106
|
-
_loadItems() {
|
|
107
|
-
var r = new DataRequest();
|
|
108
|
-
this.source().load(r).pipe(takeUntilDestroyed(this._destroyRef)).subscribe(res => {
|
|
109
|
-
this._insertOptions(0, ...res.data);
|
|
112
|
+
effect(() => {
|
|
113
|
+
var value = this.value(); // track value
|
|
114
|
+
this._changeCallback?.(value);
|
|
110
115
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
let options = this._options();
|
|
114
|
-
this.source().change.subscribe(e => {
|
|
115
|
-
e.changes.forEach(change => {
|
|
116
|
-
switch (change.type) {
|
|
117
|
-
case 'insert':
|
|
118
|
-
this._insertOptions(change.index, ...change.items);
|
|
119
|
-
break;
|
|
120
|
-
case 'replace':
|
|
121
|
-
options[change.index].value = change.value;
|
|
122
|
-
break;
|
|
123
|
-
case 'remove':
|
|
124
|
-
options.splice(change.index, change.count);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
116
|
+
effect(() => {
|
|
117
|
+
var value = this.open(); // track value
|
|
127
118
|
});
|
|
119
|
+
this._activateSlectedItemEffectRef = effect(() => {
|
|
120
|
+
var value = this.value(); // track value
|
|
121
|
+
var options = this._options(); // track options
|
|
122
|
+
if (!this.multiple() && this._activeOptionIndex() == -1 && options.length > 0) {
|
|
123
|
+
let index = options.findIndex(x => this.compareBy()(x, this.value()));
|
|
124
|
+
if (index > -1) {
|
|
125
|
+
this._activeOptionIndex.set(index);
|
|
126
|
+
this._activateSlectedItemEffectRef.destroy();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}, ...(ngDevMode ? [{ debugName: "_activateSlectedItemEffectRef" }] : []));
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (optionsCount == 0 || index < 0 || index > optionsCount - 1) {
|
|
135
|
-
throw new Error('Index out of range');
|
|
136
|
-
}
|
|
137
|
-
if (index == this._selectedOptionIndex()) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
let option = this._options()[index];
|
|
141
|
-
this._cdkListboxValue.set(this.writeBy()(option.value));
|
|
142
|
-
this._onChangeCallback(this._cdkListboxValue());
|
|
143
|
-
}
|
|
144
|
-
// /**
|
|
145
|
-
// * Sets an option as active
|
|
146
|
-
// */
|
|
147
|
-
// public active(index: number) {
|
|
148
|
-
// if (index < 0) {
|
|
149
|
-
// throw Error();
|
|
150
|
-
// }
|
|
151
|
-
// this._activeOptionIndex.set(index);
|
|
152
|
-
// if (this.open()) {
|
|
153
|
-
// this.scrollItemIntoView(this._activeOptionIndex(), 'nearest');
|
|
154
|
-
// }
|
|
155
|
-
// }
|
|
156
|
-
// /**
|
|
157
|
-
// * Scrolls the item at the specified index into view within the dropdown list.
|
|
158
|
-
// * @param index The index of the item to scroll into view.
|
|
159
|
-
// * @param position The vertical alignment of the item after scrolling.
|
|
160
|
-
// * Can be 'start', 'center', 'end', or 'nearest'.
|
|
161
|
-
// * Default is 'nearest'.
|
|
162
|
-
// * @param behavior The scrolling behavior.
|
|
163
|
-
// */
|
|
164
|
-
// public scrollItemIntoView(index: number, position?: ScrollLogicalPosition, behavior?: ScrollBehavior) {
|
|
165
|
-
// let item = this._options()[index];
|
|
166
|
-
// let elm = this._document.getElementById(item.id) as HTMLUListElement;
|
|
167
|
-
// elm!.scrollIntoView({ block: position, behavior: behavior });
|
|
168
|
-
// }
|
|
169
|
-
_insertOptions(index, ...items) {
|
|
170
|
-
// let filter = this.filterBy()()
|
|
171
|
-
var options = items.map(x => ({
|
|
172
|
-
id: this._getNextOptionId(),
|
|
173
|
-
value: x,
|
|
174
|
-
show: true
|
|
175
|
-
}));
|
|
176
|
-
if (Number.isInteger(index)) {
|
|
177
|
-
this._options().splice(index, 0, ...options);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
this._options().push(...options);
|
|
181
|
-
}
|
|
182
|
-
this._changeDetector.markForCheck();
|
|
131
|
+
ngOnInit() {
|
|
132
|
+
this.source().load(new DataRequest()).pipe(takeUntilDestroyed(this._destroyRef)).subscribe(res => {
|
|
133
|
+
this._options.set(res.data);
|
|
134
|
+
this._changeDetector.markForCheck();
|
|
135
|
+
});
|
|
183
136
|
}
|
|
184
137
|
writeValue(obj) {
|
|
185
|
-
|
|
186
|
-
if (this.multiple()) {
|
|
187
|
-
if (Array.isArray(obj)) {
|
|
188
|
-
value = obj;
|
|
189
|
-
}
|
|
190
|
-
else if (obj === null || obj === undefined) {
|
|
191
|
-
value = [];
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
throw Error('Provide an array or null as the value of ng0-select component.');
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
value = [obj];
|
|
199
|
-
}
|
|
200
|
-
this._cdkListboxValue.set(value);
|
|
201
|
-
// Update selection state of items
|
|
202
|
-
// let compareBy = this.compareBy();
|
|
203
|
-
// if (this.multiple()) {
|
|
204
|
-
// this._items().forEach(x => x.selected = (value as any[]).some(y => compareBy(x.value, y)));
|
|
205
|
-
// } else {
|
|
206
|
-
// this._items().forEach(x => x.selected = compareBy(x.value, value));
|
|
207
|
-
// }
|
|
138
|
+
this.value.set(obj);
|
|
208
139
|
}
|
|
209
140
|
registerOnChange(fn) {
|
|
210
|
-
this.
|
|
141
|
+
this._changeCallback = fn;
|
|
211
142
|
}
|
|
212
143
|
registerOnTouched(fn) {
|
|
213
|
-
this.
|
|
144
|
+
this._touchCallback = fn;
|
|
214
145
|
}
|
|
215
146
|
setDisabledState(isDisabled) {
|
|
216
147
|
this._isDisabled.set(isDisabled);
|
|
217
148
|
}
|
|
218
|
-
_onKeydown(e, firedByFilter = false) {
|
|
219
|
-
let open = this.open();
|
|
220
|
-
if (this._isDisabled())
|
|
221
|
-
return;
|
|
222
|
-
let optionsCount = this._options().length;
|
|
223
|
-
if (optionsCount == 0) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
switch (e.key) {
|
|
227
|
-
case 'ArrowDown':
|
|
228
|
-
if (open) {
|
|
229
|
-
if (this._activeOptionIndex() < optionsCount - 1) {
|
|
230
|
-
// this.active(this._activeOptionIndex() + 1);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
if (this._selectedOptionIndex() < optionsCount - 1) {
|
|
235
|
-
this._selectByIndex(this._selectedOptionIndex() + 1);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
e.preventDefault();
|
|
239
|
-
break;
|
|
240
|
-
case 'ArrowUp':
|
|
241
|
-
if (open) {
|
|
242
|
-
if (this._activeOptionIndex() > 0) {
|
|
243
|
-
// this.active(this._activeOptionIndex()! - 1);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
if (this._selectedOptionIndex() > 0) {
|
|
248
|
-
this._selectByIndex(this._selectedOptionIndex() - 1);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
e.preventDefault();
|
|
252
|
-
break;
|
|
253
|
-
case 'Enter':
|
|
254
|
-
if (open) {
|
|
255
|
-
if (this._activeOptionIndex() == this._selectedOptionIndex()) {
|
|
256
|
-
this.open.set(false);
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
this._selectByIndex(this._activeOptionIndex());
|
|
260
|
-
this.open.set(false);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
this.open.set(true);
|
|
265
|
-
}
|
|
266
|
-
e.preventDefault();
|
|
267
|
-
break;
|
|
268
|
-
case ' ':
|
|
269
|
-
if (!open) {
|
|
270
|
-
this.open.set(true);
|
|
271
|
-
}
|
|
272
|
-
e.preventDefault();
|
|
273
|
-
break;
|
|
274
|
-
case 'Escape':
|
|
275
|
-
this.open.set(false);
|
|
276
|
-
e.preventDefault();
|
|
277
|
-
break;
|
|
278
|
-
case 'Home':
|
|
279
|
-
if (open) {
|
|
280
|
-
// this.active(0);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
this._selectByIndex(0);
|
|
284
|
-
}
|
|
285
|
-
e.preventDefault();
|
|
286
|
-
break;
|
|
287
|
-
case 'End':
|
|
288
|
-
if (open) {
|
|
289
|
-
// this.active(optionsCount - 1);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
this._selectByIndex(optionsCount - 1);
|
|
293
|
-
}
|
|
294
|
-
e.preventDefault();
|
|
295
|
-
break;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
149
|
_onFilterBlur() {
|
|
299
150
|
// use setTimeout to allow next element receives the focus.
|
|
300
|
-
setTimeout(() => {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}, 0);
|
|
305
|
-
}
|
|
306
|
-
_filterItems(filter) {
|
|
307
|
-
let filterFunc = this.filterBy();
|
|
308
|
-
this._options().forEach(x => x.show = filterFunc(x.value, filter));
|
|
151
|
+
// setTimeout(() => {
|
|
152
|
+
// if (!this._el.nativeElement.matches(':focus')) {
|
|
153
|
+
// this.open.set(false);
|
|
154
|
+
// }
|
|
155
|
+
// }, 0);
|
|
309
156
|
}
|
|
310
157
|
_onOverlayAttach() {
|
|
311
|
-
this._activeOptionIndex.set(this._selectedOptionIndex());
|
|
312
158
|
this._listenToResizeEvents();
|
|
313
|
-
|
|
314
|
-
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
if (this.filterable()) {
|
|
315
161
|
this._filterElementRef?.nativeElement.focus();
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
162
|
+
}
|
|
163
|
+
if (this._activeOptionIndex() > -1) {
|
|
164
|
+
this._listComponent?.active(this._activeOptionIndex());
|
|
165
|
+
}
|
|
166
|
+
}, 0);
|
|
321
167
|
}
|
|
322
168
|
_onOverlayDetach() {
|
|
323
169
|
this._unlistenFromResizeEvents();
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
this._options().forEach(x => x.show = false);
|
|
327
|
-
}
|
|
170
|
+
this._el.nativeElement.focus();
|
|
171
|
+
this.open.set(false);
|
|
328
172
|
}
|
|
329
|
-
|
|
330
|
-
|
|
173
|
+
_onListSelectionChange(e) {
|
|
174
|
+
if (!this.multiple()) {
|
|
175
|
+
this._activeOptionIndex.set(e.index);
|
|
176
|
+
this.open.set(false);
|
|
177
|
+
}
|
|
331
178
|
}
|
|
179
|
+
// Find the value in options using the comparer function
|
|
180
|
+
_mappedValue = computed(() => {
|
|
181
|
+
return this.multiple() ?
|
|
182
|
+
findValuesByComparer(this._options(), this.value(), this.compareBy()) :
|
|
183
|
+
findValueByComparer(this._options(), this.value(), this.compareBy());
|
|
184
|
+
}, ...(ngDevMode ? [{ debugName: "_mappedValue" }] : []));
|
|
332
185
|
_listenToResizeEvents() {
|
|
333
186
|
this._viewportRuler.change().subscribe(x => {
|
|
334
187
|
this.open.set(false);
|
|
@@ -356,25 +209,101 @@ class SelectComponent {
|
|
|
356
209
|
this._resizeObserver = undefined;
|
|
357
210
|
this._resizeObserverInitialized = false;
|
|
358
211
|
}
|
|
359
|
-
|
|
212
|
+
_selectFirst() {
|
|
213
|
+
let optionsCount = this._options().length;
|
|
214
|
+
if (optionsCount > 0) {
|
|
215
|
+
this._activeOptionIndex.set(0);
|
|
216
|
+
let value = this.writeBy()(this._options()[this._activeOptionIndex()]);
|
|
217
|
+
this.value.set(value);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
_selectLast() {
|
|
221
|
+
let optionsCount = this._options().length;
|
|
222
|
+
if (optionsCount > 0) {
|
|
223
|
+
this._activeOptionIndex.set(optionsCount - 1);
|
|
224
|
+
let value = this.writeBy()(this._options()[this._activeOptionIndex()]);
|
|
225
|
+
this.value.set(value);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
_selectNext() {
|
|
229
|
+
let optionsCount = this._options().length;
|
|
230
|
+
if (this._activeOptionIndex() < optionsCount - 1) {
|
|
231
|
+
this._activeOptionIndex.update(x => x + 1);
|
|
232
|
+
let value = this.writeBy()(this._options()[this._activeOptionIndex()]);
|
|
233
|
+
this.value.set(value);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
_selectPrevious() {
|
|
237
|
+
// let optionsCount = this._options().length;
|
|
238
|
+
if (this._activeOptionIndex() > 0) {
|
|
239
|
+
this._activeOptionIndex.update(x => x - 1);
|
|
240
|
+
let value = this.writeBy()(this._options()[this._activeOptionIndex()]);
|
|
241
|
+
this.value.set(value);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
_onHostKeydown(e) {
|
|
360
245
|
if (this._isDisabled())
|
|
361
246
|
return;
|
|
362
|
-
this.
|
|
363
|
-
|
|
247
|
+
let optionsCount = this._options().length;
|
|
248
|
+
if (optionsCount == 0) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
if (this.open()) {
|
|
252
|
+
const newEvent = new KeyboardEvent(e.type, e);
|
|
253
|
+
this._listComponent?.elementRef.nativeElement.dispatchEvent(newEvent);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
switch (e.key) {
|
|
257
|
+
case 'ArrowDown':
|
|
258
|
+
if (this.multiple())
|
|
259
|
+
return;
|
|
260
|
+
this._selectNext();
|
|
261
|
+
e.preventDefault();
|
|
262
|
+
break;
|
|
263
|
+
case 'ArrowUp':
|
|
264
|
+
if (this.multiple())
|
|
265
|
+
return;
|
|
266
|
+
this._selectPrevious();
|
|
267
|
+
e.preventDefault();
|
|
268
|
+
break;
|
|
269
|
+
case 'Enter':
|
|
270
|
+
this.open.set(!this.open());
|
|
271
|
+
// e.preventDefault();
|
|
272
|
+
break;
|
|
273
|
+
case 'Home':
|
|
274
|
+
if (this.multiple())
|
|
275
|
+
return;
|
|
276
|
+
this._selectFirst();
|
|
277
|
+
e.preventDefault();
|
|
278
|
+
break;
|
|
279
|
+
case 'End':
|
|
280
|
+
if (this.multiple())
|
|
281
|
+
return;
|
|
282
|
+
this._selectLast();
|
|
283
|
+
e.preventDefault();
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
_onHostClick(e) {
|
|
289
|
+
if (!this._isDisabled()) {
|
|
290
|
+
this.open.update(x => !x);
|
|
291
|
+
// this._onTouchedCallback?.(this._selectedValue());
|
|
292
|
+
}
|
|
364
293
|
}
|
|
365
294
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
366
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: SelectComponent, isStandalone: true, selector: "ng0-select", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, compareBy: { classPropertyName: "compareBy", publicName: "compareBy", isSignal: true, isRequired: false, transformFunction: null }, formatBy: { classPropertyName: "formatBy", publicName: "formatBy", isSignal: true, isRequired: false, transformFunction: null }, writeBy: { classPropertyName: "writeBy", publicName: "writeBy", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { listeners: { "keydown": "
|
|
295
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: SelectComponent, isStandalone: true, selector: "ng0-select", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, compareBy: { classPropertyName: "compareBy", publicName: "compareBy", isSignal: true, isRequired: false, transformFunction: null }, formatBy: { classPropertyName: "formatBy", publicName: "formatBy", isSignal: true, isRequired: false, transformFunction: null }, writeBy: { classPropertyName: "writeBy", publicName: "writeBy", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, idGenerator: { classPropertyName: "idGenerator", publicName: "idGenerator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", open: "openChange" }, host: { listeners: { "keydown": "_onHostKeydown($event)", "click": "_onHostClick($event)" }, properties: { "class.ng0-select-open": "open()", "class.ng0-select-loading": "source().isLoading()", "attr.aria-activedescendant": "_activeOptionIndex() > -1 ? (_options()[_activeOptionIndex()].id) : undefined", "attr.disabled": "_isDisabled()", "attr.aria-disabled": "_isDisabled()" } }, providers: [{
|
|
367
296
|
provide: NG_VALUE_ACCESSOR,
|
|
368
297
|
useExisting: forwardRef(() => SelectComponent),
|
|
369
298
|
multi: true
|
|
370
|
-
}], queries: [{ propertyName: "_optionTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "_filterElementRef", first: true, predicate: ["filterInput"], descendants: true }], exportAs: ["ng0Select"], ngImport: i0, template: "@let formattedValue = formatBy()(
|
|
299
|
+
}], queries: [{ propertyName: "_optionTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "_filterElementRef", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "_listComponent", first: true, predicate: ListComponent, descendants: true }], exportAs: ["ng0Select"], ngImport: i0, template: "@let formattedValue = formatBy()(_mappedValue());\r\n\r\n@if(formattedValue == null || formattedValue == '') {\r\n \r\n}@else {\r\n{{formattedValue}}\r\n}\r\n\r\n@if(source().isLoading()) {\r\n<div class=\"spinner-border text-success spinner-border-sm ng0-select-spinner\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n</div>\r\n}\r\n\r\n<ng-template cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"_el.nativeElement\"\r\n [cdkConnectedOverlayScrollStrategy]=\"_scrollStrategy\"\r\n [cdkConnectedOverlayOpen]=\"open()\"\r\n [cdkConnectedOverlayPush]=\"false\"\r\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\r\n [cdkConnectedOverlayPanelClass]=\"['ng0-select-dropdown-container', 'shadow']\"\r\n [cdkConnectedOverlayWidth]=\"_el.nativeElement.clientWidth\"\r\n (overlayOutsideClick)=\"open.set(false)\"\r\n (attach)=\"_onOverlayAttach()\"\r\n (detach)=\"_onOverlayDetach()\">\r\n\r\n @if(filterable()) {\r\n <div class=\"ng0-select-filter-container border-bottom\">\r\n <input #filterInput\r\n type=\"text\"\r\n class=\"ng0-select-filter-input form-control form-control-sm\"\r\n [attr.placeholder]=\"filterPlaceholder()\"\r\n (blur)=\"_onFilterBlur()\"\r\n >\r\n </div>\r\n }\r\n\r\n <ng0-list #list\r\n [source]=\"source()\"\r\n \r\n [multiple]=\"multiple()\"\r\n [idGenerator]=\"idGenerator()\"\r\n [filterBy]=\"filterBy()\"\r\n [compareBy]=\"compareBy()\"\r\n focus=\"none\"\r\n style=\"border: none; border-radius: 0;\"\r\n (mousedown)=\"$event.preventDefault(); $event.stopImmediatePropagation()\"\r\n (click)=\"open.set(false)\"\r\n (selectionChange)=\"_onListSelectionChange($event)\">\r\n\r\n <ng-template let-option>\r\n @if(_optionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_optionTemplate; context: { $implicit: option}\" />\r\n }@else {\r\n {{formatBy()(option.value)}}\r\n }\r\n </ng-template>\r\n\r\n </ng0-list>\r\n</ng-template>", styles: ["ng0-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;display:flex!important;align-items:center}ng0-select.disabled{background-color:var(--bs-secondary-bg)}.ng0-select-dropdown-container{display:flex;flex-direction:column;background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius);padding:.5rem var(--bs-dropdown-padding-x);--ng0-select-item-padding-x: 1rem;--ng0-select-item-padding-y: .25rem}.ng0-select-dropdown-container ul.ng0-select-dropdown{list-style:none;border-start-start-radius:0;border-start-end-radius:0;padding:0!important;margin:0;flex-grow:1;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.4) transparent}.ng0-select-dropdown-container ul.ng0-select-dropdown.is-open{border-top:none}.ng0-select-dropdown-container ul.ng0-select-dropdown li{overflow:hidden;cursor:pointer;padding:var(--ng0-select-item-padding-y) var(--ng0-select-item-padding-x)}.ng0-select-dropdown-container ul.ng0-select-dropdown li:hover{background-color:var(--bs-tertiary-bg)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-selected{background-color:var(--bs-primary);color:var(--bs-light)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-active:not(.ng0-select-option-selected){background-color:var(--bs-gray-300);color:var(--bs-body)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-filtered{display:none!important}.ng0-select-dropdown-container .ng0-select-filter-container{padding:.5rem var(--ng0-select-item-padding-x);background-color:inherit}.ng0-select-dropdown-container .ng0-select-filter-container .ng0-select-filter-input{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: ListModule }, { kind: "component", type: i3.ListComponent, selector: "ng0-list", inputs: ["source", "multiple", "showSelectionIndicator", "compareBy", "formatBy", "writeBy", "filterBy", "itemClass", "focus", "idGenerator"], outputs: ["selectionChange"], exportAs: ["ng0List"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
371
300
|
}
|
|
372
301
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: SelectComponent, decorators: [{
|
|
373
302
|
type: Component,
|
|
374
303
|
args: [{ selector: 'ng0-select', exportAs: 'ng0Select', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
375
304
|
CommonModule,
|
|
376
305
|
OverlayModule,
|
|
377
|
-
|
|
306
|
+
ListModule,
|
|
378
307
|
], providers: [{
|
|
379
308
|
provide: NG_VALUE_ACCESSOR,
|
|
380
309
|
useExisting: forwardRef(() => SelectComponent),
|
|
@@ -385,14 +314,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
|
|
|
385
314
|
'[attr.aria-activedescendant]': '_activeOptionIndex() > -1 ? (_options()[_activeOptionIndex()].id) : undefined',
|
|
386
315
|
'[attr.disabled]': '_isDisabled()',
|
|
387
316
|
'[attr.aria-disabled]': '_isDisabled()'
|
|
388
|
-
}, template: "@let formattedValue = formatBy()(
|
|
317
|
+
}, template: "@let formattedValue = formatBy()(_mappedValue());\r\n\r\n@if(formattedValue == null || formattedValue == '') {\r\n \r\n}@else {\r\n{{formattedValue}}\r\n}\r\n\r\n@if(source().isLoading()) {\r\n<div class=\"spinner-border text-success spinner-border-sm ng0-select-spinner\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n</div>\r\n}\r\n\r\n<ng-template cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"_el.nativeElement\"\r\n [cdkConnectedOverlayScrollStrategy]=\"_scrollStrategy\"\r\n [cdkConnectedOverlayOpen]=\"open()\"\r\n [cdkConnectedOverlayPush]=\"false\"\r\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\r\n [cdkConnectedOverlayPanelClass]=\"['ng0-select-dropdown-container', 'shadow']\"\r\n [cdkConnectedOverlayWidth]=\"_el.nativeElement.clientWidth\"\r\n (overlayOutsideClick)=\"open.set(false)\"\r\n (attach)=\"_onOverlayAttach()\"\r\n (detach)=\"_onOverlayDetach()\">\r\n\r\n @if(filterable()) {\r\n <div class=\"ng0-select-filter-container border-bottom\">\r\n <input #filterInput\r\n type=\"text\"\r\n class=\"ng0-select-filter-input form-control form-control-sm\"\r\n [attr.placeholder]=\"filterPlaceholder()\"\r\n (blur)=\"_onFilterBlur()\"\r\n >\r\n </div>\r\n }\r\n\r\n <ng0-list #list\r\n [source]=\"source()\"\r\n \r\n [multiple]=\"multiple()\"\r\n [idGenerator]=\"idGenerator()\"\r\n [filterBy]=\"filterBy()\"\r\n [compareBy]=\"compareBy()\"\r\n focus=\"none\"\r\n style=\"border: none; border-radius: 0;\"\r\n (mousedown)=\"$event.preventDefault(); $event.stopImmediatePropagation()\"\r\n (click)=\"open.set(false)\"\r\n (selectionChange)=\"_onListSelectionChange($event)\">\r\n\r\n <ng-template let-option>\r\n @if(_optionTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_optionTemplate; context: { $implicit: option}\" />\r\n }@else {\r\n {{formatBy()(option.value)}}\r\n }\r\n </ng-template>\r\n\r\n </ng0-list>\r\n</ng-template>", styles: ["ng0-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;display:flex!important;align-items:center}ng0-select.disabled{background-color:var(--bs-secondary-bg)}.ng0-select-dropdown-container{display:flex;flex-direction:column;background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius);padding:.5rem var(--bs-dropdown-padding-x);--ng0-select-item-padding-x: 1rem;--ng0-select-item-padding-y: .25rem}.ng0-select-dropdown-container ul.ng0-select-dropdown{list-style:none;border-start-start-radius:0;border-start-end-radius:0;padding:0!important;margin:0;flex-grow:1;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.4) transparent}.ng0-select-dropdown-container ul.ng0-select-dropdown.is-open{border-top:none}.ng0-select-dropdown-container ul.ng0-select-dropdown li{overflow:hidden;cursor:pointer;padding:var(--ng0-select-item-padding-y) var(--ng0-select-item-padding-x)}.ng0-select-dropdown-container ul.ng0-select-dropdown li:hover{background-color:var(--bs-tertiary-bg)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-selected{background-color:var(--bs-primary);color:var(--bs-light)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-active:not(.ng0-select-option-selected){background-color:var(--bs-gray-300);color:var(--bs-body)}.ng0-select-dropdown-container ul.ng0-select-dropdown li.ng0-select-option-filtered{display:none!important}.ng0-select-dropdown-container .ng0-select-filter-container{padding:.5rem var(--ng0-select-item-padding-x);background-color:inherit}.ng0-select-dropdown-container .ng0-select-filter-container .ng0-select-filter-input{width:100%}\n"] }]
|
|
389
318
|
}], ctorParameters: () => [], propDecorators: { _filterElementRef: [{
|
|
390
319
|
type: ViewChild,
|
|
391
320
|
args: ['filterInput']
|
|
321
|
+
}], _listComponent: [{
|
|
322
|
+
type: ViewChild,
|
|
323
|
+
args: [ListComponent]
|
|
392
324
|
}], _optionTemplate: [{
|
|
393
325
|
type: ContentChild,
|
|
394
326
|
args: [TemplateRef]
|
|
395
|
-
}],
|
|
327
|
+
}], _onHostKeydown: [{
|
|
396
328
|
type: HostListener,
|
|
397
329
|
args: ['keydown', ['$event']]
|
|
398
330
|
}], _onHostClick: [{
|