@progress/kendo-angular-dropdowns 21.4.1 → 22.0.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.
Files changed (84) hide show
  1. package/common/localization/messages.d.ts +1 -1
  2. package/dropdowntrees/checked-state/base-check.directive.d.ts +1 -1
  3. package/fesm2022/progress-kendo-angular-dropdowns.mjs +173 -173
  4. package/package.json +14 -22
  5. package/schematics/ngAdd/index.js +2 -2
  6. package/esm2022/autocomplete/autocomplete.component.mjs +0 -1687
  7. package/esm2022/autocomplete/autocomplete.module.mjs +0 -70
  8. package/esm2022/comboboxes/combobox-column/column-cell-template.directive.mjs +0 -42
  9. package/esm2022/comboboxes/combobox-column/column-header-template.directive.mjs +0 -40
  10. package/esm2022/comboboxes/combobox-column/combobox-column.component.mjs +0 -116
  11. package/esm2022/comboboxes/combobox-column/util.mjs +0 -60
  12. package/esm2022/comboboxes/combobox.component.mjs +0 -2149
  13. package/esm2022/comboboxes/combobox.module.mjs +0 -77
  14. package/esm2022/comboboxes/multicolumncombobox.component.mjs +0 -883
  15. package/esm2022/common/adaptive-renderer.component.mjs +0 -253
  16. package/esm2022/common/constants/error-messages.mjs +0 -61
  17. package/esm2022/common/data.service.mjs +0 -250
  18. package/esm2022/common/disabled-items/disabled-items.service.mjs +0 -47
  19. package/esm2022/common/disabled-items/item-disabled.mjs +0 -5
  20. package/esm2022/common/filter-input.directive.mjs +0 -39
  21. package/esm2022/common/filtering/filter-settings.mjs +0 -5
  22. package/esm2022/common/filtering/filter.directive.mjs +0 -136
  23. package/esm2022/common/filtering/filterable-component.mjs +0 -34
  24. package/esm2022/common/list-item.directive.mjs +0 -25
  25. package/esm2022/common/list.component.mjs +0 -968
  26. package/esm2022/common/localization/custom-messages.component.mjs +0 -96
  27. package/esm2022/common/localization/localized-messages.directive.mjs +0 -47
  28. package/esm2022/common/localization/messages.mjs +0 -77
  29. package/esm2022/common/models/checkboxes-settings.mjs +0 -15
  30. package/esm2022/common/models/direction.mjs +0 -5
  31. package/esm2022/common/models/fillmode.mjs +0 -5
  32. package/esm2022/common/models/list-type.mjs +0 -5
  33. package/esm2022/common/models/page-change-event.mjs +0 -5
  34. package/esm2022/common/models/popup-settings.mjs +0 -5
  35. package/esm2022/common/models/preventable-event.mjs +0 -25
  36. package/esm2022/common/models/remove-tag-event.mjs +0 -23
  37. package/esm2022/common/models/rounded.mjs +0 -5
  38. package/esm2022/common/models/size.mjs +0 -5
  39. package/esm2022/common/models/virtualization-settings.mjs +0 -24
  40. package/esm2022/common/navigation/navigation-action.mjs +0 -32
  41. package/esm2022/common/navigation/navigation.service.mjs +0 -188
  42. package/esm2022/common/searchbar.component.mjs +0 -386
  43. package/esm2022/common/selection/selectable.directive.mjs +0 -83
  44. package/esm2022/common/selection/selection.service.mjs +0 -166
  45. package/esm2022/common/shared-events.directive.mjs +0 -99
  46. package/esm2022/common/taglist.component.mjs +0 -295
  47. package/esm2022/common/templates/custom-item-template.directive.mjs +0 -48
  48. package/esm2022/common/templates/fixed-group-template.directive.mjs +0 -55
  49. package/esm2022/common/templates/footer-template.directive.mjs +0 -49
  50. package/esm2022/common/templates/group-tag-template.directive.mjs +0 -47
  51. package/esm2022/common/templates/group-template.directive.mjs +0 -55
  52. package/esm2022/common/templates/header-template.directive.mjs +0 -49
  53. package/esm2022/common/templates/item-template.directive.mjs +0 -48
  54. package/esm2022/common/templates/no-data-template.directive.mjs +0 -49
  55. package/esm2022/common/templates/tag-template.directive.mjs +0 -46
  56. package/esm2022/common/templates/value-template.directive.mjs +0 -50
  57. package/esm2022/common/util.mjs +0 -376
  58. package/esm2022/directives.mjs +0 -172
  59. package/esm2022/dropdownlist/dropdownlist.component.mjs +0 -1999
  60. package/esm2022/dropdownlist/dropdownlist.module.mjs +0 -79
  61. package/esm2022/dropdowns.module.mjs +0 -76
  62. package/esm2022/dropdowntrees/checked-state/base-check.directive.mjs +0 -76
  63. package/esm2022/dropdowntrees/checked-state/check-all.directive.mjs +0 -170
  64. package/esm2022/dropdowntrees/checked-state/check.directive.mjs +0 -168
  65. package/esm2022/dropdowntrees/checked-state/checkable-settings.mjs +0 -5
  66. package/esm2022/dropdowntrees/checked-state/checked-item.mjs +0 -5
  67. package/esm2022/dropdowntrees/data-binding/dropdowntree/flat-binding.directive.mjs +0 -69
  68. package/esm2022/dropdowntrees/data-binding/dropdowntree/hierarchy-binding.directive.mjs +0 -62
  69. package/esm2022/dropdowntrees/data-binding/multiselecttree/flat-binding.directive.mjs +0 -69
  70. package/esm2022/dropdowntrees/data-binding/multiselecttree/hierarchy-binding.directive.mjs +0 -62
  71. package/esm2022/dropdowntrees/dropdowntree.component.mjs +0 -1967
  72. package/esm2022/dropdowntrees/dropdowntrees.module.mjs +0 -79
  73. package/esm2022/dropdowntrees/expanded-state/expand.directive.mjs +0 -49
  74. package/esm2022/dropdowntrees/lookup/lookup.mjs +0 -5
  75. package/esm2022/dropdowntrees/lookup/lookup.service.mjs +0 -82
  76. package/esm2022/dropdowntrees/multiselecttree.component.mjs +0 -2359
  77. package/esm2022/dropdowntrees/summary-tag/summary-tag.directive.mjs +0 -70
  78. package/esm2022/dropdowntrees/templates/node-template.directive.mjs +0 -31
  79. package/esm2022/index.mjs +0 -55
  80. package/esm2022/multiselect/multiselect.component.mjs +0 -2380
  81. package/esm2022/multiselect/multiselect.module.mjs +0 -79
  82. package/esm2022/multiselect/summary-tag.directive.mjs +0 -68
  83. package/esm2022/package-metadata.mjs +0 -16
  84. package/esm2022/progress-kendo-angular-dropdowns.mjs +0 -8
