@skyux/lookup 5.7.2 → 6.0.0-beta.2
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/documentation.json +2 -2
- package/esm2020/index.mjs +32 -0
- package/esm2020/lib/modules/autocomplete/autocomplete-adapter.service.mjs +61 -0
- package/esm2020/lib/modules/autocomplete/autocomplete-default-search-function.mjs +39 -0
- package/esm2020/lib/modules/autocomplete/autocomplete-input.directive.mjs +221 -0
- package/esm2020/lib/modules/autocomplete/autocomplete-search-async-disabled.pipe.mjs +19 -0
- package/esm2020/lib/modules/autocomplete/autocomplete.component.mjs +739 -0
- package/esm2020/lib/modules/autocomplete/autocomplete.module.mjs +65 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-default-search-function-options.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-input-text-change.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-message-type.mjs +15 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-message.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-async-args.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-async-function.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-async-result-display-type.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-async-result.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-function-filter.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-function-response.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-search-function.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-selection-change.mjs +2 -0
- package/esm2020/lib/modules/autocomplete/types/autocomplete-show-more-args.mjs +2 -0
- package/esm2020/lib/modules/country-field/country-field.component.mjs +397 -0
- package/esm2020/lib/modules/country-field/country-field.module.mjs +49 -0
- package/esm2020/lib/modules/country-field/types/country.mjs +2 -0
- package/esm2020/lib/modules/lookup/lookup-adapter.service.mjs +21 -0
- package/esm2020/lib/modules/lookup/lookup-autocomplete-adapter.mjs +78 -0
- package/esm2020/lib/modules/lookup/lookup-item-selected.pipe.mjs +16 -0
- package/esm2020/lib/modules/lookup/lookup-show-more-async-modal.component.mjs +181 -0
- package/esm2020/lib/modules/lookup/lookup-show-more-modal.component.mjs +249 -0
- package/esm2020/lib/modules/lookup/lookup.component.mjs +601 -0
- package/esm2020/lib/modules/lookup/lookup.module.mjs +90 -0
- package/esm2020/lib/modules/lookup/types/lookup-add-click-callback-args.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-add-click-event-args.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-select-mode-type.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-select-mode.mjs +16 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-config.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-custom-picker-context.mjs +7 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-custom-picker.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-native-picker-async-context.mjs +7 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-native-picker-config.mjs +2 -0
- package/esm2020/lib/modules/lookup/types/lookup-show-more-native-picker-context.mjs +7 -0
- package/esm2020/lib/modules/search/search-adapter.service.mjs +45 -0
- package/esm2020/lib/modules/search/search.component.mjs +253 -0
- package/esm2020/lib/modules/search/search.module.mjs +46 -0
- package/esm2020/lib/modules/shared/sky-lookup-resources.module.mjs +72 -0
- package/esm2020/lib/modules/shared/sky-lookup-string-utils.mjs +8 -0
- package/esm2020/skyux-lookup.mjs +5 -0
- package/esm2020/testing/country-field/country-field-fixture.mjs +114 -0
- package/esm2020/testing/country-field/country-field-testing.module.mjs +15 -0
- package/esm2020/testing/public-api.mjs +5 -0
- package/esm2020/testing/search/search-fixture.mjs +57 -0
- package/esm2020/testing/search/search-testing.module.mjs +15 -0
- package/esm2020/testing/skyux-lookup-testing.mjs +5 -0
- package/fesm2015/{skyux-lookup-testing.js → skyux-lookup-testing.mjs} +9 -9
- package/fesm2015/skyux-lookup-testing.mjs.map +1 -0
- package/fesm2015/skyux-lookup.mjs +3153 -0
- package/fesm2015/skyux-lookup.mjs.map +1 -0
- package/fesm2020/skyux-lookup-testing.mjs +203 -0
- package/fesm2020/skyux-lookup-testing.mjs.map +1 -0
- package/fesm2020/skyux-lookup.mjs +3144 -0
- package/fesm2020/skyux-lookup.mjs.map +1 -0
- package/package.json +45 -21
- package/testing/package.json +5 -5
- package/bundles/skyux-lookup-testing.umd.js +0 -620
- package/bundles/skyux-lookup.umd.js +0 -3793
- package/esm2015/index.js +0 -32
- package/esm2015/index.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete-adapter.service.js +0 -61
- package/esm2015/lib/modules/autocomplete/autocomplete-adapter.service.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete-default-search-function.js +0 -39
- package/esm2015/lib/modules/autocomplete/autocomplete-default-search-function.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete-input.directive.js +0 -221
- package/esm2015/lib/modules/autocomplete/autocomplete-input.directive.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete-search-async-disabled.pipe.js +0 -19
- package/esm2015/lib/modules/autocomplete/autocomplete-search-async-disabled.pipe.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete.component.js +0 -745
- package/esm2015/lib/modules/autocomplete/autocomplete.component.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/autocomplete.module.js +0 -65
- package/esm2015/lib/modules/autocomplete/autocomplete.module.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-default-search-function-options.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-default-search-function-options.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-input-text-change.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-input-text-change.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-message-type.js +0 -15
- package/esm2015/lib/modules/autocomplete/types/autocomplete-message-type.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-message.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-message.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-args.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-args.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-function.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-function.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-result-display-type.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-result-display-type.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-result.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-async-result.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function-filter.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function-filter.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function-response.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function-response.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-search-function.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-selection-change.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-selection-change.js.map +0 -1
- package/esm2015/lib/modules/autocomplete/types/autocomplete-show-more-args.js +0 -2
- package/esm2015/lib/modules/autocomplete/types/autocomplete-show-more-args.js.map +0 -1
- package/esm2015/lib/modules/country-field/country-field.component.js +0 -404
- package/esm2015/lib/modules/country-field/country-field.component.js.map +0 -1
- package/esm2015/lib/modules/country-field/country-field.module.js +0 -49
- package/esm2015/lib/modules/country-field/country-field.module.js.map +0 -1
- package/esm2015/lib/modules/country-field/types/country.js +0 -2
- package/esm2015/lib/modules/country-field/types/country.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup-adapter.service.js +0 -21
- package/esm2015/lib/modules/lookup/lookup-adapter.service.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup-autocomplete-adapter.js +0 -78
- package/esm2015/lib/modules/lookup/lookup-autocomplete-adapter.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup-item-selected.pipe.js +0 -16
- package/esm2015/lib/modules/lookup/lookup-item-selected.pipe.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup-show-more-async-modal.component.js +0 -186
- package/esm2015/lib/modules/lookup/lookup-show-more-async-modal.component.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup-show-more-modal.component.js +0 -258
- package/esm2015/lib/modules/lookup/lookup-show-more-modal.component.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup.component.js +0 -610
- package/esm2015/lib/modules/lookup/lookup.component.js.map +0 -1
- package/esm2015/lib/modules/lookup/lookup.module.js +0 -94
- package/esm2015/lib/modules/lookup/lookup.module.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-add-click-callback-args.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-add-click-callback-args.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-add-click-event-args.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-add-click-event-args.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-select-mode-type.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-select-mode-type.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-select-mode.js +0 -16
- package/esm2015/lib/modules/lookup/types/lookup-select-mode.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-config.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-show-more-config.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-custom-picker-context.js +0 -7
- package/esm2015/lib/modules/lookup/types/lookup-show-more-custom-picker-context.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-custom-picker.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-show-more-custom-picker.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-async-context.js +0 -7
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-async-context.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-config.js +0 -2
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-config.js.map +0 -1
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-context.js +0 -7
- package/esm2015/lib/modules/lookup/types/lookup-show-more-native-picker-context.js.map +0 -1
- package/esm2015/lib/modules/search/search-adapter.service.js +0 -45
- package/esm2015/lib/modules/search/search-adapter.service.js.map +0 -1
- package/esm2015/lib/modules/search/search.component.js +0 -260
- package/esm2015/lib/modules/search/search.component.js.map +0 -1
- package/esm2015/lib/modules/search/search.module.js +0 -46
- package/esm2015/lib/modules/search/search.module.js.map +0 -1
- package/esm2015/lib/modules/shared/sky-lookup-resources.module.js +0 -72
- package/esm2015/lib/modules/shared/sky-lookup-resources.module.js.map +0 -1
- package/esm2015/lib/modules/shared/sky-lookup-string-utils.js +0 -8
- package/esm2015/lib/modules/shared/sky-lookup-string-utils.js.map +0 -1
- package/esm2015/skyux-lookup.js +0 -5
- package/esm2015/skyux-lookup.js.map +0 -1
- package/esm2015/testing/country-field/country-field-fixture.js +0 -123
- package/esm2015/testing/country-field/country-field-fixture.js.map +0 -1
- package/esm2015/testing/country-field/country-field-testing.module.js +0 -15
- package/esm2015/testing/country-field/country-field-testing.module.js.map +0 -1
- package/esm2015/testing/public-api.js +0 -5
- package/esm2015/testing/public-api.js.map +0 -1
- package/esm2015/testing/search/search-fixture.js +0 -57
- package/esm2015/testing/search/search-fixture.js.map +0 -1
- package/esm2015/testing/search/search-testing.module.js +0 -15
- package/esm2015/testing/search/search-testing.module.js.map +0 -1
- package/esm2015/testing/skyux-lookup-testing.js +0 -5
- package/esm2015/testing/skyux-lookup-testing.js.map +0 -1
- package/fesm2015/skyux-lookup-testing.js.map +0 -1
- package/fesm2015/skyux-lookup.js +0 -3191
- package/fesm2015/skyux-lookup.js.map +0 -1
|
@@ -1,745 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, Input, Optional, Output, TemplateRef, ViewChild, } from '@angular/core';
|
|
2
|
-
import { SkyAffixAutoFitContext, SkyAffixService, SkyOverlayService, } from '@skyux/core';
|
|
3
|
-
import { SkyInputBoxHostService } from '@skyux/forms';
|
|
4
|
-
import { Subject, from, fromEvent as observableFromEvent, of, } from 'rxjs';
|
|
5
|
-
import { debounceTime, map, switchMap, take, takeUntil } from 'rxjs/operators';
|
|
6
|
-
import { normalizeDiacritics } from '../shared/sky-lookup-string-utils';
|
|
7
|
-
import { SkyAutocompleteAdapterService } from './autocomplete-adapter.service';
|
|
8
|
-
import { skyAutocompleteDefaultSearchFunction } from './autocomplete-default-search-function';
|
|
9
|
-
import { SkyAutocompleteInputDirective } from './autocomplete-input.directive';
|
|
10
|
-
import { SkyAutocompleteMessageType } from './types/autocomplete-message-type';
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
import * as i1 from "@skyux/core";
|
|
13
|
-
import * as i2 from "./autocomplete-adapter.service";
|
|
14
|
-
import * as i3 from "@skyux/forms";
|
|
15
|
-
import * as i4 from "@skyux/indicators";
|
|
16
|
-
import * as i5 from "@skyux/theme";
|
|
17
|
-
import * as i6 from "@angular/common";
|
|
18
|
-
import * as i7 from "@skyux/i18n";
|
|
19
|
-
import * as i8 from "./autocomplete-search-async-disabled.pipe";
|
|
20
|
-
let uniqueId = 0;
|
|
21
|
-
export class SkyAutocompleteComponent {
|
|
22
|
-
constructor(changeDetector, elementRef, affixService, adapterService, overlayService, inputBoxHostSvc) {
|
|
23
|
-
this.changeDetector = changeDetector;
|
|
24
|
-
this.elementRef = elementRef;
|
|
25
|
-
this.affixService = affixService;
|
|
26
|
-
this.adapterService = adapterService;
|
|
27
|
-
this.overlayService = overlayService;
|
|
28
|
-
this.inputBoxHostSvc = inputBoxHostSvc;
|
|
29
|
-
/**
|
|
30
|
-
* @internal
|
|
31
|
-
* Indicates whether to display a button in the dropdown that opens a picker where users can view all options.
|
|
32
|
-
*/
|
|
33
|
-
this.enableShowMore = false;
|
|
34
|
-
/**
|
|
35
|
-
* @internal
|
|
36
|
-
* Indicates whether to display a button that lets users add options to the data source.
|
|
37
|
-
*/
|
|
38
|
-
this.showAddButton = false;
|
|
39
|
-
/**
|
|
40
|
-
* @internal
|
|
41
|
-
* Allows async search to be disabled even when a listener is specified for
|
|
42
|
-
* the `searchAsync` output.
|
|
43
|
-
*/
|
|
44
|
-
this.searchAsyncDisabled = false;
|
|
45
|
-
/**
|
|
46
|
-
* @internal
|
|
47
|
-
* Fires when users select the button to add options to the data source.
|
|
48
|
-
*/
|
|
49
|
-
this.addClick = new EventEmitter();
|
|
50
|
-
/**
|
|
51
|
-
* @internal
|
|
52
|
-
* Fires when users select the button to view all options.
|
|
53
|
-
*/
|
|
54
|
-
this.showMoreClick = new EventEmitter();
|
|
55
|
-
/**
|
|
56
|
-
* Fires when users enter new search information and allows results to be
|
|
57
|
-
* returned via an observable.
|
|
58
|
-
*/
|
|
59
|
-
this.searchAsync = new EventEmitter();
|
|
60
|
-
this.isOpen = false;
|
|
61
|
-
this.isSearchingAsync = false;
|
|
62
|
-
/**
|
|
63
|
-
* Index that indicates which descendant of the overlay currently has focus.
|
|
64
|
-
*/
|
|
65
|
-
this.activeElementIndex = -1;
|
|
66
|
-
this.inputDirectiveUnsubscribe = new Subject();
|
|
67
|
-
this.ngUnsubscribe = new Subject();
|
|
68
|
-
/**
|
|
69
|
-
* Elements within the autocomplete dropdown that are focusable.
|
|
70
|
-
* These are typically the search results and action buttons, but could also be
|
|
71
|
-
* elements provided in the consumer's own template.
|
|
72
|
-
*/
|
|
73
|
-
this.overlayFocusableElements = [];
|
|
74
|
-
this._selectionChange = new EventEmitter();
|
|
75
|
-
const id = ++uniqueId;
|
|
76
|
-
this.resultsListId = `sky-autocomplete-list-${id}`;
|
|
77
|
-
this.resultsWrapperId = `sky-autocomplete-wrapper-${id}`;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Specifies a static data source for the autocomplete component to search
|
|
81
|
-
* when users enter text. For a dynamic data source such as an array that
|
|
82
|
-
* changes due to server calls, use `search` or `searchAsync` instead.
|
|
83
|
-
*/
|
|
84
|
-
set data(value) {
|
|
85
|
-
this._data = value;
|
|
86
|
-
}
|
|
87
|
-
get data() {
|
|
88
|
-
return this._data || [];
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Specifies how many milliseconds to wait before searching while users
|
|
92
|
-
* enter text in the autocomplete field.
|
|
93
|
-
* @default 0
|
|
94
|
-
*/
|
|
95
|
-
set debounceTime(value) {
|
|
96
|
-
this._debounceTime = value;
|
|
97
|
-
}
|
|
98
|
-
get debounceTime() {
|
|
99
|
-
return this._debounceTime || 0;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Specifies an object property to display in the text input after users
|
|
103
|
-
* select an item in the dropdown list.
|
|
104
|
-
* @default "name"
|
|
105
|
-
*/
|
|
106
|
-
set descriptorProperty(value) {
|
|
107
|
-
this._descriptorProperty = value;
|
|
108
|
-
}
|
|
109
|
-
get descriptorProperty() {
|
|
110
|
-
return this._descriptorProperty || 'name';
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Specifies an observable of `SkyAutocompleteMessage` that can close the dropdown.
|
|
114
|
-
* @internal
|
|
115
|
-
*/
|
|
116
|
-
set messageStream(value) {
|
|
117
|
-
this._messageStream = value;
|
|
118
|
-
this.initMessageStream();
|
|
119
|
-
}
|
|
120
|
-
get messageStream() {
|
|
121
|
-
return this._messageStream;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Specifies the object properties to search.
|
|
125
|
-
* @default ["name"]
|
|
126
|
-
*/
|
|
127
|
-
set propertiesToSearch(value) {
|
|
128
|
-
this._propertiesToSearch = value;
|
|
129
|
-
}
|
|
130
|
-
get propertiesToSearch() {
|
|
131
|
-
return this._propertiesToSearch || ['name'];
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Specifies a function to dynamically manage the data source when users
|
|
135
|
-
* change the text in the autocomplete field. The search function must return
|
|
136
|
-
* an array or a promise of an array. The `search` property is particularly
|
|
137
|
-
* useful when the data source does not live in the source code. If the
|
|
138
|
-
* search requires calling a remote data source, use `searchAsync` instead of
|
|
139
|
-
* `search`.
|
|
140
|
-
*/
|
|
141
|
-
set search(value) {
|
|
142
|
-
this._search = value;
|
|
143
|
-
}
|
|
144
|
-
get search() {
|
|
145
|
-
return (this._search ||
|
|
146
|
-
skyAutocompleteDefaultSearchFunction({
|
|
147
|
-
propertiesToSearch: this.propertiesToSearch,
|
|
148
|
-
searchFilters: this.searchFilters,
|
|
149
|
-
}));
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Specifies a template to format each search result in the dropdown list.
|
|
153
|
-
* The autocomplete component injects search result values into the template
|
|
154
|
-
* as `item` variables that reference all of the object properties of the search results.
|
|
155
|
-
*/
|
|
156
|
-
set searchResultTemplate(value) {
|
|
157
|
-
this._searchResultTemplate = value;
|
|
158
|
-
}
|
|
159
|
-
get searchResultTemplate() {
|
|
160
|
-
return this._searchResultTemplate || this.defaultSearchResultTemplate;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Specifies the minimum number of characters that users must enter before
|
|
164
|
-
* the autocomplete component searches the data source and displays search
|
|
165
|
-
* results in the dropdown list.
|
|
166
|
-
* @default 1
|
|
167
|
-
*/
|
|
168
|
-
set searchTextMinimumCharacters(value) {
|
|
169
|
-
this._searchTextMinimumCharacters = value;
|
|
170
|
-
}
|
|
171
|
-
get searchTextMinimumCharacters() {
|
|
172
|
-
return this._searchTextMinimumCharacters > 0
|
|
173
|
-
? this._searchTextMinimumCharacters
|
|
174
|
-
: 1;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Specifies the maximum number of search results to display in the dropdown list.
|
|
178
|
-
* By default, the component displays all matching results.
|
|
179
|
-
*/
|
|
180
|
-
set searchResultsLimit(value) {
|
|
181
|
-
this._searchResultsLimit = value;
|
|
182
|
-
}
|
|
183
|
-
get searchResultsLimit() {
|
|
184
|
-
if (this._searchResultsLimit) {
|
|
185
|
-
return this._searchResultsLimit;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
return this.enableShowMore ? 5 : this._searchResultsLimit;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Fires when users select items in the dropdown list.
|
|
193
|
-
*/
|
|
194
|
-
get selectionChange() {
|
|
195
|
-
return this._selectionChange;
|
|
196
|
-
}
|
|
197
|
-
//#endregion
|
|
198
|
-
//#region template_properties
|
|
199
|
-
get searchResults() {
|
|
200
|
-
return this._searchResults || [];
|
|
201
|
-
}
|
|
202
|
-
get highlightText() {
|
|
203
|
-
return this._highlightText || [];
|
|
204
|
-
}
|
|
205
|
-
get showActionsArea() {
|
|
206
|
-
return this.showAddButton || this.enableShowMore;
|
|
207
|
-
}
|
|
208
|
-
set inputDirective(directive) {
|
|
209
|
-
if (this._inputDirective !== directive) {
|
|
210
|
-
if (!directive) {
|
|
211
|
-
throw Error([
|
|
212
|
-
'The SkyAutocompleteComponent requires a ContentChild input or',
|
|
213
|
-
'textarea bound with the SkyAutocomplete directive. For example:',
|
|
214
|
-
'`<input type="text" skyAutocomplete>`.',
|
|
215
|
-
].join(' '));
|
|
216
|
-
}
|
|
217
|
-
// Unsubscribe from old subscriptions on any previous input directive
|
|
218
|
-
this.inputDirectiveUnsubscribe.next();
|
|
219
|
-
this._inputDirective = directive;
|
|
220
|
-
this._inputDirective.displayWith = this.descriptorProperty;
|
|
221
|
-
this._inputDirective.textChanges
|
|
222
|
-
.pipe(takeUntil(this.inputDirectiveUnsubscribe), debounceTime(this.debounceTime), switchMap((change) => {
|
|
223
|
-
this.isSearchingAsync = true;
|
|
224
|
-
return of(change);
|
|
225
|
-
}))
|
|
226
|
-
.subscribe((change) => {
|
|
227
|
-
this.searchTextChanged(change.value);
|
|
228
|
-
});
|
|
229
|
-
this._inputDirective.blur
|
|
230
|
-
.pipe(takeUntil(this.inputDirectiveUnsubscribe))
|
|
231
|
-
.subscribe(() => {
|
|
232
|
-
this.inputDirective.onTouched();
|
|
233
|
-
});
|
|
234
|
-
this._inputDirective.focus
|
|
235
|
-
.pipe(takeUntil(this.inputDirectiveUnsubscribe))
|
|
236
|
-
.subscribe(() => {
|
|
237
|
-
if (this.showActionsArea) {
|
|
238
|
-
this.openDropdown();
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
get inputDirective() {
|
|
244
|
-
return this._inputDirective;
|
|
245
|
-
}
|
|
246
|
-
set resultsRef(value) {
|
|
247
|
-
if (value) {
|
|
248
|
-
this._resultsRef = value;
|
|
249
|
-
this.destroyAffixer();
|
|
250
|
-
this.createAffixer();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
get resultsRef() {
|
|
254
|
-
return this._resultsRef;
|
|
255
|
-
}
|
|
256
|
-
ngAfterContentInit() {
|
|
257
|
-
if (!this.inputDirective) {
|
|
258
|
-
throw Error([
|
|
259
|
-
'The SkyAutocompleteComponent requires a ContentChild input or',
|
|
260
|
-
'textarea bound with the SkyAutocomplete directive. For example:',
|
|
261
|
-
'`<input type="text" skyAutocomplete>`.',
|
|
262
|
-
].join(' '));
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
ngAfterViewInit() {
|
|
266
|
-
this.addInputEventListeners();
|
|
267
|
-
}
|
|
268
|
-
ngOnDestroy() {
|
|
269
|
-
this.cancelCurrentSearch();
|
|
270
|
-
this.inputDirectiveUnsubscribe.next();
|
|
271
|
-
this.inputDirectiveUnsubscribe.complete();
|
|
272
|
-
this.ngUnsubscribe.next();
|
|
273
|
-
this.ngUnsubscribe.complete();
|
|
274
|
-
this.destroyAffixer();
|
|
275
|
-
this.destroyOverlay();
|
|
276
|
-
}
|
|
277
|
-
addButtonClicked() {
|
|
278
|
-
this.addClick.emit();
|
|
279
|
-
this.inputDirective.restoreInputTextValueToPreviousState();
|
|
280
|
-
this.closeDropdown();
|
|
281
|
-
}
|
|
282
|
-
handleKeydown(event) {
|
|
283
|
-
/* Sanity check */
|
|
284
|
-
/* istanbul ignore else */
|
|
285
|
-
if (event.key) {
|
|
286
|
-
const key = event.key.toLowerCase();
|
|
287
|
-
const activeElement = this.getActiveElement();
|
|
288
|
-
const activeElementId = activeElement === null || activeElement === void 0 ? void 0 : activeElement.id;
|
|
289
|
-
const targetIsSearchResult = this.searchResults.find((r) => r.elementId === activeElementId);
|
|
290
|
-
/* tslint:disable-next-line:switch-default */
|
|
291
|
-
switch (key) {
|
|
292
|
-
case 'enter':
|
|
293
|
-
if (targetIsSearchResult) {
|
|
294
|
-
this.selectSearchResultById(activeElementId);
|
|
295
|
-
if (!this.showActionsArea) {
|
|
296
|
-
this.closeDropdown();
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this.resetSearch();
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
if (activeElement) {
|
|
304
|
-
activeElement.click();
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
event.preventDefault();
|
|
308
|
-
event.stopPropagation();
|
|
309
|
-
break;
|
|
310
|
-
case 'tab':
|
|
311
|
-
if (targetIsSearchResult) {
|
|
312
|
-
this.selectSearchResultById(activeElementId);
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
this.inputDirective.restoreInputTextValueToPreviousState();
|
|
316
|
-
}
|
|
317
|
-
this.closeDropdown();
|
|
318
|
-
break;
|
|
319
|
-
case 'escape':
|
|
320
|
-
this.closeDropdown();
|
|
321
|
-
break;
|
|
322
|
-
case 'arrowdown':
|
|
323
|
-
case 'down':
|
|
324
|
-
this.removeFocusedClass();
|
|
325
|
-
if (this.activeElementIndex ===
|
|
326
|
-
this.overlayFocusableElements.length - 1 ||
|
|
327
|
-
this.activeElementIndex === -1) {
|
|
328
|
-
this.activeElementIndex = 0;
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
this.activeElementIndex = this.activeElementIndex + 1;
|
|
332
|
-
}
|
|
333
|
-
this.addFocusedClass();
|
|
334
|
-
this.changeDetector.markForCheck();
|
|
335
|
-
event.preventDefault();
|
|
336
|
-
event.stopPropagation();
|
|
337
|
-
break;
|
|
338
|
-
case 'arrowup':
|
|
339
|
-
case 'up':
|
|
340
|
-
this.removeFocusedClass();
|
|
341
|
-
if (this.activeElementIndex <= 0) {
|
|
342
|
-
this.activeElementIndex = this.overlayFocusableElements.length - 1;
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
this.activeElementIndex = this.activeElementIndex - 1;
|
|
346
|
-
}
|
|
347
|
-
this.addFocusedClass();
|
|
348
|
-
this.changeDetector.markForCheck();
|
|
349
|
-
event.preventDefault();
|
|
350
|
-
event.stopPropagation();
|
|
351
|
-
break;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
moreButtonClicked() {
|
|
356
|
-
this.showMoreClick.emit({ inputValue: this.searchText });
|
|
357
|
-
this.inputDirective.restoreInputTextValueToPreviousState();
|
|
358
|
-
this.closeDropdown();
|
|
359
|
-
}
|
|
360
|
-
onResultMouseDown(id, event) {
|
|
361
|
-
this.selectSearchResultById(id);
|
|
362
|
-
if (!this.showActionsArea) {
|
|
363
|
-
this.closeDropdown();
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
this.resetSearch();
|
|
367
|
-
}
|
|
368
|
-
event.preventDefault();
|
|
369
|
-
event.stopPropagation();
|
|
370
|
-
}
|
|
371
|
-
onResultMouseMove(id) {
|
|
372
|
-
if (id !== this.activeElementIndex) {
|
|
373
|
-
this.removeFocusedClass();
|
|
374
|
-
this.activeElementIndex = id;
|
|
375
|
-
this.addFocusedClass();
|
|
376
|
-
this.changeDetector.markForCheck();
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
isElementFocused(ref) {
|
|
380
|
-
return ref === this.overlayFocusableElements[this.activeElementIndex];
|
|
381
|
-
}
|
|
382
|
-
searchTextChanged(searchText) {
|
|
383
|
-
const isEmpty = !searchText || !searchText.trim() || searchText.match(/^\s+$/);
|
|
384
|
-
if (isEmpty) {
|
|
385
|
-
// Emit selectionChange if value has been cleared.
|
|
386
|
-
if (this.inputDirective.value) {
|
|
387
|
-
this.inputDirective.value = undefined;
|
|
388
|
-
this.selectionChange.emit({
|
|
389
|
-
selectedItem: undefined,
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
if (!this.showActionsArea) {
|
|
393
|
-
this.closeDropdown();
|
|
394
|
-
}
|
|
395
|
-
else {
|
|
396
|
-
this.resetSearch();
|
|
397
|
-
}
|
|
398
|
-
this.isSearchingAsync = false;
|
|
399
|
-
this.changeDetector.markForCheck();
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
const isLongEnough = searchText.length >= this.searchTextMinimumCharacters;
|
|
403
|
-
const isDifferent = searchText !== this.searchText;
|
|
404
|
-
this.searchText = searchText.trim();
|
|
405
|
-
if (isLongEnough && isDifferent) {
|
|
406
|
-
this.cancelCurrentSearch();
|
|
407
|
-
this.currentSearchSub = this.performSearch()
|
|
408
|
-
.pipe(take(1))
|
|
409
|
-
.subscribe((result) => {
|
|
410
|
-
const items = result.items.filter((item) => {
|
|
411
|
-
return item && this.descriptorProperty in item;
|
|
412
|
-
});
|
|
413
|
-
this.isSearchingAsync = false;
|
|
414
|
-
this._searchResults = items.map((r, i) => {
|
|
415
|
-
const result = {
|
|
416
|
-
elementId: `${this.resultsListId}-item-${i}`,
|
|
417
|
-
data: r,
|
|
418
|
-
};
|
|
419
|
-
return result;
|
|
420
|
-
});
|
|
421
|
-
this.searchResultsCount = result.totalCount;
|
|
422
|
-
this._highlightText = this.getHighlightText(this.searchText);
|
|
423
|
-
this.removeFocusedClass();
|
|
424
|
-
this.removeActiveDescendant();
|
|
425
|
-
if (this.searchResults.length > 0) {
|
|
426
|
-
this.activeElementIndex = 0;
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
this.activeElementIndex = -1;
|
|
430
|
-
}
|
|
431
|
-
this.changeDetector.markForCheck();
|
|
432
|
-
if (this.isOpen) {
|
|
433
|
-
// Let the results populate in the DOM before recalculating placement.
|
|
434
|
-
setTimeout(() => {
|
|
435
|
-
this.affixer.reaffix();
|
|
436
|
-
this.changeDetector.detectChanges();
|
|
437
|
-
this.initOverlayFocusableElements();
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
this.openDropdown();
|
|
442
|
-
this.changeDetector.markForCheck();
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
this.isSearchingAsync = false;
|
|
448
|
-
this.changeDetector.markForCheck();
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
performSearch() {
|
|
452
|
-
if (!this.searchAsyncDisabled && this.searchAsync.observers.length > 0) {
|
|
453
|
-
const searchAsyncArgs = {
|
|
454
|
-
displayType: 'popover',
|
|
455
|
-
offset: 0,
|
|
456
|
-
searchText: this.searchText,
|
|
457
|
-
};
|
|
458
|
-
this.searchAsync.emit(searchAsyncArgs);
|
|
459
|
-
return searchAsyncArgs.result;
|
|
460
|
-
}
|
|
461
|
-
const result = this.search(this.searchText, this.data);
|
|
462
|
-
if (result instanceof Array) {
|
|
463
|
-
return of({
|
|
464
|
-
items: result,
|
|
465
|
-
totalCount: result.length,
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
return from(result).pipe(map((items) => {
|
|
469
|
-
return {
|
|
470
|
-
items,
|
|
471
|
-
totalCount: items.length,
|
|
472
|
-
};
|
|
473
|
-
}));
|
|
474
|
-
}
|
|
475
|
-
cancelCurrentSearch() {
|
|
476
|
-
if (this.currentSearchSub) {
|
|
477
|
-
this.currentSearchSub.unsubscribe();
|
|
478
|
-
this.currentSearchSub = undefined;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Returns the text to highlight based on exact matches, case-insensitive matches, and matches for corresponding diacritical characters (a will match à).
|
|
483
|
-
*/
|
|
484
|
-
getHighlightText(searchText) {
|
|
485
|
-
const normalizedSearchText = normalizeDiacritics(searchText)
|
|
486
|
-
.toLocaleUpperCase()
|
|
487
|
-
.trim();
|
|
488
|
-
if (!normalizedSearchText) {
|
|
489
|
-
return [];
|
|
490
|
-
}
|
|
491
|
-
let matchesToHighlight = [];
|
|
492
|
-
for (let i = 0, n = this._searchResults.length; i < n; i++) {
|
|
493
|
-
const value = this._searchResults[i].data[this.descriptorProperty]
|
|
494
|
-
.toString()
|
|
495
|
-
.toLocaleUpperCase();
|
|
496
|
-
const normalizedDataValue = normalizeDiacritics(value);
|
|
497
|
-
let offset = 0;
|
|
498
|
-
let index;
|
|
499
|
-
while ((index = normalizedDataValue.indexOf(normalizedSearchText, offset)) > -1) {
|
|
500
|
-
const matchedString = value.slice(index, index + searchText.length);
|
|
501
|
-
offset = index + searchText.length;
|
|
502
|
-
matchesToHighlight = matchesToHighlight.concat(matchedString);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
// Remove any duplicates from the array.
|
|
506
|
-
return [...new Set(matchesToHighlight)];
|
|
507
|
-
}
|
|
508
|
-
selectSearchResultById(id) {
|
|
509
|
-
const result = this.searchResults.find((r) => r.elementId === id).data;
|
|
510
|
-
/* Sanity check */
|
|
511
|
-
/* istanbul ignore else */
|
|
512
|
-
if (result) {
|
|
513
|
-
this.searchText = result[this.descriptorProperty];
|
|
514
|
-
this.inputDirective.value = result;
|
|
515
|
-
this.selectionChange.emit({
|
|
516
|
-
selectedItem: result,
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
openDropdown() {
|
|
521
|
-
if (!this.overlay) {
|
|
522
|
-
const overlay = this.overlayService.create({
|
|
523
|
-
enableClose: false,
|
|
524
|
-
enablePointerEvents: true,
|
|
525
|
-
wrapperClass: this.wrapperClass,
|
|
526
|
-
});
|
|
527
|
-
overlay.attachTemplate(this.resultsTemplateRef);
|
|
528
|
-
this.overlay = overlay;
|
|
529
|
-
this.isOpen = true;
|
|
530
|
-
this.changeDetector.markForCheck();
|
|
531
|
-
this.initOverlayFocusableElements();
|
|
532
|
-
overlay.backdropClick
|
|
533
|
-
.pipe(takeUntil(this.ngUnsubscribe))
|
|
534
|
-
.subscribe(() => {
|
|
535
|
-
/* Sanity check as you should not be able to active the directive from the backdrop */
|
|
536
|
-
/* istanbul ignore else */
|
|
537
|
-
if (document.activeElement !== this.inputDirective.inputElement) {
|
|
538
|
-
this.inputDirective.restoreInputTextValueToPreviousState();
|
|
539
|
-
this.closeDropdown();
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
closeDropdown() {
|
|
545
|
-
this.resetSearch();
|
|
546
|
-
this.isOpen = false;
|
|
547
|
-
this.destroyOverlay();
|
|
548
|
-
this.removeActiveDescendant();
|
|
549
|
-
this.changeDetector.markForCheck();
|
|
550
|
-
}
|
|
551
|
-
setActiveDescendant() {
|
|
552
|
-
const activeElement = this.overlayFocusableElements[this.activeElementIndex];
|
|
553
|
-
/* Sanity check */
|
|
554
|
-
/* istanbul ignore else */
|
|
555
|
-
if (activeElement) {
|
|
556
|
-
this.inputDirective.setActiveDescendant(activeElement.id);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
removeActiveDescendant() {
|
|
560
|
-
/* tslint:disable-next-line:no-null-keyword */
|
|
561
|
-
this.inputDirective.setActiveDescendant(null);
|
|
562
|
-
}
|
|
563
|
-
resetSearch() {
|
|
564
|
-
this._searchResults = [];
|
|
565
|
-
this.searchText = '';
|
|
566
|
-
this._highlightText = [];
|
|
567
|
-
this.activeElementIndex = -1;
|
|
568
|
-
this.searchResultsCount = undefined;
|
|
569
|
-
this.removeActiveDescendant();
|
|
570
|
-
this.initOverlayFocusableElements();
|
|
571
|
-
this.changeDetector.markForCheck();
|
|
572
|
-
}
|
|
573
|
-
addInputEventListeners() {
|
|
574
|
-
const element = this.elementRef.nativeElement;
|
|
575
|
-
observableFromEvent(element, 'keydown')
|
|
576
|
-
.pipe(takeUntil(this.ngUnsubscribe))
|
|
577
|
-
.subscribe((event) => {
|
|
578
|
-
this.handleKeydown(event);
|
|
579
|
-
});
|
|
580
|
-
observableFromEvent(window, 'resize')
|
|
581
|
-
.pipe(takeUntil(this.ngUnsubscribe))
|
|
582
|
-
.subscribe(() => {
|
|
583
|
-
/* istanbul ignore else */
|
|
584
|
-
if (this.isOpen) {
|
|
585
|
-
this.adapterService.setDropdownWidth(this.elementRef, this.resultsRef, !!this.inputBoxHostSvc);
|
|
586
|
-
}
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
destroyOverlay() {
|
|
590
|
-
if (this.overlay) {
|
|
591
|
-
this.overlayService.close(this.overlay);
|
|
592
|
-
this.overlay = undefined;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
createAffixer() {
|
|
596
|
-
/* Sanity check */
|
|
597
|
-
/* istanbul ignore else */
|
|
598
|
-
if (!this.affixer) {
|
|
599
|
-
const affixer = this.affixService.createAffixer(this.resultsRef);
|
|
600
|
-
this.adapterService.setDropdownWidth(this.elementRef, this.resultsRef, !!this.inputBoxHostSvc);
|
|
601
|
-
affixer.affixTo(this.elementRef.nativeElement, {
|
|
602
|
-
autoFitContext: SkyAffixAutoFitContext.Viewport,
|
|
603
|
-
enableAutoFit: true,
|
|
604
|
-
isSticky: true,
|
|
605
|
-
placement: 'below',
|
|
606
|
-
horizontalAlignment: 'left',
|
|
607
|
-
});
|
|
608
|
-
this.affixer = affixer;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
destroyAffixer() {
|
|
612
|
-
if (this.affixer) {
|
|
613
|
-
this.affixer.destroy();
|
|
614
|
-
this.affixer = undefined;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
initMessageStream() {
|
|
618
|
-
/* istanbul ignore if */
|
|
619
|
-
if (this.messageStreamSub) {
|
|
620
|
-
this.messageStreamSub.unsubscribe();
|
|
621
|
-
}
|
|
622
|
-
if (this.messageStream) {
|
|
623
|
-
this.messageStreamSub = this.messageStream
|
|
624
|
-
.pipe(takeUntil(this.ngUnsubscribe))
|
|
625
|
-
.subscribe((message) => {
|
|
626
|
-
/* tslint:disable-next-line:switch-default */
|
|
627
|
-
switch (message.type) {
|
|
628
|
-
case SkyAutocompleteMessageType.CloseDropdown:
|
|
629
|
-
this.closeDropdown();
|
|
630
|
-
break;
|
|
631
|
-
case SkyAutocompleteMessageType.RepositionDropdown:
|
|
632
|
-
// Settimeout waits for changes in DOM (e.g., tokens being removed)
|
|
633
|
-
setTimeout(() => {
|
|
634
|
-
/* istanbul ignore else */
|
|
635
|
-
if (this.affixer) {
|
|
636
|
-
this.affixer.reaffix();
|
|
637
|
-
}
|
|
638
|
-
});
|
|
639
|
-
break;
|
|
640
|
-
}
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
initOverlayFocusableElements() {
|
|
645
|
-
// Wait for dropdown elements to render.
|
|
646
|
-
setTimeout(() => {
|
|
647
|
-
if (this.overlay) {
|
|
648
|
-
this.overlayFocusableElements =
|
|
649
|
-
this.adapterService.getOverlayFocusableElements(this.overlay);
|
|
650
|
-
this.overlayFocusableElements.forEach((el) => {
|
|
651
|
-
this.adapterService.setTabIndex(el, -1);
|
|
652
|
-
});
|
|
653
|
-
this.addFocusedClass();
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
getActiveElement() {
|
|
658
|
-
return this.overlayFocusableElements[this.activeElementIndex];
|
|
659
|
-
}
|
|
660
|
-
removeFocusedClass() {
|
|
661
|
-
if (this.activeElementIndex > -1) {
|
|
662
|
-
this.adapterService.removeCSSClass(this.overlayFocusableElements[this.activeElementIndex], 'sky-autocomplete-descendant-focus');
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
addFocusedClass() {
|
|
666
|
-
if (this.activeElementIndex > -1) {
|
|
667
|
-
this.adapterService.addCSSClass(this.overlayFocusableElements[this.activeElementIndex], 'sky-autocomplete-descendant-focus');
|
|
668
|
-
this.setActiveDescendant();
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
SkyAutocompleteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyAutocompleteComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.SkyAffixService }, { token: i2.SkyAutocompleteAdapterService }, { token: i1.SkyOverlayService }, { token: i3.SkyInputBoxHostService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
673
|
-
SkyAutocompleteComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyAutocompleteComponent, selector: "sky-autocomplete", inputs: { ariaLabelledBy: "ariaLabelledBy", data: "data", debounceTime: "debounceTime", descriptorProperty: "descriptorProperty", enableShowMore: "enableShowMore", messageStream: "messageStream", wrapperClass: "wrapperClass", propertiesToSearch: "propertiesToSearch", search: "search", searchResultTemplate: "searchResultTemplate", searchTextMinimumCharacters: "searchTextMinimumCharacters", searchFilters: "searchFilters", searchResultsLimit: "searchResultsLimit", showAddButton: "showAddButton", noResultsFoundText: "noResultsFoundText", searchAsyncDisabled: "searchAsyncDisabled" }, outputs: { addClick: "addClick", showMoreClick: "showMoreClick", selectionChange: "selectionChange", searchAsync: "searchAsync" }, providers: [SkyAutocompleteAdapterService], queries: [{ propertyName: "inputDirective", first: true, predicate: SkyAutocompleteInputDirective, descendants: true }], viewQueries: [{ propertyName: "defaultSearchResultTemplate", first: true, predicate: ["defaultSearchResultTemplate"], descendants: true, read: TemplateRef }, { propertyName: "resultsTemplateRef", first: true, predicate: ["resultsTemplateRef"], descendants: true, read: TemplateRef }, { propertyName: "resultsRef", first: true, predicate: ["resultsRef"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n class=\"sky-autocomplete\"\n role=\"combobox\"\n [attr.aria-expanded]=\"isOpen && searchText\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-owns]=\"isOpen ? resultsListId : null\"\n [attr.id]=\"resultsWrapperId\"\n>\n <ng-content></ng-content>\n</div>\n\n<ng-template #resultsTemplateRef>\n <div\n class=\"sky-autocomplete-results-container\"\n [skyThemeClass]=\"{\n 'sky-shadow': 'default',\n 'sky-elevation-4': 'modern'\n }\"\n (keydown)=\"handleKeydown($event)\"\n #resultsRef\n >\n <div\n *ngIf=\"isSearchingAsync; else resultControlsTemplateRef\"\n class=\"sky-autocomplete-results-waiting\"\n >\n <sky-wait [isWaiting]=\"true\"></sky-wait>\n </div>\n </div>\n</ng-template>\n\n<ng-template #resultControlsTemplateRef>\n <div\n *ngIf=\"searchText && (!showActionsArea || searchResults.length > 0)\"\n class=\"sky-autocomplete-results\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.id]=\"resultsListId\"\n >\n <ng-container *ngFor=\"let result of searchResults; let i = index\">\n <div\n *ngIf=\"!searchResultsLimit || i < searchResultsLimit\"\n class=\"sky-autocomplete-result\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isElementFocused(searchResultEl)\"\n [attr.id]=\"result.elementId\"\n [skyHighlight]=\"highlightText\"\n (mousedown)=\"onResultMouseDown(result.elementId, $event)\"\n (mousemove)=\"onResultMouseMove(i)\"\n #searchResultEl\n >\n <ng-container\n *ngTemplateOutlet=\"\n searchResultTemplate;\n context: { item: result.data }\n \"\n >\n </ng-container>\n </div>\n </ng-container>\n <div\n *ngIf=\"searchResults.length === 0\"\n class=\"sky-deemphasized sky-padding-squish-default\"\n >\n {{\n noResultsFoundText ||\n ('skyux_autocomplete_no_results' | skyLibResources)\n }}\n </div>\n </div>\n <div *ngIf=\"showActionsArea\" class=\"sky-autocomplete-actions\">\n <button\n *ngIf=\"enableShowMore && (!searchText || searchResults.length > 0)\"\n class=\"\n sky-autocomplete-action\n sky-autocomplete-action-more\n sky-btn\n sky-btn-link\n \"\n type=\"button\"\n (click)=\"moreButtonClicked()\"\n >\n <ng-container\n *ngIf=\"\n !(\n searchAsync\n | skyAutocompleteSearchAsyncDisabled: searchAsyncDisabled\n ) &&\n searchResults.length === 0 &&\n !searchText\n \"\n >\n {{ 'skyux_autocomplete_show_all' | skyLibResources }}\n </ng-container>\n <ng-container\n *ngIf=\"\n (searchAsync\n | skyAutocompleteSearchAsyncDisabled: searchAsyncDisabled) &&\n !searchText\n \"\n >\n {{\n 'skyux_autocomplete_show_all_count'\n | skyLibResources: (data.length | skyNumeric: { truncate: false })\n }}\n </ng-container>\n <ng-container *ngIf=\"searchText\">\n {{\n 'skyux_autocomplete_show_matches_count'\n | skyLibResources\n : (searchResultsCount === undefined\n ? data.length\n : (searchResultsCount | skyNumeric: { truncate: false }))\n }}\n </ng-container>\n </button>\n <div\n *ngIf=\"searchText && searchResults.length === 0\"\n class=\"sky-font-deemphasized sky-autocomplete-actions-no-results\"\n >\n {{\n noResultsFoundText ||\n ('skyux_autocomplete_no_results' | skyLibResources)\n }}\n </div>\n <button\n *ngIf=\"showAddButton\"\n class=\"\n sky-autocomplete-action sky-autocomplete-action-add sky-btn sky-btn-link\n \"\n tabindex=\"0\"\n type=\"button\"\n [class.focused]=\"isElementFocused(addButtonEl)\"\n (click)=\"addButtonClicked()\"\n #addButtonEl\n >\n <sky-icon *skyThemeIf=\"'modern'\" icon=\"add\" iconType=\"skyux\"></sky-icon>\n <sky-icon *skyThemeIf=\"'default'\" icon=\"plus-circle\"></sky-icon>\n {{ 'skyux_autocomplete_add' | skyLibResources }}\n </button>\n </div>\n</ng-template>\n\n<ng-template let-item=\"item\" #defaultSearchResultTemplate>\n {{ item[descriptorProperty] }}\n</ng-template>\n", styles: [".sky-autocomplete-results-container{position:fixed;background-color:#fff}.sky-autocomplete-results-waiting{height:70px}.sky-autocomplete-results{display:flex;flex-direction:column;padding:4px;overflow-y:auto;overflow-x:hidden;min-height:35px;max-height:calc(50vh - 50px)}.sky-autocomplete-result{color:#212327;margin-bottom:4px;padding:3px 20px;cursor:pointer}.sky-autocomplete-result:last-child{margin-bottom:0}.sky-autocomplete-actions{border-top:1px solid #cdcfd2}.sky-autocomplete-actions .sky-autocomplete-action{border:none}.sky-autocomplete-actions .sky-autocomplete-actions-no-results{display:inline-block;padding:7px 13px}.sky-autocomplete-action-add{float:right}.sky-autocomplete-action-add sky-icon{padding-right:5px}.sky-autocomplete-descendant-focus:not(.sky-autocomplete-action){background-color:#eeeeef}.sky-autocomplete-descendant-focus.sky-autocomplete-action{outline:thin dotted;outline:-webkit-focus-ring-color auto 5px}::ng-deep .sky-theme-modern .sky-autocomplete-results-container{border-radius:6px}::ng-deep .sky-theme-modern .sky-autocomplete-results{padding:10px 0}::ng-deep .sky-theme-modern .sky-autocomplete-result{margin-bottom:0;padding:10px 0 10px 15px}::ng-deep .sky-theme-modern .sky-autocomplete-descendant-focus:not(.sky-autocomplete-action){background-color:inherit}::ng-deep .sky-theme-modern .sky-autocomplete-descendant-focus{border:none;box-shadow:inset 0 0 0 2px #1870b8,0 1px 8px #0000004d}\n"], components: [{ type: i4.λ14, selector: "sky-wait", inputs: ["ariaLabel", "isWaiting", "isFullPage", "isNonBlocking"] }, { type: i4.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }], directives: [{ type: i5.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.λ11, selector: "[skyHighlight]", inputs: ["skyHighlight"] }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i5.λ3, selector: "[skyThemeIf]", inputs: ["skyThemeIf"] }], pipes: { "skyLibResources": i7.SkyLibResourcesPipe, "skyAutocompleteSearchAsyncDisabled": i8.SkyAutcompleteSearchAsyncDisabledPipe, "skyNumeric": i1.SkyNumericPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyAutocompleteComponent, decorators: [{
|
|
675
|
-
type: Component,
|
|
676
|
-
args: [{
|
|
677
|
-
selector: 'sky-autocomplete',
|
|
678
|
-
templateUrl: './autocomplete.component.html',
|
|
679
|
-
styleUrls: ['./autocomplete.component.scss'],
|
|
680
|
-
providers: [SkyAutocompleteAdapterService],
|
|
681
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
682
|
-
}]
|
|
683
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.SkyAffixService }, { type: i2.SkyAutocompleteAdapterService }, { type: i1.SkyOverlayService }, { type: i3.SkyInputBoxHostService, decorators: [{
|
|
684
|
-
type: Optional
|
|
685
|
-
}] }]; }, propDecorators: { ariaLabelledBy: [{
|
|
686
|
-
type: Input
|
|
687
|
-
}], data: [{
|
|
688
|
-
type: Input
|
|
689
|
-
}], debounceTime: [{
|
|
690
|
-
type: Input
|
|
691
|
-
}], descriptorProperty: [{
|
|
692
|
-
type: Input
|
|
693
|
-
}], enableShowMore: [{
|
|
694
|
-
type: Input
|
|
695
|
-
}], messageStream: [{
|
|
696
|
-
type: Input
|
|
697
|
-
}], wrapperClass: [{
|
|
698
|
-
type: Input
|
|
699
|
-
}], propertiesToSearch: [{
|
|
700
|
-
type: Input
|
|
701
|
-
}], search: [{
|
|
702
|
-
type: Input
|
|
703
|
-
}], searchResultTemplate: [{
|
|
704
|
-
type: Input
|
|
705
|
-
}], searchTextMinimumCharacters: [{
|
|
706
|
-
type: Input
|
|
707
|
-
}], searchFilters: [{
|
|
708
|
-
type: Input
|
|
709
|
-
}], searchResultsLimit: [{
|
|
710
|
-
type: Input
|
|
711
|
-
}], showAddButton: [{
|
|
712
|
-
type: Input
|
|
713
|
-
}], noResultsFoundText: [{
|
|
714
|
-
type: Input
|
|
715
|
-
}], searchAsyncDisabled: [{
|
|
716
|
-
type: Input
|
|
717
|
-
}], addClick: [{
|
|
718
|
-
type: Output
|
|
719
|
-
}], showMoreClick: [{
|
|
720
|
-
type: Output
|
|
721
|
-
}], selectionChange: [{
|
|
722
|
-
type: Output
|
|
723
|
-
}], searchAsync: [{
|
|
724
|
-
type: Output
|
|
725
|
-
}], defaultSearchResultTemplate: [{
|
|
726
|
-
type: ViewChild,
|
|
727
|
-
args: ['defaultSearchResultTemplate', {
|
|
728
|
-
read: TemplateRef,
|
|
729
|
-
static: false,
|
|
730
|
-
}]
|
|
731
|
-
}], inputDirective: [{
|
|
732
|
-
type: ContentChild,
|
|
733
|
-
args: [SkyAutocompleteInputDirective]
|
|
734
|
-
}], resultsTemplateRef: [{
|
|
735
|
-
type: ViewChild,
|
|
736
|
-
args: ['resultsTemplateRef', {
|
|
737
|
-
read: TemplateRef,
|
|
738
|
-
}]
|
|
739
|
-
}], resultsRef: [{
|
|
740
|
-
type: ViewChild,
|
|
741
|
-
args: ['resultsRef', {
|
|
742
|
-
read: ElementRef,
|
|
743
|
-
}]
|
|
744
|
-
}] } });
|
|
745
|
-
//# sourceMappingURL=autocomplete.component.js.map
|