@@ -1,2149 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { Component, forwardRef, ElementRef, TemplateRef, Input, Output, EventEmitter, ContentChild, ViewChild, ViewContainerRef, HostBinding, isDevMode, ChangeDetectorRef, NgZone, Renderer2, Injector } from '@angular/core';
6
- import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
7
- import { validatePackage } from '@progress/kendo-licensing';
8
- import { packageMetadata } from '../package-metadata';
9
- import { SearchBarComponent } from '../common/searchbar.component';
10
- import { ItemTemplateDirective } from '../common/templates/item-template.directive';
11
- import { HeaderTemplateDirective } from '../common/templates/header-template.directive';
12
- import { FooterTemplateDirective } from '../common/templates/footer-template.directive';
13
- import { GroupTemplateDirective } from '../common/templates/group-template.directive';
14
- import { FixedGroupTemplateDirective } from '../common/templates/fixed-group-template.directive';
15
- import { NoDataTemplateDirective } from '../common/templates/no-data-template.directive';
16
- import { SelectionService } from '../common/selection/selection.service';
17
- import { NavigationService } from '../common/navigation/navigation.service';
18
- import { DisabledItemsService } from '../common/disabled-items/disabled-items.service';
19
- import { merge, of, Subject, Subscription } from 'rxjs';
20
- import { catchError, filter, map, partition, tap, throttleTime } from 'rxjs/operators';
21
- import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, MultiTabStop, SeparatorComponent, EventsOutsideAngularDirective, ResizeSensorComponent, Keys, TemplateContextDirective, guid, normalizeKeys, parseCSSClassNames } from '@progress/kendo-angular-common';
22
- import { AdaptiveService } from '@progress/kendo-angular-utils';
23
- import { isPresent, getter, isEmptyString, isUntouched, inDropDown, getSizeClass, getRoundedClass, getFillModeClass, isTruthy, setListBoxAriaLabelledBy, setActionSheetTitle, animationDuration } from '../common/util';
24
- import { NavigationAction } from '../common/navigation/navigation-action';
25
- import { PreventableEvent } from '../common/models/preventable-event';
26
- import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
27
- import { PopupService } from '@progress/kendo-angular-popup';
28
- import { ComboBoxMessages } from '../common/constants/error-messages';
29
- import { FilterableComponent } from '../common/filtering/filterable-component';
30
- import { DataService } from '../common/data.service';
31
- import { ListComponent } from '../common/list.component';
32
- import { normalizeVirtualizationSettings } from '../common/models/virtualization-settings';
33
- import { pointers, touchEnabled } from '@progress/kendo-common';
34
- import { caretAltDownIcon, xIcon } from '@progress/kendo-svg-icons';
35
- import { AdaptiveRendererComponent } from '../common/adaptive-renderer.component';
36
- import { NgTemplateOutlet, NgClass } from '@angular/common';
37
- import { SharedDropDownEventsDirective } from '../common/shared-events.directive';
38
- import { LocalizedMessagesDirective } from '../common/localization/localized-messages.directive';
39
- import { IconWrapperComponent } from '@progress/kendo-angular-icons';
40
- import * as i0 from "@angular/core";
41
- import * as i1 from "@progress/kendo-angular-l10n";
42
- import * as i2 from "@progress/kendo-angular-popup";
43
- import * as i3 from "../common/selection/selection.service";
44
- import * as i4 from "../common/navigation/navigation.service";
45
- import * as i5 from "../common/disabled-items/disabled-items.service";
46
- import * as i6 from "../common/data.service";
47
- import * as i7 from "@progress/kendo-angular-utils";
48
- /**
49
- * @hidden
50
- */
51
- export const COMBOBOX_VALUE_ACCESSOR = {
52
- multi: true,
53
- provide: NG_VALUE_ACCESSOR,
54
- useExisting: forwardRef(() => ComboBoxComponent)
55
- };
56
- const DEFAULT_SIZE = 'medium';
57
- const DEFAULT_ROUNDED = 'medium';
58
- const DEFAULT_FILL_MODE = 'solid';
59
- /**
60
- * Represents the [Kendo UI ComboBox component for Angular]({% slug overview_combobox %}).
61
- * @example
62
- * ```html
63
- * <kendo-combobox [data]="listItems"> </kendo-combobox>
64
- * ```
65
- * @remarks
66
- * Supported children components are: {@link CustomMessagesComponent}.
67
- */
68
- export class ComboBoxComponent extends MultiTabStop {
69
- wrapper;
70
- localization;
71
- popupService;
72
- selectionService;
73
- navigationService;
74
- disabledItemsService;
75
- dataService;
76
- zone;
77
- cdr;
78
- renderer;
79
- injector;
80
- hostElement;
81
- adaptiveService;
82
- /**
83
- * @hidden
84
- */
85
- icon;
86
- /**
87
- * @hidden
88
- */
89
- svgIcon;
90
- /**
91
- * Sets the HTML attributes of the inner focusable input element. Attributes essential for certain component functionalities cannot be changed.
92
- */
93
- inputAttributes;
94
- /**
95
- * @hidden
96
- */
97
- animationDuration = animationDuration;
98
- /**
99
- * @hidden
100
- */
101
- xIcon = xIcon;
102
- /**
103
- * @hidden
104
- */
105
- adaptiveRendererComponent;
106
- /**
107
- * @hidden
108
- */
109
- get actionSheet() {
110
- return this.adaptiveRendererComponent?.actionSheet;
111
- }
112
- /**
113
- * @hidden
114
- */
115
- get actionSheetSearchBar() {
116
- return this.adaptiveRendererComponent?.actionSheetSearchBar;
117
- }
118
- /**
119
- * @hidden
120
- */
121
- caretAltDownIcon = caretAltDownIcon;
122
- set text(text) {
123
- this._text = isPresent(text) ? text.toString() : "";
124
- }
125
- get text() {
126
- return this._text;
127
- }
128
- /**
129
- * @hidden
130
- */
131
- get ariaControls() {
132
- return this.isOpen ? this.listBoxId : undefined;
133
- }
134
- /**
135
- * @hidden
136
- */
137
- get isControlRequired() {
138
- return isControlRequired(this.formControl);
139
- }
140
- /**
141
- * @hidden
142
- */
143
- togglePopup(open) {
144
- const isDisabled = this.disabled || this.readonly;
145
- const sameState = this.isOpen === open;
146
- if (isDisabled || sameState) {
147
- return;
148
- }
149
- const isDefaultPrevented = this.triggerPopupEvents(open);
150
- if (!isDefaultPrevented) {
151
- this._toggle(open);
152
- }
153
- }
154
- get activeDescendant() {
155
- if (!this.isOpen || !isPresent(this.selectionService.focused) || this.selectionService.focused === -1) {
156
- return null;
157
- }
158
- return this.optionPrefix + "-" + this.selectionService.focused;
159
- }
160
- get appendTo() {
161
- const { appendTo } = this.popupSettings;
162
- if (!appendTo || appendTo === 'root') {
163
- return undefined;
164
- }
165
- return appendTo === 'component' ? this.container : appendTo;
166
- }
167
- dataItem;
168
- selected = [];
169
- /**
170
- * Shows or hides the current group sticky header when using grouped data.
171
- * By default the sticky header is displayed ([see example]({% slug grouping_autocomplete %}#toc-sticky-header)).
172
- * @default true
173
- */
174
- showStickyHeader = true;
175
- /**
176
- * @hidden
177
- */
178
- focusableId = `k-${guid()}`;
179
- /**
180
- * Specifies whether the ComboBox allows user-defined values that are not present in the dataset
181
- * ([more information and examples]({% slug custom_values_combobox %})).
182
- * Defaults to `false`.
183
- *
184
- * The feature is not available when using adaptive mode.
185
- * @default false
186
- */
187
- allowCustom = false;
188
- /**
189
- * Sets the data of the ComboBox.
190
- * The data must be provided in an array-like list.
191
- */
192
- set data(data) {
193
- this.dataService.data = data || [];
194
- if (this.virtual) {
195
- this.virtual.skip = 0;
196
- }
197
- this.setState();
198
- if (this._filtering) {
199
- const queryAndDataPresent = this.text.length > 0 && this.dataService.itemsCount > 0;
200
- const index = queryAndDataPresent ? this.firstFocusableIndex(0) : -1;
201
- this.selectionService.focused = index;
202
- }
203
- if (this.suggest && this.dataService.itemsCount && this.text) {
204
- this.suggestedText = getter(this.dataService.itemAt(0), this.textField);
205
- }
206
- }
207
- get data() {
208
- const virtual = this.virtual;
209
- if (virtual) {
210
- const start = virtual.skip || 0;
211
- const end = start + virtual.pageSize;
212
- // Use length instead of itemsCount because of the grouping.
213
- virtual.total = this.dataService.data.length;
214
- return this.dataService.data.slice(start, end);
215
- }
216
- return this.dataService.data;
217
- }
218
- /**
219
- * Sets the value of the ComboBox. The value can be a primitive (string, number) or a complex object. Use the `valuePrimitive` property to define the type.
220
- *
221
- * All selected values not present in the dataset are custom values. When the `Enter` key is pressed or the component loses focus, custom values are dismissed unless `allowCustom` is set to `true`.
222
- */
223
- set value(newValue) {
224
- this._value = newValue;
225
- this.setState();
226
- this.cdr.markForCheck();
227
- }
228
- get value() {
229
- return this._value;
230
- }
231
- /**
232
- * Sets the data item field that represents the item text. If the data contains only primitive values, do not define this property.
233
- *
234
- * The `textField` property can be set to a nested property value, for example, `category.name`.
235
- */
236
- textField;
237
- /**
238
- * Sets the data item field that represents the item value.
239
- * If the data contains only primitive values, do not define it.
240
- *
241
- * > The `valueField` property can be set to point to a nested property value - e.g. `category.id`.
242
- */
243
- valueField;
244
- /**
245
- * Specifies the type of the selected value. If set to `true`, the selected value must be a primitive type.
246
- * ([more information and example]({% slug valuebinding_combobox %}#toc-primitive-values-from-object-fields))
247
- */
248
- set valuePrimitive(isPrimitive) {
249
- this._valuePrimitive = isPrimitive;
250
- }
251
- get valuePrimitive() {
252
- if (!isPresent(this._valuePrimitive)) {
253
- return !isPresent(this.valueField);
254
- }
255
- return this._valuePrimitive;
256
- }
257
- /**
258
- * A user-defined callback which returns normalized custom values.
259
- * Typically used when the data items are different from type `string`.
260
- * @param { Any } value - The custom value defined by the user.
261
- * @returns { Any }
262
- *
263
- * @example
264
- * ```ts
265
- * import { map } from 'rxjs/operators';
266
- *
267
- * _@Component({
268
- * selector: 'my-app',
269
- * template: `
270
- * <kendo-combobox
271
- * [allowCustom]="true"
272
- * [data]="listItems"
273
- * textField="text"
274
- * valueField="value"
275
- * [valueNormalizer]="valueNormalizer"
276
- * (valueChange)="onValueChange($event)"
277
- * >
278
- * </kendo-combobox>
279
- * `
280
- * })
281
- *
282
- * class AppComponent {
283
- * public listItems: Array<{ text: string, value: number }> = [
284
- * { text: "Small", value: 1 },
285
- * { text: "Medium", value: 2 },
286
- * { text: "Large", value: 3 }
287
- * ];
288
- *
289
- * public onValueChange(value) {
290
- * console.log("valueChange : ", value);
291
- * }
292
- *
293
- * public valueNormalizer = (text$: Observable<string>) => text$.pipe(map((text: string) => {
294
- * return { ProductID: null, ProductName: text };
295
- * }));
296
- *
297
- * }
298
- * ```
299
- */
300
- valueNormalizer = (text) => text.pipe(map((userInput) => userInput));
301
- /**
302
- * The hint that is displayed when the component is empty.
303
- * @default ''
304
- */
305
- placeholder = "";
306
- /**
307
- * Enables or disables the adaptive mode. By default, adaptive rendering is disabled.
308
- * @default 'none'
309
- */
310
- adaptiveMode = 'none';
311
- /**
312
- * Sets the title of the ActionSheet that is rendered instead of the Popup when using small screen devices.
313
- * By default, the ActionSheet title uses the text provided for the label of the ComboBox.
314
- * @default ''
315
- */
316
- adaptiveTitle = '';
317
- /**
318
- * Sets the subtitle of the ActionSheet that is rendered instead of the Popup when using small screen devices. By default, the ActionSheet does not render a subtitle.
319
- */
320
- adaptiveSubtitle;
321
- /**
322
- * @hidden
323
- */
324
- get isAdaptiveModeEnabled() {
325
- return this.adaptiveMode === 'auto';
326
- }
327
- /**
328
- * Configures the popup of the ComboBox.
329
- */
330
- set popupSettings(settings) {
331
- this._popupSettings = Object.assign({ animate: true }, settings);
332
- }
333
- get popupSettings() {
334
- return this._popupSettings;
335
- }
336
- /**
337
- * Sets the height of the options list in the popup. By default, `listHeight` is 200px.
338
- *
339
- * > The `listHeight` property affects only the list of options and not the whole popup container.
340
- * > To set the height of the popup container, use `popupSettings.height`.
341
- *
342
- * When using `adaptiveMode` and the screen size is `small` or `medium` the `listHeight` property is set to null.
343
- */
344
- set listHeight(_listHeight) {
345
- this._listHeight = _listHeight;
346
- }
347
- get listHeight() {
348
- if (this.isAdaptive) {
349
- return;
350
- }
351
- return this._listHeight;
352
- }
353
- _listHeight = 200;
354
- /**
355
- * Sets and gets the loading state of the ComboBox.
356
- */
357
- loading;
358
- /**
359
- * Enables the auto-completion of the text based on the first data item.
360
- * @default false
361
- */
362
- suggest = false;
363
- /**
364
- * If set to `true`, renders a button on hovering over the component.
365
- * Clicking this button resets the value of the component to `undefined` and triggers the `change` event.
366
- * @default true
367
- */
368
- clearButton = true;
369
- /**
370
- * Sets the disabled state of the component. To learn how to disable the component in reactive forms, refer to the articles on [ComboBox Forms Support](slug:formssupport_combobox#toc-managing-the-combobox-disabled-state-in-reactive-forms) and [MultiColumnComboBox Forms Support](slug:formssupport_multicolumncombobox#toc-managing-the-multicolumncombobox-disabled-state-in-reactive-forms).
371
- */
372
- disabled = false;
373
- /**
374
- * Defines a Boolean function that is executed for each data item in the component ([see examples]({% slug disableditems_combobox %})). Determines whether the item is disabled.
375
- */
376
- set itemDisabled(fn) {
377
- if (typeof fn !== 'function') {
378
- throw new Error(`itemDisabled must be a function, but received ${JSON.stringify(fn)}.`);
379
- }
380
- this.disabledItemsService.itemDisabled = fn;
381
- }
382
- /**
383
- * Sets the read-only state of the component.
384
- * @default false
385
- */
386
- readonly = false;
387
- /**
388
- * Specifies the [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
389
- */
390
- tabindex = 0;
391
- /**
392
- * @hidden
393
- */
394
- set tabIndex(tabIndex) {
395
- this.tabindex = tabIndex;
396
- }
397
- get tabIndex() {
398
- return this.tabindex;
399
- }
400
- /**
401
- * Enables the [filtering]({% slug filtering_combobox %}) functionality.
402
- * If set to `true`, the component emits the `filterChange` event.
403
- */
404
- filterable = false;
405
- /**
406
- * Enables the [virtualization]({% slug virtualization_combobox %}) functionality.
407
- */
408
- set virtual(settings) {
409
- this._virtualSettings = normalizeVirtualizationSettings(settings, {
410
- itemHeight: this.defaultVirtualItemHeight,
411
- pageSize: this.defaultVirtualPageSize
412
- });
413
- }
414
- get virtual() {
415
- return this._virtualSettings;
416
- }
417
- /**
418
- * Sets the size of the component.
419
- *
420
- * The possible values are:
421
- * * `small`
422
- * * `medium` (default)
423
- * * `large`
424
- * * `none`
425
- *
426
- */
427
- set size(size) {
428
- const newSize = size ? size : DEFAULT_SIZE;
429
- this.renderer.removeClass(this.wrapper.nativeElement, getSizeClass('input', this.size));
430
- if (size !== 'none') {
431
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('input', newSize));
432
- }
433
- this._size = newSize;
434
- }
435
- get size() {
436
- return this._size;
437
- }
438
- /**
439
- * Sets the border radius of the component.
440
- *
441
- * The possible values are:
442
- * * `small`
443
- * * `medium` (default)
444
- * * `large`
445
- * * `full`
446
- * * `none`
447
- *
448
- */
449
- set rounded(rounded) {
450
- const newRounded = rounded ? rounded : DEFAULT_ROUNDED;
451
- this.renderer.removeClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
452
- if (rounded !== 'none') {
453
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(newRounded));
454
- }
455
- this._rounded = newRounded;
456
- }
457
- get rounded() {
458
- return this._rounded;
459
- }
460
- /**
461
- * Sets the fillMode of the component.
462
- *
463
- * The possible values are:
464
- * * `flat`
465
- * * `solid` (default)
466
- * * `outline`
467
- * * `none`
468
- *
469
- */
470
- set fillMode(fillMode) {
471
- const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE;
472
- this.renderer.removeClass(this.wrapper.nativeElement, getFillModeClass('input', this.fillMode));
473
- if (fillMode !== 'none') {
474
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('input', newFillMode));
475
- }
476
- this._fillMode = newFillMode;
477
- }
478
- get fillMode() {
479
- return this._fillMode;
480
- }
481
- /**
482
- * Fires each time the value is changed&mdash;
483
- * when the component is blurred or the value is cleared through the **Clear** button
484
- * ([see example](slug:events_combobox)).
485
- * When the value of the component is programmatically changed to `ngModel` or `formControl`
486
- * through its API or form binding, the `valueChange` event is not triggered because it
487
- * might cause a mix-up with the built-in `valueChange` mechanisms of the `ngModel` or `formControl` bindings.
488
- */
489
- valueChange = new EventEmitter();
490
- /**
491
- * Fires each time an item selection is changed ([see example](slug:events_combobox)).
492
- */
493
- selectionChange = new EventEmitter();
494
- /**
495
- * Fires each time the user types in the input field. You can filter the source based on the passed filtration value ([see example](slug:events_combobox)).
496
- */
497
- filterChange = new EventEmitter();
498
- /**
499
- * Fires each time the popup is about to open. This event is preventable. If you cancel it, the popup remains closed.
500
- */
501
- open = new EventEmitter();
502
- /**
503
- * Fires after the popup has been opened.
504
- */
505
- opened = new EventEmitter();
506
- /**
507
- * Fires each time the popup is about to close. This event is preventable. If you cancel it, the popup remains open.
508
- */
509
- close = new EventEmitter();
510
- /**
511
- * Fires after the popup has been closed.
512
- */
513
- closed = new EventEmitter();
514
- /**
515
- * Fires each time the user focuses the ComboBox.
516
- */
517
- onFocus = new EventEmitter();
518
- /**
519
- * Fires each time the ComboBox gets blurred.
520
- */
521
- onBlur = new EventEmitter();
522
- /**
523
- * Fires each time the user focuses the `input` element.
524
- */
525
- inputFocus = new EventEmitter();
526
- /**
527
- * Fires each time the `input` element gets blurred.
528
- */
529
- inputBlur = new EventEmitter();
530
- /**
531
- * @hidden
532
- */
533
- escape = new EventEmitter();
534
- template;
535
- headerTemplate;
536
- footerTemplate;
537
- noDataTemplate;
538
- groupTemplate;
539
- fixedGroupTemplate;
540
- /**
541
- * @hidden
542
- */
543
- suffixTemplate;
544
- /**
545
- * @hidden
546
- */
547
- prefixTemplate;
548
- container;
549
- popupTemplate;
550
- searchbar;
551
- optionsList;
552
- select;
553
- widgetClasses = true;
554
- get isDisabled() {
555
- return this.disabled;
556
- }
557
- get isLoading() {
558
- return this.loading;
559
- }
560
- get dir() {
561
- return this.direction;
562
- }
563
- _isFocused = false;
564
- get isFocused() {
565
- return this._isFocused;
566
- }
567
- set isFocused(value) {
568
- this.renderer[value ? 'addClass' : 'removeClass'](this.wrapper.nativeElement, "k-focus");
569
- this._isFocused = value;
570
- }
571
- get clearButtonVisibility() {
572
- if (touchEnabled) {
573
- return 'visible';
574
- }
575
- }
576
- /**
577
- * @hidden
578
- */
579
- get formControl() {
580
- const ngControl = this.injector.get(NgControl, null);
581
- return ngControl?.control || null;
582
- }
583
- /**
584
- * @hidden
585
- */
586
- windowSize = 'large';
587
- /**
588
- * @hidden
589
- */
590
- get isActionSheetExpanded() {
591
- return this.actionSheet?.expanded;
592
- }
593
- /**
594
- * @hidden
595
- */
596
- get isAdaptive() {
597
- return this.isAdaptiveModeEnabled && this.windowSize !== 'large';
598
- }
599
- listBoxId = `k-${guid()}`;
600
- optionPrefix = `k-${guid()}`;
601
- popupRef;
602
- get popupWidth() {
603
- let wrapperOffsetWidth = 0;
604
- if (isDocumentAvailable()) {
605
- wrapperOffsetWidth = this.wrapper.nativeElement.offsetWidth;
606
- }
607
- const width = this.popupSettings.width || wrapperOffsetWidth;
608
- const minWidth = isNaN(wrapperOffsetWidth) ? wrapperOffsetWidth : `${wrapperOffsetWidth}px`;
609
- const maxWidth = isNaN(width) ? width : `${width}px`;
610
- return { min: minWidth, max: maxWidth };
611
- }
612
- get popupHeight() {
613
- const popupHeight = this.popupSettings.height;
614
- return isPresent(popupHeight) ? `${popupHeight}px` : 'auto';
615
- }
616
- onChangeCallback = (_) => { };
617
- onTouchedCallback = (_) => { };
618
- /**
619
- * Used for the default virtualization settings config.
620
- */
621
- defaultVirtualItemHeight = 28;
622
- /**
623
- * Used for the default virtualization settings config.
624
- */
625
- defaultVirtualPageSize = 50;
626
- valueSubscription;
627
- _filtering = false;
628
- _text = '';
629
- filterText = '';
630
- _open = false;
631
- _value;
632
- _valuePrimitive;
633
- _previousDataItem;
634
- suggestedText;
635
- backspacePressed;
636
- _popupSettings = { animate: true };
637
- _virtualSettings;
638
- popupMouseDownHandler = (event) => event.preventDefault();
639
- customValueSubject = new Subject();
640
- valueSubject = new Subject();
641
- clearValueSubject = new Subject();
642
- direction;
643
- subs = new Subscription();
644
- touchstartDisposeHandler;
645
- selectClickDisposeHandler;
646
- _size = 'medium';
647
- _rounded = 'medium';
648
- _fillMode = 'solid';
649
- constructor(wrapper, localization, popupService, selectionService, navigationService, disabledItemsService, dataService, zone, cdr, renderer, injector, hostElement, adaptiveService) {
650
- super();
651
- this.wrapper = wrapper;
652
- this.localization = localization;
653
- this.popupService = popupService;
654
- this.selectionService = selectionService;
655
- this.navigationService = navigationService;
656
- this.disabledItemsService = disabledItemsService;
657
- this.dataService = dataService;
658
- this.zone = zone;
659
- this.cdr = cdr;
660
- this.renderer = renderer;
661
- this.injector = injector;
662
- this.hostElement = hostElement;
663
- this.adaptiveService = adaptiveService;
664
- validatePackage(packageMetadata);
665
- this.direction = localization.rtl ? 'rtl' : 'ltr';
666
- this.data = [];
667
- }
668
- ngOnInit() {
669
- this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
670
- this.attachStreams();
671
- this.createValueStream();
672
- this.subscribeTouchEvents();
673
- this.attachSelectClickHandler();
674
- this.setComponentClasses();
675
- }
676
- ngAfterViewInit() {
677
- this.windowSize = this.adaptiveService.size;
678
- this.cdr.detectChanges();
679
- }
680
- createValueStream() {
681
- const valueStream = this.valueSubject.pipe(filter((candidate) => {
682
- const current = getter(this.value, this.valueField);
683
- const newValue = getter(candidate, this.valueField);
684
- let newText = getter(candidate, this.textField);
685
- if (!isPresent(this.value) && !isPresent(newValue)) {
686
- return false;
687
- }
688
- if (isPresent(newText)) {
689
- newText = newText.toString();
690
- }
691
- if (current === newValue && this.text === newText) {
692
- this.clearFilter();
693
- return false;
694
- }
695
- else {
696
- return true;
697
- }
698
- }), map((candidate) => {
699
- const newValue = getter(candidate, this.valueField);
700
- const newText = getter(candidate, this.textField);
701
- return {
702
- dataItem: candidate,
703
- text: newText,
704
- value: this.valuePrimitive ? newValue : candidate
705
- };
706
- }));
707
- const customValueStreams = partition(() => this.allowCustom)(this.customValueSubject.pipe(throttleTime(300)));
708
- const allowCustomValueStream = customValueStreams[0].pipe(tap(() => {
709
- this.loading = true;
710
- this.disabled = true;
711
- this.cdr.detectChanges();
712
- }), filter(() => {
713
- const hasChange = this.text !== getter(this.value, this.valueField);
714
- this.loading = hasChange;
715
- this.disabled = hasChange;
716
- if (!hasChange) {
717
- this.clearFilter();
718
- }
719
- return hasChange;
720
- }), this.valueNormalizer, map((normalizedValue) => {
721
- return {
722
- custom: true,
723
- dataItem: normalizedValue,
724
- text: this.text,
725
- value: normalizedValue
726
- };
727
- }));
728
- const disableCustomValueStream = customValueStreams[1].pipe(map(() => {
729
- return {
730
- custom: true,
731
- dataItem: undefined,
732
- text: undefined,
733
- value: undefined
734
- };
735
- }));
736
- const clearValueStream = this.clearValueSubject.pipe(map(() => ({
737
- dataItem: undefined,
738
- text: undefined,
739
- value: undefined
740
- })));
741
- if (this.valueSubscription) {
742
- this.valueSubscription.unsubscribe();
743
- }
744
- const merged = merge(valueStream, allowCustomValueStream, disableCustomValueStream, clearValueStream);
745
- this.valueSubscription = merged.pipe(catchError(() => {
746
- const selectionChanged = getter(this.dataItem, this.valueField) !== undefined;
747
- this.dataItem = undefined;
748
- this.value = undefined;
749
- this.text = undefined;
750
- this.loading = false;
751
- this.disabled = false;
752
- if (selectionChanged) {
753
- this.selectionChange.emit(undefined);
754
- }
755
- this.emitValueChange();
756
- this.createValueStream();
757
- return of(null);
758
- }))
759
- .subscribe((state) => {
760
- const selectionChanged = getter(this.dataItem, this.valueField) !== getter(state.dataItem, this.valueField);
761
- this.dataItem = state.dataItem;
762
- this.value = state.value;
763
- this.text = state.text;
764
- this.loading = false;
765
- this.disabled = false;
766
- this.clearFilter();
767
- if (state.custom) {
768
- this.selectionService.focused = -1;
769
- }
770
- if (selectionChanged) {
771
- const selectionArgs = state.custom ? undefined : this.dataItem;
772
- this.selectionChange.emit(selectionArgs);
773
- }
774
- this.emitValueChange();
775
- });
776
- }
777
- attachStreams() {
778
- if (!isDocumentAvailable()) {
779
- return;
780
- }
781
- this.subs.add(this.localization
782
- .changes.subscribe(({ rtl }) => {
783
- this.direction = rtl ? 'rtl' : 'ltr';
784
- this.cdr.detectChanges();
785
- }));
786
- this.subs.add(merge(this.navigationService.up, this.navigationService.down, this.navigationService.home, this.navigationService.end)
787
- .pipe(filter((event) => isPresent(event.index)))
788
- .subscribe((event) => this.navigate(event.index)));
789
- this.subs.add(this.navigationService.open.subscribe(this.handleNavigationOpen.bind(this)));
790
- this.subs.add(this.navigationService.close.subscribe(() => this.togglePopup(false)));
791
- this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
792
- if (this.isOpen) {
793
- event.originalEvent.preventDefault();
794
- const code = normalizeKeys(event.originalEvent);
795
- this.optionsList.scrollWithOnePage(NavigationAction[code]);
796
- }
797
- }));
798
- this.subs.add(this.navigationService.esc.subscribe(this.handleEscape.bind(this)));
799
- this.subs.add(this.navigationService.enter.pipe(tap((event) => {
800
- if (this.isOpen) {
801
- event.originalEvent.preventDefault();
802
- }
803
- }))
804
- .subscribe(this.handleEnter.bind(this)));
805
- this.subs.add(merge(this.selectionService.onChange, this.selectionService.onSelect.pipe(filter(() => !this.isOpen)))
806
- .pipe(tap(() => {
807
- this._filtering = false;
808
- this.togglePopup(false);
809
- }), map((event) => this.dataService.itemAt(event.indices[0])))
810
- .subscribe(dataItem => {
811
- this.change(dataItem);
812
- }));
813
- this.subs.add(this.selectionService.onSelect.pipe(filter(() => this.isOpen), tap(() => this._filtering = false), map((event) => this.dataService.itemAt(event.indices[0])))
814
- .subscribe(dataItem => {
815
- const selectionChanged = getter(dataItem, this.valueField) !== getter(this.dataItem, this.valueField);
816
- this.updateState({ dataItem });
817
- if (selectionChanged) {
818
- this.selectionChange.emit(dataItem);
819
- }
820
- }));
821
- }
822
- ngOnDestroy() {
823
- this.destroyPopup();
824
- this.subs.unsubscribe();
825
- if (isPresent(this.valueSubscription)) {
826
- this.valueSubscription.unsubscribe();
827
- }
828
- if (this.touchstartDisposeHandler) {
829
- this.touchstartDisposeHandler();
830
- }
831
- if (this.selectClickDisposeHandler) {
832
- this.selectClickDisposeHandler();
833
- }
834
- }
835
- ngOnChanges(changes) {
836
- const virtual = this.virtual;
837
- const requestInitialData = virtual && changes['data'] && changes['data'].isFirstChange();
838
- if (requestInitialData) {
839
- this.pageChange({ skip: 0, take: virtual.pageSize });
840
- }
841
- if (isChanged('valueNormalizer', changes)) {
842
- this.createValueStream();
843
- }
844
- if (anyChanged(['textField', 'valueField', 'valuePrimitive'], changes, false)) {
845
- this.setState();
846
- }
847
- }
848
- ngAfterContentChecked() {
849
- this.verifySettings();
850
- }
851
- /**
852
- * Focuses a specific item of the ComboBox based on a provided index.
853
- * If null or invalid index is provided the focus will be removed.
854
- */
855
- focusItemAt(index) {
856
- const isInRange = index >= 0 && index < this.data.length;
857
- if (isPresent(index) && isInRange && !this.disabledItemsService.isIndexDisabled(index)) {
858
- this.selectionService.focus(index);
859
- }
860
- else {
861
- this.selectionService.focus(-1);
862
- }
863
- }
864
- /**
865
- * Focuses the ComboBox.
866
- */
867
- focus() {
868
- if (!this.disabled) {
869
- this.searchbar.focus();
870
- }
871
- }
872
- /**
873
- * Blurs the ComboBox.
874
- */
875
- blur() {
876
- if (!this.disabled) {
877
- this.searchbar.blur();
878
- }
879
- }
880
- /**
881
- * Toggles the visibility of the popup or actionSheet. If you use the `toggle` method to open or close the popup or actionSheet,
882
- * the `open` and `close` events will not be fired.
883
- *
884
- * @param open - The state of the popup.
885
- */
886
- toggle(open) {
887
- Promise.resolve(null).then(() => {
888
- const shouldOpen = isPresent(open) ? open : !this._open;
889
- this._toggle(shouldOpen);
890
- this.cdr.markForCheck();
891
- });
892
- }
893
- /**
894
- * Returns the current open state. Returns `true` if the popup or actionSheet is open.
895
- */
896
- get isOpen() {
897
- return isTruthy(this._open || this.isActionSheetExpanded);
898
- }
899
- /**
900
- * @hidden
901
- */
902
- handleClick() {
903
- this.windowSize = this.adaptiveService.size;
904
- if (this.isAdaptive) {
905
- this.togglePopup(true);
906
- }
907
- }
908
- /**
909
- * Resets the value of the ComboBox.
910
- * If you use the `reset` method to clear the value of the component,
911
- * the model will not update automatically and the `selectionChange` and `valueChange` events will not be fired.
912
- */
913
- reset() {
914
- this.value = undefined;
915
- this.clearState();
916
- this.resetSelection();
917
- }
918
- /**
919
- * @hidden
920
- *
921
- * Used by the TextBoxContainer to determine if the floating label
922
- * should be rendered in the input when the component is not focused.
923
- */
924
- isEmpty() {
925
- const textEmpty = !isPresent(this.text) || isEmptyString(this.text);
926
- const valueEmpty = !isPresent(this.value) || isEmptyString(this.value);
927
- return textEmpty && valueEmpty;
928
- }
929
- /**
930
- * @hidden
931
- */
932
- messageFor(key) {
933
- return this.localization.get(key);
934
- }
935
- /**
936
- * @hidden
937
- */
938
- clearValue(event) {
939
- event?.stopImmediatePropagation();
940
- if (event) {
941
- this.focus();
942
- }
943
- this._previousDataItem = undefined;
944
- this.selectionService.resetSelection([]);
945
- this.clearValueSubject.next(undefined);
946
- this._filtering = false;
947
- }
948
- /**
949
- * @hidden
950
- */
951
- writeValue(value) {
952
- this.value = value === null ? undefined : value;
953
- }
954
- /**
955
- * @hidden
956
- */
957
- registerOnChange(fn) {
958
- this.onChangeCallback = fn;
959
- }
960
- /**
961
- * @hidden
962
- */
963
- registerOnTouched(fn) {
964
- this.onTouchedCallback = fn;
965
- }
966
- /**
967
- * @hidden
968
- */
969
- setDisabledState(isDisabled) {
970
- this.cdr.markForCheck();
971
- this.disabled = isDisabled;
972
- }
973
- /**
974
- * @hidden
975
- */
976
- get selectButtonClasses() {
977
- return `${this.size ? getSizeClass('button', this.size) : ''} ${this.fillMode ? 'k-button-' + this.fillMode : ''} ${this.fillMode ? 'k-button-' + this.fillMode + '-base' : ''}
978
- `;
979
- }
980
- /**
981
- * @hidden
982
- */
983
- onResize() {
984
- const currentWindowSize = this.adaptiveService.size;
985
- if (this.isAdaptiveModeEnabled && this.windowSize !== currentWindowSize) {
986
- if (this.isOpen) {
987
- this.togglePopup(false);
988
- }
989
- this.windowSize = currentWindowSize;
990
- this.cdr.detectChanges();
991
- }
992
- if (this.isOpen && !this.isActionSheetExpanded) {
993
- const popupWrapper = this.popupRef.popupElement;
994
- const { min, max } = this.popupWidth;
995
- popupWrapper.style.minWidth = min;
996
- popupWrapper.style.width = max;
997
- }
998
- }
999
- verifySettings() {
1000
- if (!isDevMode()) {
1001
- return;
1002
- }
1003
- if (this.valuePrimitive === true && isPresent(this.value) && typeof this.value === "object") {
1004
- throw new Error(ComboBoxMessages.primitive);
1005
- }
1006
- if (this.valuePrimitive === false && isPresent(this.value) && typeof this.value !== "object") {
1007
- throw new Error(ComboBoxMessages.object);
1008
- }
1009
- const valueOrText = !isPresent(this.valueField) !== !isPresent(this.textField);
1010
- if (valueOrText) {
1011
- throw new Error(ComboBoxMessages.textAndValue);
1012
- }
1013
- if (this.virtual && isNaN(this.virtual.itemHeight)) {
1014
- throw new Error(ComboBoxMessages.noItemHeight);
1015
- }
1016
- }
1017
- setState() {
1018
- // Filtering in process, do nothing.
1019
- if (this._filtering) {
1020
- return;
1021
- }
1022
- const value = this.value;
1023
- const valueField = this.valueField;
1024
- const resolved = this.findDataItem({ valueField, value });
1025
- if (isPresent(resolved.index) && resolved.index !== -1) {
1026
- this.updateState({ dataItem: resolved.dataItem, confirm: true });
1027
- this.resetSelection(resolved.index);
1028
- }
1029
- else if (isPresent(value) && this.allowCustom) {
1030
- this.updateState({ dataItem: value });
1031
- this.resetSelection(-1);
1032
- }
1033
- else if (this._previousDataItem && this.value) {
1034
- this.updateState({ dataItem: this._previousDataItem });
1035
- this.resetSelection();
1036
- }
1037
- else {
1038
- this.clearState();
1039
- this.resetSelection(-1);
1040
- }
1041
- }
1042
- updateState({ dataItem, confirm = false }) {
1043
- this.dataItem = dataItem;
1044
- this.text = getter(dataItem, this.textField);
1045
- if (confirm) {
1046
- this._previousDataItem = dataItem;
1047
- }
1048
- }
1049
- clearState() {
1050
- this.text = undefined;
1051
- this.dataItem = undefined;
1052
- }
1053
- resetSelection(index) {
1054
- const clear = !isPresent(index) || index < 0;
1055
- this.selectionService.resetSelection(clear ? [] : [index]);
1056
- this.selectionService.focused = index;
1057
- }
1058
- firstFocusableIndex(index) {
1059
- const maxIndex = this.data.length - 1;
1060
- if (this.disabledItemsService.isIndexDisabled(index)) {
1061
- return (index < maxIndex) ? this.firstFocusableIndex(index + 1) : undefined;
1062
- }
1063
- else {
1064
- return index;
1065
- }
1066
- }
1067
- findIndexPredicate(text) {
1068
- if (this.dataService.grouped) {
1069
- return (item) => {
1070
- let itemText = getter(item.value, this.textField);
1071
- itemText = !isPresent(itemText) ? "" : itemText.toString().toLowerCase();
1072
- return itemText.startsWith(text.toLowerCase());
1073
- };
1074
- }
1075
- else {
1076
- return (item) => {
1077
- let itemText = getter(item, this.textField);
1078
- itemText = !isPresent(itemText) ? "" : itemText.toString().toLowerCase();
1079
- return itemText.startsWith(text.toLowerCase());
1080
- };
1081
- }
1082
- }
1083
- findDataItem({ valueField, value }) {
1084
- const result = {
1085
- dataItem: null,
1086
- index: -1
1087
- };
1088
- const comparer = (element) => {
1089
- const dataItem = this.dataService.grouped ? element.value : element;
1090
- return getter(dataItem, valueField) === getter(value, valueField);
1091
- };
1092
- const index = this.dataService.findIndex(comparer);
1093
- result.dataItem = this.dataService.itemAt(index);
1094
- result.index = index;
1095
- return result;
1096
- }
1097
- search(text, startFrom = 0) {
1098
- const index = this.findIndex(text, startFrom);
1099
- if (this.disabledItemsService.isIndexDisabled(index)) {
1100
- if (index + 1 < this.dataService.itemsCount) {
1101
- this.search(text, index + 1);
1102
- }
1103
- else {
1104
- this.selectionService.focus(-1);
1105
- }
1106
- }
1107
- else {
1108
- this.selectionService.focus(index);
1109
- if (this.suggest) {
1110
- this.suggestedText = getter(this.dataService.itemAt(index), this.textField);
1111
- }
1112
- }
1113
- }
1114
- /**
1115
- * @hidden
1116
- */
1117
- getSuggestion() {
1118
- const hasSelected = !!this.selectionService.selected.length;
1119
- const shouldSuggest = this.suggest && !this.backspacePressed && this.suggestedText && this.text;
1120
- if (!hasSelected && shouldSuggest && this.suggestedText.toLowerCase().startsWith(this.text.toLowerCase())) {
1121
- return this.suggestedText;
1122
- }
1123
- else {
1124
- this.suggestedText = undefined;
1125
- }
1126
- }
1127
- navigate(index) {
1128
- if (this.dataService.itemsCount === 0) {
1129
- return;
1130
- }
1131
- this.text = getter(this.dataService.itemAt(index), this.textField);
1132
- this.selectionService.select(index);
1133
- }
1134
- /**
1135
- * @hidden
1136
- */
1137
- handleNavigate(event) {
1138
- const hasSelected = isPresent(this.selectionService.selected[0]);
1139
- const focused = isNaN(this.selectionService.focused) ? this.firstFocusableIndex(0) : this.selectionService.focused;
1140
- let offset = 0;
1141
- if (this.disabled || this.readonly) {
1142
- return;
1143
- }
1144
- // on some keyboards, Home and End keys are mapped to Numpad keys
1145
- const code = normalizeKeys(event);
1146
- const isHomeKey = code === Keys.Home;
1147
- const isEndKey = code === Keys.End;
1148
- if (isHomeKey || isEndKey) {
1149
- return;
1150
- }
1151
- if (!hasSelected) {
1152
- if (code === Keys.ArrowDown) {
1153
- offset = -1;
1154
- }
1155
- else if (code === Keys.ArrowUp) {
1156
- offset = 1;
1157
- }
1158
- }
1159
- const action = this.navigationService.process({
1160
- current: offset + focused,
1161
- max: this.dataService.itemsCount - 1,
1162
- min: 0,
1163
- originalEvent: event
1164
- });
1165
- if (action !== NavigationAction.Undefined &&
1166
- action !== NavigationAction.Left &&
1167
- action !== NavigationAction.Right &&
1168
- action !== NavigationAction.Backspace &&
1169
- action !== NavigationAction.Delete &&
1170
- action !== NavigationAction.PageDown &&
1171
- action !== NavigationAction.PageUp &&
1172
- ((action === NavigationAction.Enter && this.isOpen) || action !== NavigationAction.Enter)) {
1173
- event.preventDefault();
1174
- }
1175
- if (action === NavigationAction.Tab && this.isActionSheetExpanded) {
1176
- event.stopImmediatePropagation();
1177
- this.togglePopup(false);
1178
- }
1179
- }
1180
- handleEnter() {
1181
- const text = this.text;
1182
- const focused = this.selectionService.focused;
1183
- const hasFocused = isPresent(focused) && focused !== -1;
1184
- const previousText = getter(this._previousDataItem, this.textField) || "";
1185
- const focusedItemText = getter(this.dataService.itemAt(focused), this.textField);
1186
- const textHasChanged = text !== previousText;
1187
- this.togglePopup(false);
1188
- this._filtering = false;
1189
- if (this.allowCustom && textHasChanged) {
1190
- if (text === focusedItemText || this.useSuggestion()) {
1191
- this.selectionService.change(focused);
1192
- }
1193
- else {
1194
- this.change(text, true);
1195
- }
1196
- }
1197
- if (!this.allowCustom) {
1198
- if (hasFocused) {
1199
- this.selectionService.change(focused);
1200
- }
1201
- else if (textHasChanged) {
1202
- this.change(text, true);
1203
- }
1204
- }
1205
- }
1206
- /**
1207
- * @hidden
1208
- */
1209
- handleFocus() {
1210
- this.zone.run(() => {
1211
- if (!this.isFocused && hasObservers(this.onFocus)) {
1212
- this.onFocus.emit();
1213
- }
1214
- this.isFocused = true;
1215
- });
1216
- }
1217
- /**
1218
- * @hidden
1219
- */
1220
- handleBlur() {
1221
- if (!this.isActionSheetExpanded) {
1222
- this.blurComponent();
1223
- }
1224
- }
1225
- /**
1226
- * @hidden
1227
- */
1228
- handleInputBlur() {
1229
- if (!this.isActionSheetExpanded) {
1230
- this._filtering = false;
1231
- this.searchbar.input.nativeElement.scrollLeft = 0; // Firefox doesn't auto-scroll to the left on blur like other browsers
1232
- const unresolvedSelection = getter(this.dataItem, this.valueField) !== getter(this.value, this.valueField);
1233
- const currentText = this.searchbar.value;
1234
- const textHasChanged = currentText !== (getter(this.dataItem, this.textField) || '');
1235
- const valueHasChanged = unresolvedSelection || textHasChanged;
1236
- const runInZone = valueHasChanged ||
1237
- hasObservers(this.onBlur) ||
1238
- hasObservers(this.close) ||
1239
- isUntouched(this.wrapper.nativeElement) ||
1240
- this.formControl?.updateOn === 'blur';
1241
- if (runInZone) {
1242
- this.zone.run(() => {
1243
- if (valueHasChanged) {
1244
- const lowerCaseMatch = isPresent(this.focusedItemText) && this.focusedItemText.toLowerCase() === currentText.toLowerCase();
1245
- if (lowerCaseMatch || unresolvedSelection) {
1246
- this.selectionService.change(this.selectionService.focused);
1247
- }
1248
- else {
1249
- this.change(currentText, true);
1250
- }
1251
- }
1252
- this.inputBlur.emit();
1253
- this.onTouchedCallback();
1254
- this.togglePopup(false);
1255
- });
1256
- }
1257
- else {
1258
- this.togglePopup(false);
1259
- }
1260
- }
1261
- }
1262
- /**
1263
- * @hidden
1264
- */
1265
- handleEscape() {
1266
- this.isOpen ? this.togglePopup(false) : this.clearValue();
1267
- // clear the focus only if the focused item is not selected
1268
- const hasSelected = this.selectionService.selected.length > 0;
1269
- if (!hasSelected) {
1270
- this.suggestedText = null;
1271
- this.selectionService.focused = -1;
1272
- }
1273
- hasObservers(this.escape) && this.escape.emit();
1274
- }
1275
- /**
1276
- * @hidden
1277
- */
1278
- handleNavigationOpen() {
1279
- this.restoreItemFocus();
1280
- this.togglePopup(true);
1281
- }
1282
- /**
1283
- * @hidden
1284
- */
1285
- searchBarChange(text) {
1286
- const currentTextLength = this.text ? this.text.length : 0;
1287
- this.backspacePressed = Boolean(text.length < currentTextLength);
1288
- this.text = text;
1289
- // Reset the selection prior to filter. If a match is present, it will be resolved. If a match is not present, it is not needed.
1290
- this.selectionService.resetSelection([]);
1291
- this.togglePopup(true);
1292
- this._filtering = true;
1293
- if (this.filterable && this.filterText !== text) {
1294
- this.filterText = text;
1295
- this.filterChange.emit(text);
1296
- }
1297
- else {
1298
- this.search(text);
1299
- }
1300
- }
1301
- /**
1302
- * @hidden
1303
- */
1304
- handleInputFocus() {
1305
- this.handleFocus();
1306
- if (hasObservers(this.inputFocus)) {
1307
- this.zone.run(() => this.inputFocus.emit());
1308
- }
1309
- }
1310
- /**
1311
- * @hidden
1312
- */
1313
- pageChange(event) {
1314
- const virtual = this.virtual;
1315
- virtual.skip = event.skip;
1316
- }
1317
- /**
1318
- * @hidden
1319
- */
1320
- closeActionSheet() {
1321
- this.blurComponent();
1322
- this.closed.emit();
1323
- }
1324
- change(candidate, isCustom = false) {
1325
- if (isCustom) {
1326
- this.customValueSubject.next(candidate);
1327
- }
1328
- else {
1329
- this.valueSubject.next(candidate);
1330
- if (this.isActionSheetExpanded) {
1331
- this.togglePopup(false);
1332
- }
1333
- }
1334
- }
1335
- emitValueChange() {
1336
- this.onChangeCallback(this.value);
1337
- this.valueChange.emit(this.value);
1338
- this._previousDataItem = this.dataItem;
1339
- }
1340
- /**
1341
- * @hidden
1342
- */
1343
- selectClick() {
1344
- if (!touchEnabled) {
1345
- this.searchbar.focus();
1346
- this.isFocused = true;
1347
- }
1348
- if (!this.isOpen) {
1349
- this.restoreItemFocus();
1350
- }
1351
- this.togglePopup(!this.isOpen);
1352
- }
1353
- get listContainerClasses() {
1354
- const containerClasses = ['k-list-container', 'k-combobox-popup'];
1355
- if (!this.popupSettings.popupClass) {
1356
- return containerClasses;
1357
- }
1358
- const parsedPopupClasses = parseCSSClassNames(this.popupSettings.popupClass);
1359
- if (parsedPopupClasses?.length) {
1360
- containerClasses.push(...parsedPopupClasses);
1361
- }
1362
- return containerClasses;
1363
- }
1364
- /**
1365
- * @hidden
1366
- */
1367
- preventEventDefault(event) {
1368
- event.preventDefault();
1369
- }
1370
- get focusedItemText() {
1371
- const focused = this.selectionService.focused;
1372
- if (!isPresent(focused) || focused === -1) {
1373
- return null;
1374
- }
1375
- const itemText = getter(this.dataService.itemAt(focused), this.textField);
1376
- return !isPresent(itemText) ? "" : itemText.toString();
1377
- }
1378
- /**
1379
- * Focuses the first match when there's text in the input field, but no focused item.
1380
- */
1381
- restoreItemFocus() {
1382
- const hasFocus = isPresent(this.selectionService.focused) && this.selectionService.focused > -1;
1383
- if (!hasFocus && this.text && this.dataService.itemsCount) {
1384
- if (this.filterable) {
1385
- this.selectionService.focused = this.firstFocusableIndex(0);
1386
- }
1387
- else {
1388
- this.search(this.text);
1389
- }
1390
- }
1391
- }
1392
- useSuggestion() {
1393
- if (!(this.suggest && isPresent(this.searchbar.value))) {
1394
- return false;
1395
- }
1396
- const focusedDataItem = this.dataService.itemAt(this.selectionService.focused);
1397
- const focusedItemText = getter(focusedDataItem, this.textField);
1398
- if (!isPresent(focusedItemText)) {
1399
- return false;
1400
- }
1401
- return this.searchbar.value.toLowerCase() === focusedItemText.toLowerCase();
1402
- }
1403
- destroyPopup() {
1404
- if (this.popupRef) {
1405
- this.popupRef.popupElement
1406
- .removeEventListener('mousedown', this.popupMouseDownHandler);
1407
- this.popupRef.close();
1408
- this.popupRef = null;
1409
- }
1410
- }
1411
- createPopup() {
1412
- if (this.virtual) {
1413
- this.virtual.skip = 0;
1414
- }
1415
- this.windowSize = this.adaptiveService.size;
1416
- if (this.isAdaptive) {
1417
- this.openActionSheet();
1418
- return;
1419
- }
1420
- const horizontalAlign = this.direction === "rtl" ? "right" : "left";
1421
- const anchorPosition = { horizontal: horizontalAlign, vertical: "bottom" };
1422
- const popupPosition = { horizontal: horizontalAlign, vertical: "top" };
1423
- const appendToComponent = typeof this.popupSettings.appendTo === 'string' && this.popupSettings.appendTo === 'component';
1424
- this.popupRef = this.popupService.open({
1425
- anchor: this.wrapper,
1426
- animate: this.popupSettings.animate,
1427
- appendTo: this.appendTo,
1428
- content: this.popupTemplate,
1429
- popupClass: this.listContainerClasses,
1430
- positionMode: appendToComponent ? 'fixed' : 'absolute',
1431
- anchorAlign: anchorPosition,
1432
- popupAlign: popupPosition
1433
- });
1434
- const popupWrapper = this.popupRef.popupElement;
1435
- const { min, max } = this.popupWidth;
1436
- popupWrapper.addEventListener('mousedown', this.popupMouseDownHandler);
1437
- popupWrapper.style.minWidth = min;
1438
- popupWrapper.style.width = max;
1439
- popupWrapper.style.height = this.popupHeight;
1440
- popupWrapper.setAttribute('dir', this.direction);
1441
- if (!this.appendTo) {
1442
- this.renderer.setAttribute(popupWrapper, 'role', 'region');
1443
- this.renderer.setAttribute(popupWrapper, 'aria-label', this.messageFor('popupLabel'));
1444
- }
1445
- this.popupRef.popupOpen.subscribe(() => {
1446
- this.cdr.detectChanges();
1447
- if (!this.dataService.grouped) {
1448
- setListBoxAriaLabelledBy(this.optionsList, this.searchbar.input, this.renderer);
1449
- }
1450
- this.optionsList.scrollToItem(this.selectionService.focused);
1451
- this.selectionService.focus(this.selectionService.focused);
1452
- this.opened.emit();
1453
- });
1454
- this.popupRef.popupClose.subscribe(() => {
1455
- this.closed.emit();
1456
- });
1457
- this.popupRef.popupAnchorViewportLeave.subscribe(() => this.togglePopup(false));
1458
- }
1459
- _toggle(open) {
1460
- this._open = open;
1461
- this.destroyPopup();
1462
- if (this.isActionSheetExpanded) {
1463
- this.actionSheet.toggle(false);
1464
- this.focus();
1465
- }
1466
- if (this._open) {
1467
- this.windowSize = this.adaptiveService.size;
1468
- this.createPopup();
1469
- }
1470
- }
1471
- triggerPopupEvents(open) {
1472
- const eventArgs = new PreventableEvent();
1473
- if (open) {
1474
- this.open.emit(eventArgs);
1475
- }
1476
- else {
1477
- this.close.emit(eventArgs);
1478
- }
1479
- return eventArgs.isDefaultPrevented();
1480
- }
1481
- clearFilter() {
1482
- if (!(this.filterable && this.filterText)) {
1483
- return;
1484
- }
1485
- this.filterText = '';
1486
- this.filterChange.emit(this.filterText);
1487
- }
1488
- subscribeTouchEvents() {
1489
- if (!isDocumentAvailable() || !touchEnabled) {
1490
- return;
1491
- }
1492
- this.zone.runOutsideAngular(() =>
1493
- // Roll up ComboBox on iOS when tapped outside
1494
- this.touchstartDisposeHandler = this.renderer.listen(document, 'touchstart', (e) => {
1495
- const target = e.target;
1496
- const isInDropDown = inDropDown(this.wrapper, target, this.popupRef);
1497
- if (this.isFocused && !isInDropDown) {
1498
- // Close popup and mobile keyboard if searchbar is focused
1499
- this.zone.run(() => this.blur());
1500
- }
1501
- else if (this.isOpen && !isInDropDown) {
1502
- // Close popup if the popup is opened via the select click
1503
- this.zone.run(() => this.togglePopup(false));
1504
- }
1505
- }));
1506
- }
1507
- attachSelectClickHandler() {
1508
- const selectElement = this.select.nativeElement;
1509
- const event = pointers ? 'pointerdown' : 'click';
1510
- this.selectClickDisposeHandler = this.renderer.listen(selectElement, event, this.selectClick.bind(this));
1511
- }
1512
- setComponentClasses() {
1513
- if (this.size !== 'none') {
1514
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('input', this.size));
1515
- }
1516
- if (this.rounded !== 'none') {
1517
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
1518
- }
1519
- if (this.fillMode !== 'none') {
1520
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('input', this.fillMode));
1521
- }
1522
- }
1523
- findIndex(value, startFrom = 0) {
1524
- let index;
1525
- if (value && value.length && this.dataService.itemsCount) {
1526
- index = this.dataService.findIndex(this.findIndexPredicate(value), startFrom);
1527
- }
1528
- else {
1529
- index = -1;
1530
- }
1531
- return index;
1532
- }
1533
- openActionSheet() {
1534
- this.windowSize = this.adaptiveService.size;
1535
- this.actionSheet.toggle(true);
1536
- this.cdr.detectChanges();
1537
- if (!this.dataService.grouped) {
1538
- setListBoxAriaLabelledBy(this.optionsList, this.searchbar.input, this.renderer);
1539
- }
1540
- this.adaptiveTitle = setActionSheetTitle(this.searchbar.input, this.adaptiveTitle);
1541
- this.cdr.detectChanges();
1542
- this.opened.emit();
1543
- this.optionsList.scrollToItem(this.selectionService.focused);
1544
- this.selectionService.focus(this.selectionService.focused);
1545
- this.actionSheetSearchBar.focus();
1546
- }
1547
- blurComponent() {
1548
- this._filtering = false;
1549
- this.searchbar.input.nativeElement.scrollLeft = 0; // Firefox doesn't auto-scroll to the left on blur like other browsers
1550
- this.isFocused = false;
1551
- const unresolvedSelection = getter(this.dataItem, this.valueField) !== getter(this.value, this.valueField);
1552
- const currentText = this.searchbar.value;
1553
- const textHasChanged = currentText !== (getter(this.dataItem, this.textField) || '');
1554
- const valueHasChanged = unresolvedSelection || textHasChanged;
1555
- const runInZone = valueHasChanged ||
1556
- hasObservers(this.onBlur) ||
1557
- hasObservers(this.close) ||
1558
- isUntouched(this.wrapper.nativeElement);
1559
- if (runInZone) {
1560
- this.zone.run(() => {
1561
- if (valueHasChanged) {
1562
- const lowerCaseMatch = isPresent(this.focusedItemText) && this.focusedItemText.toLowerCase() === currentText.toLowerCase();
1563
- if (lowerCaseMatch || unresolvedSelection) {
1564
- this.selectionService.change(this.selectionService.focused);
1565
- }
1566
- else {
1567
- this.change(currentText, true);
1568
- }
1569
- }
1570
- this.onBlur.emit();
1571
- this.onTouchedCallback();
1572
- this.togglePopup(false);
1573
- });
1574
- }
1575
- else {
1576
- this.togglePopup(false);
1577
- }
1578
- }
1579
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComboBoxComponent, deps: [{ token: i0.ElementRef }, { token: i1.LocalizationService }, { token: i2.PopupService }, { token: i3.SelectionService }, { token: i4.NavigationService }, { token: i5.DisabledItemsService }, { token: i6.DataService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.Injector }, { token: i0.ElementRef }, { token: i7.AdaptiveService }], target: i0.ɵɵFactoryTarget.Component });
1580
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComboBoxComponent, isStandalone: true, selector: "kendo-combobox", inputs: { icon: "icon", svgIcon: "svgIcon", inputAttributes: "inputAttributes", showStickyHeader: "showStickyHeader", focusableId: "focusableId", allowCustom: "allowCustom", data: "data", value: "value", textField: "textField", valueField: "valueField", valuePrimitive: "valuePrimitive", valueNormalizer: "valueNormalizer", placeholder: "placeholder", adaptiveMode: "adaptiveMode", adaptiveTitle: "adaptiveTitle", adaptiveSubtitle: "adaptiveSubtitle", popupSettings: "popupSettings", listHeight: "listHeight", loading: "loading", suggest: "suggest", clearButton: "clearButton", disabled: "disabled", itemDisabled: "itemDisabled", readonly: "readonly", tabindex: "tabindex", tabIndex: "tabIndex", filterable: "filterable", virtual: "virtual", size: "size", rounded: "rounded", fillMode: "fillMode" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange", filterChange: "filterChange", open: "open", opened: "opened", close: "close", closed: "closed", onFocus: "focus", onBlur: "blur", inputFocus: "inputFocus", inputBlur: "inputBlur", escape: "escape" }, host: { properties: { "class.k-readonly": "this.readonly", "class.k-combobox": "this.widgetClasses", "class.k-input": "this.widgetClasses", "class.k-disabled": "this.isDisabled", "class.k-loading": "this.isLoading", "attr.dir": "this.dir" } }, providers: [
1581
- COMBOBOX_VALUE_ACCESSOR,
1582
- DataService,
1583
- SelectionService,
1584
- NavigationService,
1585
- DisabledItemsService,
1586
- LocalizationService,
1587
- {
1588
- provide: L10N_PREFIX,
1589
- useValue: 'kendo.combobox'
1590
- },
1591
- {
1592
- provide: FilterableComponent, useExisting: forwardRef(() => ComboBoxComponent)
1593
- },
1594
- {
1595
- provide: KendoInput, useExisting: forwardRef(() => ComboBoxComponent)
1596
- },
1597
- {
1598
- provide: MultiTabStop, useExisting: forwardRef(() => ComboBoxComponent)
1599
- }
1600
- ], queries: [{ propertyName: "template", first: true, predicate: ItemTemplateDirective, descendants: true }, { propertyName: "headerTemplate", first: true, predicate: HeaderTemplateDirective, descendants: true }, { propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "noDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "groupTemplate", first: true, predicate: GroupTemplateDirective, descendants: true }, { propertyName: "fixedGroupTemplate", first: true, predicate: FixedGroupTemplateDirective, descendants: true }, { propertyName: "suffixTemplate", first: true, predicate: SuffixTemplateDirective, descendants: true }, { propertyName: "prefixTemplate", first: true, predicate: PrefixTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "adaptiveRendererComponent", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, static: true }, { propertyName: "searchbar", first: true, predicate: SearchBarComponent, descendants: true, static: true }, { propertyName: "optionsList", first: true, predicate: ["optionsList"], descendants: true }, { propertyName: "select", first: true, predicate: ["select"], descendants: true, static: true }], exportAs: ["kendoComboBox"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
1601
- <ng-container kendoComboBoxLocalizedMessages
1602
- i18n-noDataText="kendo.combobox.noDataText|The text displayed in the popup when there are no items"
1603
- noDataText="NO DATA FOUND"
1604
-
1605
- i18n-clearTitle="kendo.combobox.clearTitle|The title of the clear button"
1606
- clearTitle="clear"
1607
-
1608
- i18n-selectButtonText="kendo.combobox.selectButtonText|The text set as aria-label on the select button"
1609
- selectButtonText="Select"
1610
-
1611
- i18n-popupLabel="kendo.combobox.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
1612
- popupLabel="Options list"
1613
-
1614
- i18n-adaptiveCloseButtonTitle="kendo.combobox.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode"
1615
- adaptiveCloseButtonTitle="Close"
1616
- >
1617
- </ng-container>
1618
-
1619
- <ng-container
1620
- kendoDropDownSharedEvents
1621
- [hostElement]="hostElement"
1622
- [(isFocused)]="isFocused"
1623
- (handleBlur)="handleBlur()"
1624
- (onFocus)="handleFocus()"
1625
- >
1626
- @if (prefixTemplate) {
1627
- <span class="k-input-prefix k-input-prefix-horizontal">
1628
- <ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
1629
- </ng-template>
1630
- </span>
1631
- }
1632
- @if (prefixTemplate && prefixTemplate.showSeparator) {
1633
- <kendo-separator></kendo-separator>
1634
- }
1635
- <input
1636
- kendoSearchbar
1637
- [ariaExpanded]="isOpen"
1638
- [ariaControls]="ariaControls"
1639
- [id]="focusableId"
1640
- [isLoading]="loading"
1641
- [isSuggestable]="suggest"
1642
- [isFilterable]="filterable"
1643
- [activeDescendant]="activeDescendant"
1644
- [userInput]="text"
1645
- [suggestedText]="getSuggestion()"
1646
- [disabled]="disabled"
1647
- [readonly]="readonly || isAdaptive"
1648
- [tabIndex]="tabIndex"
1649
- [isRequired]="isControlRequired"
1650
- [placeholder]="placeholder"
1651
- [inputAttributes]="inputAttributes"
1652
- (onNavigate)="handleNavigate($event)"
1653
- (valueChange)="searchBarChange($event)"
1654
- (onBlur)="handleInputBlur()"
1655
- (onFocus)="handleInputFocus()"
1656
- (click)="handleClick()"
1657
- />
1658
- @if (clearButton && !loading && !disabled && !readonly && text?.length) {
1659
- <span
1660
- class="k-clear-value"
1661
- [style.visibility]="clearButtonVisibility"
1662
- aria-hidden="true"
1663
- [attr.title]="messageFor('clearTitle')"
1664
- (click)="clearValue($event)"
1665
- [kendoEventsOutsideAngular]="{
1666
- mousedown: preventEventDefault
1667
- }"
1668
- >
1669
- <kendo-icon-wrapper
1670
- name="x"
1671
- [svgIcon]="xIcon"
1672
- >
1673
- </kendo-icon-wrapper>
1674
- </span>
1675
- }
1676
- @if (loading) {
1677
- <span class="k-i-loading k-input-loading-icon k-icon"></span>
1678
- }
1679
- @if (suffixTemplate && suffixTemplate.showSeparator) {
1680
- <kendo-separator></kendo-separator>
1681
- }
1682
- @if (suffixTemplate) {
1683
- <span class="k-input-suffix k-input-suffix-horizontal">
1684
- <ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
1685
- </ng-template>
1686
- </span>
1687
- }
1688
- <button
1689
- #select
1690
- tabindex="-1"
1691
- unselectable="on"
1692
- type="button"
1693
- class="k-input-button k-button k-icon-button"
1694
- [ngClass]="selectButtonClasses"
1695
- [attr.aria-label]="messageFor('selectButtonText')"
1696
- [attr.disabled]="disabled ? '' : null"
1697
- (keydown.enter)="$event.stopImmediatePropagation();"
1698
- [kendoEventsOutsideAngular]="{
1699
- mousedown: preventEventDefault
1700
- }"
1701
- >
1702
- <kendo-icon-wrapper
1703
- [name]="icon || 'caret-alt-down'"
1704
- innerCssClass="k-button-icon"
1705
- [svgIcon]="svgIcon || caretAltDownIcon"
1706
- >
1707
- </kendo-icon-wrapper>
1708
- </button>
1709
- </ng-container>
1710
-
1711
- <ng-template #popupTemplate>
1712
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
1713
- </ng-template>
1714
- @if (isOpen || isAdaptiveModeEnabled) {
1715
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
1716
- }
1717
- <ng-container #container></ng-container>
1718
-
1719
- <kendo-adaptive-renderer
1720
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
1721
- [title]="adaptiveTitle"
1722
- [showTextInput]="true"
1723
- [subtitle]="adaptiveSubtitle"
1724
- (closePopup)="closeActionSheet()"
1725
- (textInputChange)="searchBarChange($event)"
1726
- (navigate)="handleNavigate($event)"
1727
- [placeholder]="placeholder"
1728
- [searchBarValue]="text"
1729
- >
1730
- </kendo-adaptive-renderer>
1731
- <ng-template #sharedPopupActionSheetTemplate>
1732
- <!--header template-->
1733
- @if (headerTemplate) {
1734
- <ng-template
1735
- [templateContext]="{
1736
- templateRef: headerTemplate.templateRef
1737
- }">
1738
- </ng-template>
1739
- }
1740
- <!--list-->
1741
- <kendo-list
1742
- #optionsList
1743
- [size]="isAdaptive ? 'large' : size"
1744
- [rounded]="rounded"
1745
- [id]="listBoxId"
1746
- [optionPrefix]="optionPrefix"
1747
- [data]="data"
1748
- [textField]="textField"
1749
- [valueField]="valueField"
1750
- [template]="template"
1751
- [groupTemplate]="groupTemplate"
1752
- [fixedGroupTemplate]="fixedGroupTemplate"
1753
- [height]="listHeight"
1754
- [show]="isOpen"
1755
- [virtual]="virtual"
1756
- [showStickyHeader]="showStickyHeader"
1757
- (pageChange)="pageChange($event)"
1758
- >
1759
- </kendo-list>
1760
- <!--no-data template-->
1761
- @if (data.length === 0) {
1762
- <div class="k-no-data">
1763
- @if (noDataTemplate) {
1764
- <ng-template
1765
- [templateContext]="{
1766
- templateRef: noDataTemplate ? noDataTemplate.templateRef : undefined
1767
- }">
1768
- </ng-template>
1769
- }
1770
- @if (!noDataTemplate) {
1771
- <div>{{ messageFor('noDataText') }}</div>
1772
- }
1773
- </div>
1774
- }
1775
- <!--footer template-->
1776
- @if (footerTemplate) {
1777
- <ng-template
1778
- [templateContext]="{
1779
- templateRef: footerTemplate.templateRef
1780
- }">
1781
- </ng-template>
1782
- }
1783
- </ng-template>
1784
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoDropDownListLocalizedMessages],\n [kendoDropDownTreeLocalizedMessages],\n [kendoComboBoxLocalizedMessages],\n [kendoMultiColumnComboBoxLocalizedMessages],\n [kendoAutoCompleteLocalizedMessages],\n [kendoMultiSelectLocalizedMessages],\n [kendoMultiSelectTreeLocalizedMessages]\n " }, { kind: "directive", type: SharedDropDownEventsDirective, selector: "[kendoDropDownSharedEvents]", inputs: ["hostElement", "clearButtonClicked", "isFocused"], outputs: ["isFocusedChange", "onFocus", "handleBlur"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SeparatorComponent, selector: "kendo-separator", inputs: ["orientation"] }, { kind: "component", type: SearchBarComponent, selector: "input[kendoSearchbar]", inputs: ["tagListId", "readonly", "disabled", "isRequired", "isSuggestable", "isFilterable", "userInput", "suggestedText", "inputAttributes", "id", "activeDescendant", "tabIndex", "isLoading", "ariaControls", "ariaExpanded", "placeholder"], outputs: ["valueChange", "onBlur", "onFocus", "onClick", "onNavigate"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "component", type: AdaptiveRendererComponent, selector: "kendo-adaptive-renderer", inputs: ["title", "subtitle", "showTextInput", "sharedPopupActionSheetTemplate", "text", "placeholder", "searchBarValue", "filterable"], outputs: ["closePopup", "textInputChange", "navigate", "onExpand"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: ListComponent, selector: "kendo-list", inputs: ["selected", "focused", "textField", "valueField", "height", "template", "groupTemplate", "fixedGroupTemplate", "show", "id", "optionPrefix", "multipleSelection", "virtual", "type", "checkboxes", "ariaLive", "isMultiselect", "isActionSheetExpanded", "showStickyHeader", "rowWidth", "customItemTemplate", "text", "allowCustom", "defaultItem", "data", "size", "rounded"], outputs: ["onClick", "pageChange", "listResize", "popupListScroll"] }] });
1785
- }
1786
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComboBoxComponent, decorators: [{
1787
- type: Component,
1788
- args: [{
1789
- exportAs: 'kendoComboBox',
1790
- providers: [
1791
- COMBOBOX_VALUE_ACCESSOR,
1792
- DataService,
1793
- SelectionService,
1794
- NavigationService,
1795
- DisabledItemsService,
1796
- LocalizationService,
1797
- {
1798
- provide: L10N_PREFIX,
1799
- useValue: 'kendo.combobox'
1800
- },
1801
- {
1802
- provide: FilterableComponent, useExisting: forwardRef(() => ComboBoxComponent)
1803
- },
1804
- {
1805
- provide: KendoInput, useExisting: forwardRef(() => ComboBoxComponent)
1806
- },
1807
- {
1808
- provide: MultiTabStop, useExisting: forwardRef(() => ComboBoxComponent)
1809
- }
1810
- ],
1811
- selector: 'kendo-combobox',
1812
- template: `
1813
- <ng-container kendoComboBoxLocalizedMessages
1814
- i18n-noDataText="kendo.combobox.noDataText|The text displayed in the popup when there are no items"
1815
- noDataText="NO DATA FOUND"
1816
-
1817
- i18n-clearTitle="kendo.combobox.clearTitle|The title of the clear button"
1818
- clearTitle="clear"
1819
-
1820
- i18n-selectButtonText="kendo.combobox.selectButtonText|The text set as aria-label on the select button"
1821
- selectButtonText="Select"
1822
-
1823
- i18n-popupLabel="kendo.combobox.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
1824
- popupLabel="Options list"
1825
-
1826
- i18n-adaptiveCloseButtonTitle="kendo.combobox.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode"
1827
- adaptiveCloseButtonTitle="Close"
1828
- >
1829
- </ng-container>
1830
-
1831
- <ng-container
1832
- kendoDropDownSharedEvents
1833
- [hostElement]="hostElement"
1834
- [(isFocused)]="isFocused"
1835
- (handleBlur)="handleBlur()"
1836
- (onFocus)="handleFocus()"
1837
- >
1838
- @if (prefixTemplate) {
1839
- <span class="k-input-prefix k-input-prefix-horizontal">
1840
- <ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
1841
- </ng-template>
1842
- </span>
1843
- }
1844
- @if (prefixTemplate && prefixTemplate.showSeparator) {
1845
- <kendo-separator></kendo-separator>
1846
- }
1847
- <input
1848
- kendoSearchbar
1849
- [ariaExpanded]="isOpen"
1850
- [ariaControls]="ariaControls"
1851
- [id]="focusableId"
1852
- [isLoading]="loading"
1853
- [isSuggestable]="suggest"
1854
- [isFilterable]="filterable"
1855
- [activeDescendant]="activeDescendant"
1856
- [userInput]="text"
1857
- [suggestedText]="getSuggestion()"
1858
- [disabled]="disabled"
1859
- [readonly]="readonly || isAdaptive"
1860
- [tabIndex]="tabIndex"
1861
- [isRequired]="isControlRequired"
1862
- [placeholder]="placeholder"
1863
- [inputAttributes]="inputAttributes"
1864
- (onNavigate)="handleNavigate($event)"
1865
- (valueChange)="searchBarChange($event)"
1866
- (onBlur)="handleInputBlur()"
1867
- (onFocus)="handleInputFocus()"
1868
- (click)="handleClick()"
1869
- />
1870
- @if (clearButton && !loading && !disabled && !readonly && text?.length) {
1871
- <span
1872
- class="k-clear-value"
1873
- [style.visibility]="clearButtonVisibility"
1874
- aria-hidden="true"
1875
- [attr.title]="messageFor('clearTitle')"
1876
- (click)="clearValue($event)"
1877
- [kendoEventsOutsideAngular]="{
1878
- mousedown: preventEventDefault
1879
- }"
1880
- >
1881
- <kendo-icon-wrapper
1882
- name="x"
1883
- [svgIcon]="xIcon"
1884
- >
1885
- </kendo-icon-wrapper>
1886
- </span>
1887
- }
1888
- @if (loading) {
1889
- <span class="k-i-loading k-input-loading-icon k-icon"></span>
1890
- }
1891
- @if (suffixTemplate && suffixTemplate.showSeparator) {
1892
- <kendo-separator></kendo-separator>
1893
- }
1894
- @if (suffixTemplate) {
1895
- <span class="k-input-suffix k-input-suffix-horizontal">
1896
- <ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
1897
- </ng-template>
1898
- </span>
1899
- }
1900
- <button
1901
- #select
1902
- tabindex="-1"
1903
- unselectable="on"
1904
- type="button"
1905
- class="k-input-button k-button k-icon-button"
1906
- [ngClass]="selectButtonClasses"
1907
- [attr.aria-label]="messageFor('selectButtonText')"
1908
- [attr.disabled]="disabled ? '' : null"
1909
- (keydown.enter)="$event.stopImmediatePropagation();"
1910
- [kendoEventsOutsideAngular]="{
1911
- mousedown: preventEventDefault
1912
- }"
1913
- >
1914
- <kendo-icon-wrapper
1915
- [name]="icon || 'caret-alt-down'"
1916
- innerCssClass="k-button-icon"
1917
- [svgIcon]="svgIcon || caretAltDownIcon"
1918
- >
1919
- </kendo-icon-wrapper>
1920
- </button>
1921
- </ng-container>
1922
-
1923
- <ng-template #popupTemplate>
1924
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
1925
- </ng-template>
1926
- @if (isOpen || isAdaptiveModeEnabled) {
1927
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
1928
- }
1929
- <ng-container #container></ng-container>
1930
-
1931
- <kendo-adaptive-renderer
1932
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
1933
- [title]="adaptiveTitle"
1934
- [showTextInput]="true"
1935
- [subtitle]="adaptiveSubtitle"
1936
- (closePopup)="closeActionSheet()"
1937
- (textInputChange)="searchBarChange($event)"
1938
- (navigate)="handleNavigate($event)"
1939
- [placeholder]="placeholder"
1940
- [searchBarValue]="text"
1941
- >
1942
- </kendo-adaptive-renderer>
1943
- <ng-template #sharedPopupActionSheetTemplate>
1944
- <!--header template-->
1945
- @if (headerTemplate) {
1946
- <ng-template
1947
- [templateContext]="{
1948
- templateRef: headerTemplate.templateRef
1949
- }">
1950
- </ng-template>
1951
- }
1952
- <!--list-->
1953
- <kendo-list
1954
- #optionsList
1955
- [size]="isAdaptive ? 'large' : size"
1956
- [rounded]="rounded"
1957
- [id]="listBoxId"
1958
- [optionPrefix]="optionPrefix"
1959
- [data]="data"
1960
- [textField]="textField"
1961
- [valueField]="valueField"
1962
- [template]="template"
1963
- [groupTemplate]="groupTemplate"
1964
- [fixedGroupTemplate]="fixedGroupTemplate"
1965
- [height]="listHeight"
1966
- [show]="isOpen"
1967
- [virtual]="virtual"
1968
- [showStickyHeader]="showStickyHeader"
1969
- (pageChange)="pageChange($event)"
1970
- >
1971
- </kendo-list>
1972
- <!--no-data template-->
1973
- @if (data.length === 0) {
1974
- <div class="k-no-data">
1975
- @if (noDataTemplate) {
1976
- <ng-template
1977
- [templateContext]="{
1978
- templateRef: noDataTemplate ? noDataTemplate.templateRef : undefined
1979
- }">
1980
- </ng-template>
1981
- }
1982
- @if (!noDataTemplate) {
1983
- <div>{{ messageFor('noDataText') }}</div>
1984
- }
1985
- </div>
1986
- }
1987
- <!--footer template-->
1988
- @if (footerTemplate) {
1989
- <ng-template
1990
- [templateContext]="{
1991
- templateRef: footerTemplate.templateRef
1992
- }">
1993
- </ng-template>
1994
- }
1995
- </ng-template>
1996
- `,
1997
- standalone: true,
1998
- imports: [LocalizedMessagesDirective, SharedDropDownEventsDirective, NgTemplateOutlet, SeparatorComponent, SearchBarComponent, EventsOutsideAngularDirective, IconWrapperComponent, NgClass, ResizeSensorComponent, AdaptiveRendererComponent, TemplateContextDirective, ListComponent]
1999
- }]
2000
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.LocalizationService }, { type: i2.PopupService }, { type: i3.SelectionService }, { type: i4.NavigationService }, { type: i5.DisabledItemsService }, { type: i6.DataService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.Injector }, { type: i0.ElementRef }, { type: i7.AdaptiveService }], propDecorators: { icon: [{
2001
- type: Input
2002
- }], svgIcon: [{
2003
- type: Input
2004
- }], inputAttributes: [{
2005
- type: Input
2006
- }], adaptiveRendererComponent: [{
2007
- type: ViewChild,
2008
- args: [AdaptiveRendererComponent]
2009
- }], showStickyHeader: [{
2010
- type: Input
2011
- }], focusableId: [{
2012
- type: Input
2013
- }], allowCustom: [{
2014
- type: Input
2015
- }], data: [{
2016
- type: Input
2017
- }], value: [{
2018
- type: Input
2019
- }], textField: [{
2020
- type: Input
2021
- }], valueField: [{
2022
- type: Input
2023
- }], valuePrimitive: [{
2024
- type: Input
2025
- }], valueNormalizer: [{
2026
- type: Input
2027
- }], placeholder: [{
2028
- type: Input
2029
- }], adaptiveMode: [{
2030
- type: Input
2031
- }], adaptiveTitle: [{
2032
- type: Input
2033
- }], adaptiveSubtitle: [{
2034
- type: Input
2035
- }], popupSettings: [{
2036
- type: Input
2037
- }], listHeight: [{
2038
- type: Input
2039
- }], loading: [{
2040
- type: Input
2041
- }], suggest: [{
2042
- type: Input
2043
- }], clearButton: [{
2044
- type: Input
2045
- }], disabled: [{
2046
- type: Input
2047
- }], itemDisabled: [{
2048
- type: Input
2049
- }], readonly: [{
2050
- type: Input
2051
- }, {
2052
- type: HostBinding,
2053
- args: ['class.k-readonly']
2054
- }], tabindex: [{
2055
- type: Input
2056
- }], tabIndex: [{
2057
- type: Input,
2058
- args: ["tabIndex"]
2059
- }], filterable: [{
2060
- type: Input
2061
- }], virtual: [{
2062
- type: Input
2063
- }], size: [{
2064
- type: Input
2065
- }], rounded: [{
2066
- type: Input
2067
- }], fillMode: [{
2068
- type: Input
2069
- }], valueChange: [{
2070
- type: Output
2071
- }], selectionChange: [{
2072
- type: Output
2073
- }], filterChange: [{
2074
- type: Output
2075
- }], open: [{
2076
- type: Output
2077
- }], opened: [{
2078
- type: Output
2079
- }], close: [{
2080
- type: Output
2081
- }], closed: [{
2082
- type: Output
2083
- }], onFocus: [{
2084
- type: Output,
2085
- args: ['focus']
2086
- }], onBlur: [{
2087
- type: Output,
2088
- args: ['blur']
2089
- }], inputFocus: [{
2090
- type: Output
2091
- }], inputBlur: [{
2092
- type: Output
2093
- }], escape: [{
2094
- type: Output
2095
- }], template: [{
2096
- type: ContentChild,
2097
- args: [ItemTemplateDirective, { static: false }]
2098
- }], headerTemplate: [{
2099
- type: ContentChild,
2100
- args: [HeaderTemplateDirective, { static: false }]
2101
- }], footerTemplate: [{
2102
- type: ContentChild,
2103
- args: [FooterTemplateDirective, { static: false }]
2104
- }], noDataTemplate: [{
2105
- type: ContentChild,
2106
- args: [NoDataTemplateDirective, { static: false }]
2107
- }], groupTemplate: [{
2108
- type: ContentChild,
2109
- args: [GroupTemplateDirective, { static: false }]
2110
- }], fixedGroupTemplate: [{
2111
- type: ContentChild,
2112
- args: [FixedGroupTemplateDirective, { static: false }]
2113
- }], suffixTemplate: [{
2114
- type: ContentChild,
2115
- args: [SuffixTemplateDirective]
2116
- }], prefixTemplate: [{
2117
- type: ContentChild,
2118
- args: [PrefixTemplateDirective]
2119
- }], container: [{
2120
- type: ViewChild,
2121
- args: ['container', { read: ViewContainerRef, static: true }]
2122
- }], popupTemplate: [{
2123
- type: ViewChild,
2124
- args: ['popupTemplate', { static: true }]
2125
- }], searchbar: [{
2126
- type: ViewChild,
2127
- args: [SearchBarComponent, { static: true }]
2128
- }], optionsList: [{
2129
- type: ViewChild,
2130
- args: ['optionsList', { static: false }]
2131
- }], select: [{
2132
- type: ViewChild,
2133
- args: ['select', { static: true }]
2134
- }], widgetClasses: [{
2135
- type: HostBinding,
2136
- args: ['class.k-combobox']
2137
- }, {
2138
- type: HostBinding,
2139
- args: ['class.k-input']
2140
- }], isDisabled: [{
2141
- type: HostBinding,
2142
- args: ['class.k-disabled']
2143
- }], isLoading: [{
2144
- type: HostBinding,
2145
- args: ['class.k-loading']
2146
- }], dir: [{
2147
- type: HostBinding,
2148
- args: ['attr.dir']
2149
- }] } });