@progress/kendo-angular-dropdowns 21.4.1 → 22.0.0-develop.1

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,1967 +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 { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostBinding, Input, Output, NgZone, Renderer2, TemplateRef, ViewChild, ChangeDetectorRef, ContentChild, forwardRef, ViewContainerRef, isDevMode, Injector } from '@angular/core';
6
- import { anyChanged, EventsOutsideAngularDirective, guid, hasObservers, isChanged, isDocumentAvailable, KendoInput, Keys, parseCSSClassNames, ResizeSensorComponent, TemplateContextDirective } from '@progress/kendo-angular-common';
7
- import { AdaptiveService } from '@progress/kendo-angular-utils';
8
- import { PopupService } from '@progress/kendo-angular-popup';
9
- import { TreeViewComponent, DataBoundComponent, ExpandableComponent, SelectDirective } from '@progress/kendo-angular-treeview';
10
- import { getter, touchEnabled } from '@progress/kendo-common';
11
- import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
12
- import { DataService } from '../common/data.service';
13
- import { DisabledItemsService } from '../common/disabled-items/disabled-items.service';
14
- import { NavigationService } from '../common/navigation/navigation.service';
15
- import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
16
- import { SelectionService } from '../common/selection/selection.service';
17
- import { PreventableEvent } from '../common/models/preventable-event';
18
- import { animationDuration, getFillModeClass, getRoundedClass, getSearchableItems, getSizeClass, inDropDown, isArray, isLetter, isPresent, isTruthy, isUntouched, noop, setActionSheetTitle } from '../common/util';
19
- import { NoDataTemplateDirective } from '../common/templates/no-data-template.directive';
20
- import { of, Subject, Subscription } from 'rxjs';
21
- import { debounceTime, take, tap } from 'rxjs/operators';
22
- import { HeaderTemplateDirective } from '../common/templates/header-template.directive';
23
- import { FooterTemplateDirective } from '../common/templates/footer-template.directive';
24
- import { NodeTemplateDirective } from './templates/node-template.directive';
25
- import { DropDownTreeMessages } from '../common/constants/error-messages';
26
- import { ValueTemplateDirective } from '../common/templates/value-template.directive';
27
- import { caretAltDownIcon, searchIcon, xIcon } from '@progress/kendo-svg-icons';
28
- import { AdaptiveRendererComponent } from '../common/adaptive-renderer.component';
29
- import { FilterInputDirective } from '../common/filter-input.directive';
30
- import { NgClass, NgTemplateOutlet } from '@angular/common';
31
- import { LocalizedMessagesDirective } from '../common/localization/localized-messages.directive';
32
- import { IconWrapperComponent } from '@progress/kendo-angular-icons';
33
- import * as i0 from "@angular/core";
34
- import * as i1 from "@progress/kendo-angular-popup";
35
- import * as i2 from "../common/navigation/navigation.service";
36
- import * as i3 from "@progress/kendo-angular-l10n";
37
- import * as i4 from "@progress/kendo-angular-utils";
38
- const DEFAULT_POPUP_SETTINGS = { animate: true };
39
- const hasChildren = () => false;
40
- const fetchChildren = () => of([]);
41
- const itemDisabled = () => false;
42
- const isNodeVisible = () => true;
43
- const DEFAULT_SIZE = 'medium';
44
- const DEFAULT_ROUNDED = 'medium';
45
- const DEFAULT_FILL_MODE = 'solid';
46
- const stopPropagation = (event) => event.stopImmediatePropagation();
47
- /**
48
- * Represents the [Kendo UI DropDownTree component for Angular]({% slug overview_ddt %}).
49
- * @example
50
- * ```html
51
- * <kendo-dropdowntree [data]="data" textField="text" valueField="value"></kendo-dropdowntree>
52
- * ```
53
- *
54
- * @remarks
55
- * Supported children components are: {@link CustomMessagesComponent}.
56
- */
57
- export class DropDownTreeComponent {
58
- injector;
59
- wrapper;
60
- popupService;
61
- navigationService;
62
- renderer;
63
- _zone;
64
- cdr;
65
- localization;
66
- adaptiveService;
67
- /**
68
- * @hidden
69
- */
70
- icon;
71
- /**
72
- * @hidden
73
- */
74
- svgIcon;
75
- /**
76
- * @hidden
77
- */
78
- touchEnabled = touchEnabled;
79
- /**
80
- * @hidden
81
- */
82
- animationDuration = animationDuration;
83
- /**
84
- * @hidden
85
- */
86
- searchIcon = searchIcon;
87
- /**
88
- * @hidden
89
- */
90
- caretAltDownIcon = caretAltDownIcon;
91
- /**
92
- * @hidden
93
- */
94
- xIcon = xIcon;
95
- /**
96
- * @hidden
97
- */
98
- adaptiveRendererComponent;
99
- /**
100
- * @hidden
101
- */
102
- get actionSheet() {
103
- return this.adaptiveRendererComponent?.actionSheet;
104
- }
105
- /**
106
- * @hidden
107
- */
108
- get actionSheetSearchBar() {
109
- return this.adaptiveRendererComponent?.actionSheetSearchBar;
110
- }
111
- hostClasses = true;
112
- get isReadonly() {
113
- return this.readonly ? '' : null;
114
- }
115
- get hostAriaInvalid() {
116
- return this.formControl?.invalid ? true : null;
117
- }
118
- get isDisabled() {
119
- return this.disabled || null;
120
- }
121
- get isLoading() {
122
- return this.loading;
123
- }
124
- get isBusy() {
125
- return this.loading ? 'true' : null;
126
- }
127
- get hostAriaControls() {
128
- return this.isOpen ? this.treeViewId : null;
129
- }
130
- get id() {
131
- return this.focusableId;
132
- }
133
- direction;
134
- get hostTabIndex() {
135
- return this.tabindex;
136
- }
137
- role = 'combobox';
138
- ariaHasPopup = 'tree';
139
- get isAriaExpanded() {
140
- return this.isOpen;
141
- }
142
- get hostAriaAutocomplete() {
143
- return this.filterable ? 'list' : null;
144
- }
145
- noDataTemplate;
146
- headerTemplate;
147
- footerTemplate;
148
- nodeTemplate;
149
- valueTemplate;
150
- popupTemplate;
151
- container;
152
- set treeview(treeview) {
153
- if (treeview) {
154
- if (this.isFocused && !this.filterable || this.touchEnabled) {
155
- treeview.focus();
156
- }
157
- // the treeview animations are initially disabled (we don't want expand animations during popup opening)
158
- // re-enables the animations for user interaction
159
- treeview.animate = true;
160
- this._treeview = treeview;
161
- }
162
- }
163
- get treeview() {
164
- return this._treeview;
165
- }
166
- filterInput;
167
- /**
168
- * Fires each time the popup is about to open
169
- * ([see example]({% slug openstate_ddt %})).
170
- * This event is preventable. If you cancel it, the popup will remain closed.
171
- */
172
- open = new EventEmitter();
173
- /**
174
- * Fires after the popup has been opened.
175
- */
176
- opened = new EventEmitter();
177
- /**
178
- * Fires each time the popup is about to close
179
- * ([see example]({% slug openstate_ddt %})).
180
- * This event is preventable. If you cancel it, the popup will remain open.
181
- */
182
- close = new EventEmitter();
183
- /**
184
- * Fires after the popup has been closed.
185
- */
186
- closed = new EventEmitter();
187
- /**
188
- * Fires when the user expands a node in the popup TreeView.
189
- */
190
- nodeExpand = new EventEmitter();
191
- /**
192
- * Fires when the user collapses a node in the popup TreeView.
193
- */
194
- nodeCollapse = new EventEmitter();
195
- /**
196
- * Fires each time the user focuses the DropDownTree.
197
- */
198
- onFocus = new EventEmitter();
199
- /**
200
- * Fires each time the DropDownTree gets blurred.
201
- */
202
- onBlur = new EventEmitter();
203
- /**
204
- * Fires each time the value is changed
205
- * ([see example](slug:events_ddt)).
206
- */
207
- valueChange = new EventEmitter();
208
- /**
209
- * Fires when the value of the built-in filter input element changes.
210
- */
211
- filterChange = new EventEmitter();
212
- /**
213
- * Sets and gets the loading state of the DropDownTree.
214
- */
215
- loading;
216
- /**
217
- * If set to `true`, renders a button on hovering over the component.
218
- * Clicking this button resets the value of the component to `undefined` and triggers the `change` event.
219
- */
220
- clearButton = true;
221
- /**
222
- * Sets the data of the DropDownTree.
223
- *
224
- * > The data has to be provided in an array-like list with objects.
225
- */
226
- set data(data) {
227
- this._nodes = data;
228
- this.setState();
229
- }
230
- get data() {
231
- return this._nodes;
232
- }
233
- /**
234
- * Sets the value of the DropDownTree.
235
- * It can either be of the primitive (string, numbers) or of the complex (objects) type.
236
- * To define the type, use the `valuePrimitive` option.
237
- *
238
- */
239
- set value(newValue) {
240
- this._value = newValue;
241
- this.setState();
242
- }
243
- get value() {
244
- return this._value;
245
- }
246
- /**
247
- * The fields of the data item that provide the text content of the nodes inside the
248
- * DropDownTree ([see example]({% slug databinding_ddt %})). If the `textField`
249
- * input is set to an array, each hierarchical level uses the field that corresponds
250
- * to the same index in the array, or the last item in the array.
251
- *
252
- * > The `textField` property can be set to point to a nested property value - e.g. `category.name`.
253
- */
254
- textField;
255
- /**
256
- * The fields of the data item that provide the value of the nodes inside the
257
- * DropDownTree ([see example]({% slug databinding_ddt %})). If the `valueField`
258
- * input is set to an array, each hierarchical level uses the field that corresponds
259
- * to the same index in the array, or the last item in the array.
260
- *
261
- * > The `valueField` property can be set to point to a nested property value - e.g. `category.id`.
262
- */
263
- valueField;
264
- /**
265
- * Sets the level in the data set where the value can be found when `valueField` is an Array.
266
- * The field serves to correctly allocate a data item used when the DropDownTree is initialized with a value.
267
- */
268
- valueDepth;
269
- /**
270
- * A function which determines if a specific node has child nodes.
271
- */
272
- hasChildren = hasChildren;
273
- /**
274
- * A function which provides the child nodes for a given parent node.
275
- */
276
- fetchChildren = fetchChildren;
277
- /**
278
- * Sets the placeholder of the input element of the DropDownTree.
279
- */
280
- placeholder = "";
281
- /**
282
- * Configures the popup of the DropDownTree.
283
- *
284
- * The available options are:
285
- * - `animate: Boolean`&mdash;Controls the popup animation. By default, the open and close animations are enabled.
286
- * - `width: Number | String`&mdash;Sets the width of the popup container. By default, the width of the host element is used. If set to `auto`, the component automatically adjusts the width of the popup and no item labels are wrapped.
287
- * - `height: Number`&mdash;Sets the height of the popup container.
288
- * - `popupClass: String`&mdash;Specifies a list of CSS classes that are used to style the popup.
289
- * - `appendTo: "root" | "component" | ViewContainerRef`&mdash;Specifies the component to which the popup will be appended.
290
- */
291
- set popupSettings(settings) {
292
- this._popupSettings = Object.assign({}, DEFAULT_POPUP_SETTINGS, settings);
293
- }
294
- get popupSettings() {
295
- return this._popupSettings;
296
- }
297
- /**
298
- * Keeps the current `dataItem` object in order to resolve selection.
299
- * Needs to be provided when `value` is bound in and `valuePrimitive` is set to true.
300
- */
301
- set dataItem(item) {
302
- this._dataItem = item;
303
- this.setState();
304
- }
305
- get dataItem() {
306
- return this._dataItem ? this._dataItem : this.value;
307
- }
308
- /**
309
- * Sets the height of the options list in the popup. By default, `listHeight` is 200px.
310
- *
311
- * > The `listHeight` property affects only the list of options and not the whole popup container.
312
- * > To set the height of the popup container, use `popupSettings.height`.
313
- *
314
- * When using `adaptiveMode` and the screen size is `small` or `medium` the `listHeight` property is set to null.
315
- */
316
- set listHeight(_listHeight) {
317
- this._listHeight = _listHeight;
318
- }
319
- get listHeight() {
320
- if (this.isAdaptive) {
321
- return;
322
- }
323
- return this._listHeight;
324
- }
325
- _listHeight = 200;
326
- /**
327
- * Sets the disabled state of the component. To learn how to disable the component in reactive forms, refer to the article on [Forms Support](slug:formssupport_ddt#toc-managing-the-dropdowntree-disabled-state-in-reactive-forms).
328
- */
329
- disabled = false;
330
- /**
331
- * Sets the read-only state of the component.
332
- *
333
- * @default false
334
- */
335
- readonly = false;
336
- /**
337
- * Specifies the type of the selected value
338
- * ([more information and example]({% slug valuebinding_ddt %}#toc-primitive-values)).
339
- * If set to `true`, the selected value has to be of a primitive value.
340
- */
341
- valuePrimitive = false;
342
- /**
343
- * Specifies the [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
344
- */
345
- set tabindex(value) {
346
- const providedTabIndex = Number(value);
347
- const defaultTabIndex = 0;
348
- this._tabindex = !isNaN(providedTabIndex) ? providedTabIndex : defaultTabIndex;
349
- }
350
- get tabindex() {
351
- return this.disabled ? -1 : this._tabindex;
352
- }
353
- /**
354
- * Sets the size of the component.
355
- *
356
- * The possible values are:
357
- * * `small`
358
- * * `medium` (default)
359
- * * `large`
360
- * * `none`
361
- *
362
- */
363
- set size(size) {
364
- const newSize = size ? size : DEFAULT_SIZE;
365
- this.renderer.removeClass(this.wrapper.nativeElement, getSizeClass('picker', this.size));
366
- if (size !== 'none') {
367
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('picker', newSize));
368
- }
369
- this._size = newSize;
370
- }
371
- get size() {
372
- return this._size;
373
- }
374
- /**
375
- * Sets the border radius of the component.
376
- *
377
- * The possible values are:
378
- * * `small`
379
- * * `medium` (default)
380
- * * `large`
381
- * * `full`
382
- * * `none`
383
- *
384
- */
385
- set rounded(rounded) {
386
- const newRounded = rounded ? rounded : DEFAULT_ROUNDED;
387
- this.renderer.removeClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
388
- if (rounded !== 'none') {
389
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(newRounded));
390
- }
391
- this._rounded = newRounded;
392
- }
393
- get rounded() {
394
- return this._rounded;
395
- }
396
- /**
397
- * Sets the fillMode of the component.
398
- *
399
- * The possible values are:
400
- * * `flat`
401
- * * `solid` (default)
402
- * * `outline`
403
- * * `none`
404
- *
405
- */
406
- set fillMode(fillMode) {
407
- const newFillMode = fillMode ? fillMode : DEFAULT_FILL_MODE;
408
- this.renderer.removeClass(this.wrapper.nativeElement, getFillModeClass('picker', this.fillMode));
409
- if (fillMode !== 'none') {
410
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('picker', newFillMode));
411
- }
412
- this._fillMode = newFillMode;
413
- }
414
- get fillMode() {
415
- return this._fillMode;
416
- }
417
- /**
418
- * A function that is executed for each data item and determines if a specific item is disabled.
419
- */
420
- itemDisabled = itemDisabled;
421
- /**
422
- * A function that is executed for each data item and determines if a specific node is expanded.
423
- */
424
- isNodeExpanded;
425
- /**
426
- * A callback which determines whether a tree node should be rendered as hidden. The utility `.k-hidden` class is used to hide the nodes.
427
- * Useful for custom filtering implementations.
428
- */
429
- isNodeVisible = isNodeVisible;
430
- /**
431
- * Indicates whether the child nodes will be fetched on node expand or will be initially prefetched.
432
- * @default true
433
- */
434
- loadOnDemand = true;
435
- /**
436
- * Renders the built-in input element for filtering the DropDownTree.
437
- * If set to `true`, the component emits the `filterChange` event, which can be used to [filter the DropDownTree manually]({% slug filtering_ddt %}#toc-manual-filtering).
438
- * A built-in filtering implementation is available to use with the [`kendoDropDownTreeHierarchyBinding`]({% slug api_dropdowns_dropdowntreehierarchybindingdirective %}) and [`kendoDropDownTreeFlatBinding`]({% slug api_dropdowns_dropdowntreeflatbindingdirective %}) directives.
439
- */
440
- filterable = false;
441
- /**
442
- * @hidden
443
- */
444
- filter = '';
445
- /**
446
- * @hidden
447
- *
448
- * Used by the kendo-label and kendo-floatinglabel to access and associate the focusable element with the provided label via aria-labelledby.
449
- */
450
- focusableId = `k-${guid()}`;
451
- set isFocused(isFocused) {
452
- this.renderer[isFocused ? 'addClass' : 'removeClass'](this.wrapper.nativeElement, 'k-focus');
453
- this._isFocused = isFocused;
454
- }
455
- get isFocused() {
456
- return this._isFocused;
457
- }
458
- get width() {
459
- const wrapperWidth = this.wrapper.nativeElement.offsetWidth;
460
- const width = this.popupSettings.width || wrapperWidth;
461
- const minWidth = isNaN(wrapperWidth) ? wrapperWidth : `${wrapperWidth}px`;
462
- const maxWidth = isNaN(width) ? width : `${width}px`;
463
- return { min: minWidth, max: maxWidth };
464
- }
465
- get height() {
466
- const popupHeight = this.popupSettings.height;
467
- return isPresent(popupHeight) ? `${popupHeight}px` : 'auto';
468
- }
469
- /**
470
- * Returns the current open state. Returns `true` if the popup or actionSheet is open.
471
- */
472
- get isOpen() {
473
- return isTruthy(isPresent(this.popupRef) || this.isActionSheetExpanded);
474
- }
475
- get clearButtonVisibility() {
476
- if (this.touchEnabled) {
477
- return 'visible';
478
- }
479
- }
480
- get isFilterActive() {
481
- return this.filterInput && document.activeElement === this.filterInput.nativeElement;
482
- }
483
- popupRef;
484
- /**
485
- * @hidden
486
- */
487
- selectedKeys = [];
488
- /**
489
- * @hidden
490
- */
491
- selectBy;
492
- /**
493
- * @hidden
494
- */
495
- text;
496
- /**
497
- * @hidden
498
- */
499
- onFilterChange(text) {
500
- if (this.filterable) {
501
- this.filterChange.emit(text);
502
- }
503
- }
504
- /**
505
- * Enables or disables the adaptive mode. By default the adaptive rendering is disabled.
506
- */
507
- adaptiveMode = 'none';
508
- /**
509
- * Sets the title of the ActionSheet that is rendered instead of the Popup when using small screen devices.
510
- * By default the ActionSheet title uses the text provided for the label of the DropDownTree.
511
- */
512
- adaptiveTitle = '';
513
- /**
514
- * Sets the subtitle of the ActionSheet that is rendered instead of the Popup when using small screen devices.
515
- * By default the ActionSheet does not render a subtitle.
516
- */
517
- adaptiveSubtitle = '';
518
- /**
519
- * @hidden
520
- */
521
- get isAdaptiveModeEnabled() {
522
- return this.adaptiveMode === 'auto';
523
- }
524
- /**
525
- * @hidden
526
- */
527
- windowSize = 'large';
528
- /**
529
- * @hidden
530
- */
531
- get isActionSheetExpanded() {
532
- return this.actionSheet?.expanded;
533
- }
534
- /**
535
- * @hidden
536
- */
537
- get isAdaptive() {
538
- return this.isAdaptiveModeEnabled && this.windowSize !== 'large';
539
- }
540
- /**
541
- * @hidden
542
- *
543
- * Alias for `isNodeExpanded`. Used for compatibility with the `ExpandableComponent` interface.
544
- * Required for the expand-directive.
545
- */
546
- set isExpanded(callback) {
547
- this.isNodeExpanded = callback;
548
- }
549
- get isExpanded() {
550
- return this.isNodeExpanded;
551
- }
552
- /**
553
- * @hidden
554
- *
555
- * Alias for `nodeExpand`. Used for compatibility with the `ExpandableComponent` interface.
556
- * Required for the expand-directive.
557
- */
558
- get expand() {
559
- return this.nodeExpand;
560
- }
561
- /**
562
- * @hidden
563
- *
564
- * Alias for `nodeCollapse`. Used for compatibility with the `ExpandableComponent` interface.
565
- * Required for the expand-directive.
566
- */
567
- get collapse() {
568
- return this.nodeCollapse;
569
- }
570
- /**
571
- * @hidden
572
- *
573
- * Alias for `data`. Used for compatibility with the `DataBoundComponent` interface.
574
- * Required for the data-binding directives.
575
- */
576
- set nodes(nodes) {
577
- this.data = nodes;
578
- }
579
- get nodes() {
580
- return this.data;
581
- }
582
- /**
583
- * @hidden
584
- *
585
- * Alias for `fetchChildren`. Used for compatibility with the `DataBoundComponent` interface.
586
- * Required for the data-binding directives
587
- */
588
- set children(callback) {
589
- this.fetchChildren = callback;
590
- }
591
- get children() {
592
- return this.fetchChildren;
593
- }
594
- /**
595
- * @hidden
596
- *
597
- * Alias for `isNodeVisible`. Used for compatibility with the `DataBoundComponent` interface.
598
- * The `DataBoundComponent` interface is used in the data-binding directives.
599
- */
600
- set isVisible(callback) {
601
- this.isNodeVisible = callback;
602
- }
603
- get isVisible() {
604
- return this.isNodeVisible;
605
- }
606
- /**
607
- * @hidden
608
- */
609
- filterStateChange = new EventEmitter();
610
- /**
611
- * @hidden
612
- */
613
- allNodesHidden = false;
614
- /**
615
- * @hidden
616
- *
617
- * Used to associate the value label with the wrapper via aria-describedby.
618
- */
619
- valueLabelId = `k-${guid()}`;
620
- /**
621
- * @hidden
622
- */
623
- get formControl() {
624
- const ngControl = this.injector.get(NgControl, null);
625
- return ngControl?.control || null;
626
- }
627
- treeViewId = `k-${guid()}`;
628
- _nodes;
629
- _value;
630
- _popupSettings = DEFAULT_POPUP_SETTINGS;
631
- _tabindex = 0;
632
- _isFocused = false;
633
- _dataItem;
634
- _treeview;
635
- _size = 'medium';
636
- _rounded = 'medium';
637
- _fillMode = 'solid';
638
- _searchableNodes = [];
639
- _typedValue = '';
640
- printableCharacters = new Subject();
641
- subs = new Subscription();
642
- touchstartDisposeHandler;
643
- // Keep an instance of the last focused node for when the popup close is prevented
644
- // in order to be able to properly restore the focus
645
- lastNodeOnFocus;
646
- constructor(injector, wrapper, popupService, navigationService, renderer, _zone, cdr, localization, adaptiveService) {
647
- this.injector = injector;
648
- this.wrapper = wrapper;
649
- this.popupService = popupService;
650
- this.navigationService = navigationService;
651
- this.renderer = renderer;
652
- this._zone = _zone;
653
- this.cdr = cdr;
654
- this.localization = localization;
655
- this.adaptiveService = adaptiveService;
656
- this.direction = localization.rtl ? 'rtl' : 'ltr';
657
- this.subscribeEvents();
658
- this.subscribeTouchEvents();
659
- this.subscribeFocusEvents();
660
- }
661
- ngOnInit() {
662
- this.subs.add(this.printableCharacters.pipe(tap((char) => {
663
- this._typedValue += char;
664
- const itemToFocus = this._searchableNodes.find((node) => {
665
- return node.text.toLowerCase().startsWith(this._typedValue);
666
- });
667
- this.treeview?.focus(itemToFocus?.index);
668
- }), debounceTime(1000)).subscribe(() => {
669
- this._typedValue = '';
670
- }));
671
- this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
672
- this.assignAriaDescribedBy();
673
- this.subs.add(this.localization
674
- .changes.subscribe(({ rtl }) => {
675
- this.direction = rtl ? 'rtl' : 'ltr';
676
- this.cdr.markForCheck();
677
- }));
678
- this.setComponentClasses();
679
- }
680
- /**
681
- * @hidden
682
- */
683
- ngOnDestroy() {
684
- this.destroyPopup();
685
- this.unsubscribeEvents();
686
- }
687
- /**
688
- * @hidden
689
- */
690
- ngOnChanges(changes) {
691
- if (anyChanged(['textField', 'valueField', 'valuePrimitive'], changes, false)) {
692
- this.setState();
693
- }
694
- if (isChanged('value', changes, false)) {
695
- if (changes['value'] && !changes['dataItem'] && !this.valuePrimitive) {
696
- // Update the dataItem if the value is updated programmatically (non-primitive values only)
697
- this.dataItem = this.value;
698
- }
699
- }
700
- }
701
- /**
702
- * @hidden
703
- */
704
- ngAfterContentChecked() {
705
- this.verifySettings();
706
- if (this.data?.length > 0 && this.popupRef) {
707
- this.allNodesHidden = this.areNodesHidden(this.data);
708
- }
709
- }
710
- ngAfterViewInit() {
711
- this.windowSize = this.adaptiveService.size;
712
- this.subs.add(this.renderer.listen(this.wrapper.nativeElement, 'click', this.handleClick.bind(this)));
713
- this.subs.add(this.renderer.listen(this.wrapper.nativeElement, 'keydown', this.handleKeydown.bind(this)));
714
- }
715
- /**
716
- * @hidden
717
- */
718
- onResize() {
719
- const currentWindowSize = this.adaptiveService.size;
720
- if (this.isAdaptiveModeEnabled && this.windowSize !== currentWindowSize) {
721
- if (this.isOpen) {
722
- this.togglePopup(false);
723
- }
724
- this.windowSize = currentWindowSize;
725
- }
726
- if (this.isOpen && !this.isActionSheetExpanded) {
727
- const popupWrapper = this.popupRef.popupElement;
728
- const { min, max } = this.width;
729
- popupWrapper.style.minWidth = min;
730
- popupWrapper.style.width = max;
731
- }
732
- }
733
- /**
734
- * @hidden
735
- *
736
- * Used by the kendo-floatinglabel component to determine if the floating label
737
- * should be rendered inside the input when the component is not focused.
738
- */
739
- isEmpty() {
740
- return !this.text && !this.placeholder;
741
- }
742
- /**
743
- * @hidden
744
- */
745
- togglePopup(open) {
746
- const isDisabled = this.disabled || this.readonly;
747
- const sameState = this.isOpen === open;
748
- if (isDisabled || sameState) {
749
- return;
750
- }
751
- const togglePrevented = this.triggerPopupEvents(open);
752
- if (!togglePrevented) {
753
- if (open) {
754
- this.createPopup();
755
- }
756
- else {
757
- this.destroyPopup();
758
- }
759
- }
760
- }
761
- /**
762
- * @hidden
763
- */
764
- handleFocus(event) {
765
- if (event.target !== this.wrapper.nativeElement) {
766
- return;
767
- }
768
- event.stopImmediatePropagation();
769
- if (!this.isFocused) {
770
- this.isFocused = true;
771
- if (hasObservers(this.onFocus)) {
772
- this._zone.run(() => {
773
- this.onFocus.emit();
774
- });
775
- }
776
- }
777
- }
778
- /**
779
- * @hidden
780
- */
781
- handleBlur(e) {
782
- if (!this.isActionSheetExpanded) {
783
- const relatedTarget = e && e.relatedTarget;
784
- if (this.wrapper.nativeElement.contains(relatedTarget) ||
785
- (this.isOpen && this.popupRef.popupElement.contains(relatedTarget))) {
786
- return;
787
- }
788
- this.isFocused = false;
789
- this.togglePopup(false);
790
- if (hasObservers(this.onBlur) ||
791
- isUntouched(this.wrapper.nativeElement) ||
792
- this.formControl?.updateOn === 'blur') {
793
- this._zone.run(() => {
794
- this.onBlur.emit();
795
- this.onTouchedCallback();
796
- });
797
- }
798
- }
799
- }
800
- /**
801
- * @hidden
802
- */
803
- handleKeydown(event, input) {
804
- if (this.disabled || this.readonly) {
805
- return;
806
- }
807
- if (event.code === Keys.Tab && this.isActionSheetExpanded) {
808
- this.togglePopup(false);
809
- return;
810
- }
811
- if (!this.isFilterActive && isLetter(event.key) && !this.actionSheetSearchBar?.onFocus) {
812
- this.printableCharacters.next(event.key);
813
- }
814
- const eventData = event;
815
- this.navigationService.process({
816
- originalEvent: eventData,
817
- openOnSpace: !this.isOpen,
818
- closeOnSpace: this.isOpen && !input && !(event.target instanceof HTMLInputElement)
819
- });
820
- }
821
- /**
822
- * Focuses a specific item of the DropDownTree based on a provided index in the format of `1_1`.
823
- * The targeted item should be expanded in order for it to be focused.
824
- * If null or invalid index is provided the focus will be set on the first item.
825
- */
826
- focusItemAt(index) {
827
- if (this.treeview) {
828
- const lookup = this.treeview.itemLookup(index);
829
- const isItemDisabled = !isPresent(lookup) || this.treeview.isDisabled(lookup.item.dataItem, lookup.item.index);
830
- if (!isItemDisabled) {
831
- this.treeview.focus(index);
832
- }
833
- }
834
- }
835
- /**
836
- * Focuses the DropDownTree.
837
- */
838
- focus() {
839
- if (!this.disabled) {
840
- this.wrapper.nativeElement.focus();
841
- }
842
- }
843
- /**
844
- * Blurs the DropDownTree.
845
- */
846
- blur() {
847
- if (!this.disabled) {
848
- this.wrapper.nativeElement.blur();
849
- }
850
- }
851
- /**
852
- * Resets the value of the DropDownTree.
853
- * If you use the `reset` method to clear the value of the component,
854
- * the model will not update automatically and the `valueChange` event will not be fired.
855
- */
856
- reset() {
857
- this.value = undefined;
858
- this.dataItem = undefined;
859
- }
860
- /**
861
- * Toggles the visibility of the popup or actionSheet.
862
- * ([see example]({% slug openstate_ddt %})).
863
- * If you use the `toggle` method to open or close the popup or actionSheet, the `open` and `close` events will not be fired.
864
- *
865
- * @param open - The state of the popup.
866
- */
867
- toggle(open) {
868
- // The Promise is required to open the popup on load.
869
- // Otherwise, the "ViewContainerRef not found..." error will be thrown.
870
- Promise.resolve(null).then(() => {
871
- const shouldOpen = isPresent(open) ? open : !isPresent(this.popupRef);
872
- this.destroyPopup();
873
- if (shouldOpen) {
874
- this.createPopup();
875
- }
876
- });
877
- }
878
- /**
879
- * @hidden
880
- */
881
- get popupContainerClasses() {
882
- const containerClasses = ['k-dropdowntree-popup'];
883
- if (!this.popupSettings.popupClass) {
884
- return containerClasses;
885
- }
886
- const parsedPopupClasses = parseCSSClassNames(this.popupSettings.popupClass);
887
- if (parsedPopupClasses?.length) {
888
- containerClasses.push(...parsedPopupClasses);
889
- }
890
- return containerClasses;
891
- }
892
- /**
893
- * @hidden
894
- */
895
- onSelectionChange({ dataItem, index }) {
896
- this.valueDepth = index.split('_').length - 1;
897
- const valueField = this.getField(this.valueField, dataItem);
898
- const newValue = this.valuePrimitive ?
899
- getter(valueField)(dataItem) :
900
- dataItem;
901
- const shouldUpdateValue = newValue !== this.value;
902
- if (shouldUpdateValue) {
903
- this.value = newValue;
904
- this.dataItem = dataItem;
905
- this.emitValueChange(this.value);
906
- }
907
- this.togglePopup(false);
908
- this.focus();
909
- }
910
- /**
911
- * @hidden
912
- */
913
- messageFor(key) {
914
- return this.localization.get(key);
915
- }
916
- /**
917
- * @hidden
918
- */
919
- clearValue(event) {
920
- event?.stopImmediatePropagation();
921
- this.focus();
922
- this.value = undefined;
923
- this.dataItem = undefined;
924
- this.clearState();
925
- this.emitValueChange();
926
- }
927
- get appendTo() {
928
- const { appendTo } = this.popupSettings;
929
- if (!appendTo || appendTo === 'root') {
930
- return undefined;
931
- }
932
- return appendTo === 'component' ? this.container : appendTo;
933
- }
934
- /**
935
- * @hidden
936
- */
937
- preventEventDefault(event) {
938
- event.preventDefault();
939
- }
940
- /**
941
- * @hidden
942
- */
943
- writeValue(value) {
944
- // If the user resets the value by providing null/undefined we need to reset the `dataItem`
945
- // Because upon initialization of the component the `writeValue` is being called twice -
946
- // first time with `null` value regardless of sync/async value - an extra check is added to
947
- // distinguish between client reset and initial phantom 'null' value
948
- if (!isPresent(value) && isPresent(this.value)) {
949
- this.dataItem = null;
950
- }
951
- this.value = value === null ? undefined : value;
952
- // Update the dataItem if the value is updated programmatically via a form control (non-primitive values only)
953
- if (isPresent(this.value) && !this.valuePrimitive) {
954
- this.dataItem = this.value;
955
- }
956
- }
957
- /**
958
- * @hidden
959
- */
960
- registerOnChange(fn) {
961
- this.onChangeCallback = fn;
962
- }
963
- /**
964
- * @hidden
965
- */
966
- registerOnTouched(fn) {
967
- this.onTouchedCallback = fn;
968
- }
969
- /**
970
- * @hidden
971
- */
972
- setDisabledState(isDisabled) {
973
- this.disabled = isDisabled;
974
- this.cdr.markForCheck();
975
- }
976
- /**
977
- * @hidden
978
- */
979
- handleFilterInputChange(input) {
980
- const value = typeof input === 'string' ? input : input.value;
981
- this.filter = value;
982
- this.filterChange.next(value);
983
- this.allNodesHidden = this.areNodesHidden(this.nodes);
984
- this._zone.onStable.pipe(take(1)).subscribe(() => {
985
- if (this.data.length === 0 || this.allNodesHidden || this.filter === '') {
986
- this.filterInput?.nativeElement.focus();
987
- }
988
- });
989
- }
990
- /**
991
- * @hidden
992
- */
993
- get selectButtonClasses() {
994
- return `${this.size ? getSizeClass('button', this.size) : ''} ${this.fillMode ? 'k-button-' + this.fillMode : ''} ${this.fillMode ? 'k-button-' + this.fillMode + '-base' : ''}`;
995
- }
996
- /**
997
- * @hidden
998
- */
999
- get filterInputClasses() {
1000
- return `${this.size ? getSizeClass('input', this.size) : ''} ${this.fillMode ? 'k-input-' + this.fillMode : ''} ${this.rounded ? getRoundedClass(this.rounded) : ''}`;
1001
- }
1002
- onTouchedCallback = noop;
1003
- onChangeCallback = noop;
1004
- verifySettings() {
1005
- if (!isDevMode()) {
1006
- return;
1007
- }
1008
- if (this.valuePrimitive === true && isPresent(this.value) && typeof this.value === "object") {
1009
- throw new Error(DropDownTreeMessages.primitive);
1010
- }
1011
- if (this.valuePrimitive === true && isPresent(this.value) && typeof this.dataItem !== "object") {
1012
- throw new Error(DropDownTreeMessages.dataItem);
1013
- }
1014
- if (this.valuePrimitive === false && isPresent(this.value) && typeof this.value !== "object") {
1015
- throw new Error(DropDownTreeMessages.object);
1016
- }
1017
- if (!isPresent(this.valueField) || !isPresent(this.textField)) {
1018
- throw new Error(DropDownTreeMessages.textAndValue);
1019
- }
1020
- if ((isArray(this.valueField) || isArray(this.textField)) && isPresent(this.value) && !isPresent(this.valueDepth)) {
1021
- throw new Error(DropDownTreeMessages.valueDepth);
1022
- }
1023
- }
1024
- emitValueChange(value) {
1025
- this.onChangeCallback(value);
1026
- this.valueChange.emit(value);
1027
- }
1028
- getText(textField, dataItem) {
1029
- if (isPresent(dataItem) && isPresent(textField)) {
1030
- const field = this.getField(textField, dataItem);
1031
- return getter(field)(dataItem);
1032
- }
1033
- return null;
1034
- }
1035
- /**
1036
- * @hidden
1037
- */
1038
- onChildrenLoaded() {
1039
- setTimeout(() => {
1040
- if (this.popupRef) {
1041
- this._searchableNodes = getSearchableItems(this.treeViewId, this.popupRef.popupElement);
1042
- }
1043
- if (this.isActionSheetExpanded) {
1044
- this._searchableNodes = getSearchableItems(this.treeViewId, this.actionSheet.element.nativeElement);
1045
- }
1046
- });
1047
- }
1048
- /**
1049
- * @hidden
1050
- *
1051
- * Determines the `valueField` and `textField` for a specific level in the data set
1052
- * @param field - the field value (string | string[])
1053
- * @param value - current value
1054
- */
1055
- getField(field, value) {
1056
- const fieldsCount = field.length - 1;
1057
- if (typeof field === 'string') {
1058
- // If the `valueField` | `textField` is the same for all levels
1059
- return field;
1060
- }
1061
- else if (isPresent(this.valueDepth)) {
1062
- // When `valueDepth` can be defined from the index on selectionChange or provided by the user
1063
- return fieldsCount < this.valueDepth ? field[fieldsCount] : field[this.valueDepth];
1064
- }
1065
- else if (value && typeof value === 'object') {
1066
- // Fallback: Look to find a match of each field in the current data item
1067
- // Side effect may occur if all of the listed fields are present in the data item
1068
- return field.find(item => item in value);
1069
- }
1070
- }
1071
- areNodesHidden(nodes) {
1072
- return nodes.every((node, index) => !this.isVisible(node, String(index)));
1073
- }
1074
- triggerPopupEvents(open) {
1075
- const eventArgs = new PreventableEvent();
1076
- if (open) {
1077
- this.open.emit(eventArgs);
1078
- }
1079
- else {
1080
- this.close.emit(eventArgs);
1081
- }
1082
- return eventArgs.isDefaultPrevented();
1083
- }
1084
- createPopup() {
1085
- this.windowSize = this.adaptiveService.size;
1086
- if (this.isAdaptive) {
1087
- this.openActionSheet();
1088
- this.cdr.detectChanges();
1089
- return;
1090
- }
1091
- const horizontalAlign = this.direction === "rtl" ? "right" : "left";
1092
- const anchorPosition = { horizontal: horizontalAlign, vertical: 'bottom' };
1093
- const popupPosition = { horizontal: horizontalAlign, vertical: 'top' };
1094
- const appendToComponent = typeof this.popupSettings.appendTo === 'string' && this.popupSettings.appendTo === 'component';
1095
- this.popupRef = this.popupService.open({
1096
- anchor: this.wrapper,
1097
- appendTo: this.appendTo,
1098
- anchorAlign: anchorPosition,
1099
- animate: this.popupSettings.animate,
1100
- content: this.popupTemplate,
1101
- popupAlign: popupPosition,
1102
- positionMode: appendToComponent ? 'fixed' : 'absolute',
1103
- popupClass: this.popupContainerClasses
1104
- });
1105
- const popupWrapper = this.popupRef.popupElement;
1106
- const { min, max } = this.width;
1107
- this.renderer.setStyle(popupWrapper, 'minWidth', min);
1108
- this.renderer.setStyle(popupWrapper, 'width', max);
1109
- this.renderer.setStyle(popupWrapper, 'height', this.height);
1110
- this.renderer.setAttribute(popupWrapper, 'dir', this.direction);
1111
- if (!this.appendTo) {
1112
- this.renderer.setAttribute(popupWrapper, 'role', 'region');
1113
- this.renderer.setAttribute(popupWrapper, 'aria-label', this.messageFor('popupLabel'));
1114
- }
1115
- this.popupRef.popupOpen.subscribe(() => {
1116
- this.allNodesHidden = this.areNodesHidden(this.data);
1117
- this.popupRef.popupElement.addEventListener('click', (event) => stopPropagation(event));
1118
- this.cdr.detectChanges();
1119
- this.opened.emit();
1120
- this._searchableNodes = getSearchableItems(this.treeViewId, this.popupRef.popupElement);
1121
- });
1122
- this.popupRef.popupClose.subscribe(() => {
1123
- this.closed.emit();
1124
- });
1125
- }
1126
- destroyPopup() {
1127
- if (this.isActionSheetExpanded) {
1128
- this.closeActionSheet();
1129
- }
1130
- if (this.popupRef) {
1131
- this.popupRef.popupElement.removeEventListener('click', (event) => stopPropagation(event));
1132
- this.popupRef.close();
1133
- this.popupRef = null;
1134
- this.clearFilter();
1135
- // Trigger change detection to update aria-controls attribute
1136
- this.cdr.markForCheck();
1137
- }
1138
- }
1139
- clearFilter() {
1140
- if (this.filter !== "") {
1141
- this.filter = "";
1142
- this.allNodesHidden = false;
1143
- if (hasObservers(this.filterChange)) {
1144
- this._zone.run(() => {
1145
- this.filterChange.emit("");
1146
- });
1147
- }
1148
- }
1149
- }
1150
- handleClick(e) {
1151
- // The check is needed otherwise when appended to the component, the popup reopens on click
1152
- // https://github.com/telerik/kendo-angular/issues/3738
1153
- this.windowSize = this.adaptiveService.size;
1154
- if (!this.isActionSheetExpanded) {
1155
- if ((this.popupRef && !this.popupRef.popupElement.contains(e.target))
1156
- || (!this.popupRef && !e.target.className.includes('k-treeview-leaf'))) {
1157
- this.togglePopup(!this.isOpen);
1158
- }
1159
- }
1160
- }
1161
- handleEscape() {
1162
- this.togglePopup(false);
1163
- this.focus();
1164
- }
1165
- setState() {
1166
- if (isPresent(this.value) && isPresent(this.dataItem) && isPresent(this.valueField)) {
1167
- this.text = this.getText(this.textField, this.dataItem);
1168
- const valueField = this.getField(this.valueField, this.dataItem);
1169
- this.selectBy = valueField;
1170
- this.selectedKeys = [getter(valueField)(this.dataItem)];
1171
- }
1172
- else {
1173
- this.clearState();
1174
- }
1175
- this.cdr.markForCheck();
1176
- }
1177
- clearState() {
1178
- this.text = undefined;
1179
- this.selectedKeys = [];
1180
- }
1181
- subscribeEvents() {
1182
- [
1183
- this.navigationService.open.subscribe((event) => {
1184
- event.originalEvent.preventDefault();
1185
- this.togglePopup(true);
1186
- }),
1187
- this.navigationService.close.subscribe((event) => {
1188
- event.originalEvent.preventDefault();
1189
- this.togglePopup(false);
1190
- this.focus();
1191
- }),
1192
- this.navigationService.enter
1193
- .pipe(tap((event) => event.originalEvent.preventDefault()))
1194
- .subscribe((e) => {
1195
- // The check is needed otherwise when appended to the component, the popup reopens on click
1196
- // https://github.com/telerik/kendo-angular/issues/3738
1197
- if (e.originalEvent.target === this.wrapper.nativeElement) {
1198
- this.togglePopup(true);
1199
- }
1200
- if (!this.isOpen) {
1201
- this.focus();
1202
- }
1203
- }),
1204
- this.navigationService.esc
1205
- .subscribe(() => {
1206
- if (this.isOpen) {
1207
- this.handleEscape();
1208
- }
1209
- else if (this.isFocused && this.selectedKeys.length > 0) {
1210
- this.clearValue();
1211
- }
1212
- }),
1213
- this.navigationService.tab.subscribe(() => {
1214
- this.focus();
1215
- if (this.isOpen) {
1216
- this.treeview.blur();
1217
- this.removeTreeViewFromTabOrder();
1218
- }
1219
- }),
1220
- this.navigationService.down.subscribe((event) => {
1221
- if (!this.treeview) {
1222
- return;
1223
- }
1224
- event.originalEvent.preventDefault();
1225
- if (!this.treeview.isActive) {
1226
- this.treeview.focus();
1227
- }
1228
- }),
1229
- this.navigationService.up.subscribe((event) => {
1230
- if (!this.treeview) {
1231
- return;
1232
- }
1233
- event.originalEvent.preventDefault();
1234
- if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
1235
- if (this.isActionSheetExpanded) {
1236
- this.actionSheetSearchBar.focus();
1237
- }
1238
- else {
1239
- this.filterInput.nativeElement.focus();
1240
- }
1241
- }
1242
- })
1243
- ].forEach(sub => this.subs.add(sub));
1244
- }
1245
- subscribeTouchEvents() {
1246
- if (!isDocumentAvailable() || !this.touchEnabled) {
1247
- return;
1248
- }
1249
- this._zone.runOutsideAngular(() =>
1250
- // Roll up DropDownTree on iOS when tapped outside
1251
- this.touchstartDisposeHandler = this.renderer.listen(document, 'touchstart', (e) => {
1252
- const target = e.target;
1253
- if (this.isFocused && !inDropDown(this.wrapper, target, this.popupRef)) {
1254
- this._zone.run(() => {
1255
- if (this.isOpen) {
1256
- this.treeview.blur();
1257
- }
1258
- this.blur();
1259
- });
1260
- }
1261
- }));
1262
- }
1263
- subscribeFocusEvents() {
1264
- if (isDocumentAvailable()) {
1265
- this.handleFocus = this.handleFocus.bind(this);
1266
- this.handleDocumentBlur = this.handleDocumentBlur.bind(this);
1267
- this._zone.runOutsideAngular(() => {
1268
- const useCapture = true;
1269
- document.addEventListener('focus', this.handleFocus, useCapture);
1270
- document.addEventListener('blur', this.handleDocumentBlur, useCapture);
1271
- });
1272
- }
1273
- }
1274
- unSubscribeFocusEvents() {
1275
- if (isDocumentAvailable()) {
1276
- const useCapture = true;
1277
- document.removeEventListener('focus', this.handleFocus, useCapture);
1278
- document.removeEventListener('blur', this.handleDocumentBlur, useCapture);
1279
- }
1280
- }
1281
- unsubscribeEvents() {
1282
- this.subs.unsubscribe();
1283
- this.unSubscribeFocusEvents();
1284
- if (this.touchstartDisposeHandler) {
1285
- this.touchstartDisposeHandler();
1286
- }
1287
- }
1288
- handleDocumentBlur(event) {
1289
- if (event.target !== this.wrapper.nativeElement) {
1290
- return;
1291
- }
1292
- event.stopImmediatePropagation();
1293
- this.handleBlur(event);
1294
- }
1295
- assignAriaDescribedBy() {
1296
- const currentValue = this.wrapper.nativeElement.getAttribute('aria-describedby') || '';
1297
- // add to the current value - don't replace it (the aria-describedby is used by the FormField component as well)
1298
- const newValue = `${this.valueLabelId} ${currentValue.trim()}`.trim();
1299
- this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-describedby', newValue);
1300
- }
1301
- setComponentClasses() {
1302
- if (this.size !== 'none') {
1303
- this.renderer.addClass(this.wrapper.nativeElement, getSizeClass('picker', this.size));
1304
- }
1305
- if (this.rounded !== 'none') {
1306
- this.renderer.addClass(this.wrapper.nativeElement, getRoundedClass(this.rounded));
1307
- }
1308
- if (this.fillMode !== 'none') {
1309
- this.renderer.addClass(this.wrapper.nativeElement, getFillModeClass('picker', this.fillMode));
1310
- }
1311
- }
1312
- /**
1313
- * Remove the `TreeView` from the tab order, otherwise a focus loop between the page elements will occur
1314
- * and the user will not be able to tab to the rest of the browser elements
1315
- */
1316
- removeTreeViewFromTabOrder() {
1317
- const nodes = this.treeview.element.nativeElement.querySelectorAll('li');
1318
- nodes.forEach(item => {
1319
- if (item.getAttribute('tabindex') === '0') {
1320
- this.lastNodeOnFocus = item;
1321
- this.lastNodeOnFocus.setAttribute('tabindex', '-1');
1322
- }
1323
- });
1324
- }
1325
- closeActionSheet() {
1326
- this.actionSheet.toggle(false);
1327
- if (this.filterable) {
1328
- this.clearFilter();
1329
- }
1330
- this.wrapper.nativeElement.focus();
1331
- this.closed.emit();
1332
- }
1333
- openActionSheet() {
1334
- this.actionSheet.toggle(true);
1335
- this.adaptiveTitle = setActionSheetTitle(this.wrapper, this.adaptiveTitle);
1336
- this.cdr.detectChanges();
1337
- this.opened.emit();
1338
- this.removeTreeViewFromTabOrder();
1339
- }
1340
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DropDownTreeComponent, deps: [{ token: i0.Injector }, { token: i0.ElementRef }, { token: i1.PopupService }, { token: i2.NavigationService }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i3.LocalizationService }, { token: i4.AdaptiveService }], target: i0.ɵɵFactoryTarget.Component });
1341
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DropDownTreeComponent, isStandalone: true, selector: "kendo-dropdowntree", inputs: { icon: "icon", svgIcon: "svgIcon", loading: "loading", clearButton: "clearButton", data: "data", value: "value", textField: "textField", valueField: "valueField", valueDepth: "valueDepth", hasChildren: "hasChildren", fetchChildren: "fetchChildren", placeholder: "placeholder", popupSettings: "popupSettings", dataItem: "dataItem", listHeight: "listHeight", disabled: "disabled", readonly: "readonly", valuePrimitive: "valuePrimitive", tabindex: "tabindex", size: "size", rounded: "rounded", fillMode: "fillMode", itemDisabled: "itemDisabled", isNodeExpanded: "isNodeExpanded", isNodeVisible: "isNodeVisible", loadOnDemand: "loadOnDemand", filterable: "filterable", filter: "filter", focusableId: "focusableId", adaptiveMode: "adaptiveMode", adaptiveTitle: "adaptiveTitle", adaptiveSubtitle: "adaptiveSubtitle" }, outputs: { open: "open", opened: "opened", close: "close", closed: "closed", nodeExpand: "nodeExpand", nodeCollapse: "nodeCollapse", onFocus: "focus", onBlur: "blur", valueChange: "valueChange", filterChange: "filterChange" }, host: { properties: { "class.k-dropdowntree": "this.hostClasses", "class.k-picker": "this.hostClasses", "attr.readonly": "this.isReadonly", "attr.aria-invalid": "this.hostAriaInvalid", "class.k-disabled": "this.isDisabled", "attr.aria-disabled": "this.isDisabled", "class.k-loading": "this.isLoading", "attr.aria-busy": "this.isBusy", "attr.aria-controls": "this.hostAriaControls", "attr.id": "this.id", "attr.dir": "this.direction", "attr.tabindex": "this.hostTabIndex", "attr.role": "this.role", "attr.aria-haspopup": "this.ariaHasPopup", "attr.aria-expanded": "this.isAriaExpanded", "attr.aria-autocomplete": "this.hostAriaAutocomplete", "class.k-readonly": "this.readonly" } }, providers: [
1342
- DataService,
1343
- SelectionService,
1344
- NavigationService,
1345
- DisabledItemsService,
1346
- LocalizationService,
1347
- {
1348
- provide: L10N_PREFIX,
1349
- useValue: 'kendo.dropdowntree'
1350
- },
1351
- {
1352
- multi: true,
1353
- provide: NG_VALUE_ACCESSOR,
1354
- useExisting: forwardRef(() => DropDownTreeComponent)
1355
- },
1356
- {
1357
- provide: KendoInput,
1358
- useExisting: forwardRef(() => DropDownTreeComponent)
1359
- },
1360
- {
1361
- provide: DataBoundComponent,
1362
- useExisting: forwardRef(() => DropDownTreeComponent)
1363
- },
1364
- {
1365
- provide: ExpandableComponent,
1366
- useExisting: forwardRef(() => DropDownTreeComponent)
1367
- }
1368
- ], queries: [{ propertyName: "noDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "headerTemplate", first: true, predicate: HeaderTemplateDirective, descendants: true }, { propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "nodeTemplate", first: true, predicate: NodeTemplateDirective, descendants: true }, { propertyName: "valueTemplate", first: true, predicate: ValueTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "adaptiveRendererComponent", first: true, predicate: AdaptiveRendererComponent, descendants: true }, { propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, static: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "treeview", first: true, predicate: ["treeview"], descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], exportAs: ["kendoDropDownTree"], usesOnChanges: true, ngImport: i0, template: `
1369
- <ng-container kendoDropDownTreeLocalizedMessages
1370
- i18n-noDataText="kendo.dropdowntree.noDataText|The text displayed in the popup when there are no items"
1371
- noDataText="NO DATA FOUND"
1372
-
1373
- i18n-clearTitle="kendo.dropdowntree.clearTitle|The title of the clear button"
1374
- clearTitle="clear"
1375
-
1376
- i18n-selectButtonText="kendo.dropdowntree.selectButtonText|The text set as aria-label on the select button"
1377
- selectButtonText="Select"
1378
-
1379
- i18n-filterInputLabel="kendo.dropdowntree.filterInputLabel|The text set as aria-label on the filter input"
1380
- filterInputLabel="Filter"
1381
-
1382
- i18n-popupLabel="kendo.dropdowntree.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
1383
- popupLabel="Options list"
1384
-
1385
- i18n-adaptiveCloseButtonTitle="kendo.dropdowntree.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"
1386
- adaptiveCloseButtonTitle="Close"
1387
-
1388
- i18n-filterInputPlaceholder="kendo.dropdowntree.filterInputPlaceholder|The text for the input's placeholder when filtering is enabled"
1389
- filterInputPlaceholder="Filter"
1390
- >
1391
- </ng-container>
1392
- <span
1393
- [attr.id]="valueLabelId"
1394
- class="k-input-inner"
1395
- (click)="$event.preventDefault()"
1396
- >
1397
- @if (valueTemplate || text || placeholder) {
1398
- <span class="k-input-value-text">
1399
- @if (valueTemplate) {
1400
- <ng-template
1401
- [templateContext]="{
1402
- templateRef: valueTemplate.templateRef,
1403
- $implicit: dataItem
1404
- }">
1405
- </ng-template>
1406
- }
1407
- @if (!valueTemplate) {
1408
- {{ text || placeholder }}
1409
- }
1410
- </span>
1411
- }
1412
- </span>
1413
- @if (!loading && !readonly && clearButton && text?.length && !disabled) {
1414
- <span
1415
- class="k-clear-value"
1416
- [style.visibility]="clearButtonVisibility"
1417
- [attr.title]="messageFor('clearTitle')"
1418
- aria-hidden="true"
1419
- (click)="clearValue($event)"
1420
- >
1421
- <kendo-icon-wrapper
1422
- name="x"
1423
- [svgIcon]="xIcon"
1424
- >
1425
- </kendo-icon-wrapper>
1426
- </span>
1427
- }
1428
- @if (loading) {
1429
- <span class="k-i-loading k-input-loading-icon k-icon"></span>
1430
- }
1431
- <button
1432
- tabindex="-1"
1433
- type="button"
1434
- class="k-input-button k-button k-icon-button"
1435
- [ngClass]="selectButtonClasses"
1436
- [attr.aria-label]="messageFor('selectButtonText')"
1437
- [attr.disabled]="disabled ? '' : null"
1438
- >
1439
- <kendo-icon-wrapper
1440
- [name]="icon || 'caret-alt-down'"
1441
- innerCssClass="k-button-icon"
1442
- [svgIcon]="svgIcon || caretAltDownIcon"
1443
- >
1444
- </kendo-icon-wrapper>
1445
- </button>
1446
- <ng-template #popupTemplate>
1447
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
1448
- </ng-template>
1449
- <ng-container #container></ng-container>
1450
-
1451
- <kendo-adaptive-renderer
1452
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
1453
- [title]="adaptiveTitle"
1454
- [showTextInput]="filterable"
1455
- [subtitle]="adaptiveSubtitle"
1456
- (closePopup)="togglePopup(false)"
1457
- (textInputChange)="handleFilterInputChange($event)"
1458
- [placeholder]="placeholder"
1459
- [searchBarValue]="filter"
1460
- [filterable]="filterable">
1461
- </kendo-adaptive-renderer>
1462
-
1463
- <ng-template #sharedPopupActionSheetTemplate>
1464
- @if (filterable && !isActionSheetExpanded) {
1465
- <span
1466
- class="k-list-filter"
1467
- >
1468
- <span
1469
- class="k-textbox k-input"
1470
- [ngClass]="filterInputClasses"
1471
- >
1472
- <span class="k-input-prefix">
1473
- <kendo-icon-wrapper
1474
- class="k-icon"
1475
- name="search"
1476
- [svgIcon]="searchIcon"
1477
- >
1478
- </kendo-icon-wrapper>
1479
- </span>
1480
- <input
1481
- #filterInput
1482
- (input)="handleFilterInputChange($event.target)"
1483
- [filterInput]="filterable && !touchEnabled"
1484
- (keydown.arrowdown)="handleKeydown($event, filterInput)"
1485
- (keydown.alt.arrowup)="handleKeydown($event, filterInput)"
1486
- (keydown.escape)="handleKeydown($event, filterInput)"
1487
- [attr.aria-label]="messageFor('filterInputLabel')"
1488
- [value]="filter"
1489
- class="k-input-inner"
1490
- role="textbox"
1491
- [kendoEventsOutsideAngular]="{
1492
- blur: handleBlur
1493
- }"
1494
- [scope]="this"
1495
- >
1496
- </span>
1497
- </span>
1498
- }
1499
- <!--header template-->
1500
- @if (headerTemplate) {
1501
- <ng-template
1502
- [templateContext]="{
1503
- templateRef: headerTemplate?.templateRef
1504
- }">
1505
- </ng-template>
1506
- }
1507
- @if (data.length !== 0 && !allNodesHidden) {
1508
- <kendo-treeview
1509
- #treeview
1510
- [attr.id]="treeViewId"
1511
- [size]="windowSize !== 'large' ? 'large' : size"
1512
- [nodes]="data"
1513
- [style.maxHeight.px]="listHeight"
1514
- [animate]="false"
1515
- [(selectedKeys)]="selectedKeys"
1516
- [selectBy]="selectBy"
1517
- [textField]="textField"
1518
- kendoTreeViewSelectable
1519
- [children]="children"
1520
- [hasChildren]="hasChildren"
1521
- [loadOnDemand]="loadOnDemand"
1522
- [isExpanded]="isNodeExpanded"
1523
- [isDisabled]="itemDisabled"
1524
- [nodeTemplate]="nodeTemplate"
1525
- [filter]="filter"
1526
- [isVisible]="isNodeVisible"
1527
- (focusout)="handleBlur($event)"
1528
- (keydown)="handleKeydown($event)"
1529
- (selectionChange)="onSelectionChange($event)"
1530
- (expand)="nodeExpand.emit($event)"
1531
- (collapse)="nodeCollapse.emit($event)"
1532
- (childrenLoaded)="onChildrenLoaded()"
1533
- >
1534
- </kendo-treeview>
1535
- }
1536
- <!--footer template-->
1537
- @if (footerTemplate) {
1538
- <ng-template
1539
- [templateContext]="{
1540
- templateRef: footerTemplate?.templateRef
1541
- }">
1542
- </ng-template>
1543
- }
1544
- <!--no-data template-->
1545
- @if (data.length === 0 || allNodesHidden) {
1546
- <div class="k-no-data">
1547
- @if (noDataTemplate) {
1548
- <ng-template
1549
- [templateContext]="{
1550
- templateRef: noDataTemplate?.templateRef
1551
- }">
1552
- </ng-template>
1553
- }
1554
- @if (!noDataTemplate) {
1555
- <div>{{ messageFor('noDataText') }}</div>
1556
- }
1557
- </div>
1558
- }
1559
- </ng-template>
1560
-
1561
- @if (isOpen || isAdaptiveModeEnabled) {
1562
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
1563
- }
1564
- `, 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: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { 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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: FilterInputDirective, selector: "[filterInput]", inputs: ["filterInput"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "component", type: TreeViewComponent, selector: "kendo-treeview", inputs: ["filterInputPlaceholder", "expandDisabledNodes", "animate", "nodeTemplate", "loadMoreButtonTemplate", "trackBy", "nodes", "textField", "hasChildren", "isChecked", "isDisabled", "hasCheckbox", "isExpanded", "isSelected", "isVisible", "navigable", "children", "loadOnDemand", "filterable", "filter", "size", "disableParentNodesOnly"], outputs: ["childrenLoaded", "blur", "focus", "expand", "collapse", "nodeDragStart", "nodeDrag", "filterStateChange", "nodeDrop", "nodeDragEnd", "addItem", "removeItem", "checkedChange", "selectionChange", "filterChange", "nodeClick", "nodeDblClick"], exportAs: ["kendoTreeView"] }, { kind: "directive", type: SelectDirective, selector: "[kendoTreeViewSelectable]", inputs: ["isSelected", "selectBy", "kendoTreeViewSelectable", "selectedKeys"], outputs: ["selectedKeysChange"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1565
- }
1566
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DropDownTreeComponent, decorators: [{
1567
- type: Component,
1568
- args: [{
1569
- exportAs: 'kendoDropDownTree',
1570
- providers: [
1571
- DataService,
1572
- SelectionService,
1573
- NavigationService,
1574
- DisabledItemsService,
1575
- LocalizationService,
1576
- {
1577
- provide: L10N_PREFIX,
1578
- useValue: 'kendo.dropdowntree'
1579
- },
1580
- {
1581
- multi: true,
1582
- provide: NG_VALUE_ACCESSOR,
1583
- useExisting: forwardRef(() => DropDownTreeComponent)
1584
- },
1585
- {
1586
- provide: KendoInput,
1587
- useExisting: forwardRef(() => DropDownTreeComponent)
1588
- },
1589
- {
1590
- provide: DataBoundComponent,
1591
- useExisting: forwardRef(() => DropDownTreeComponent)
1592
- },
1593
- {
1594
- provide: ExpandableComponent,
1595
- useExisting: forwardRef(() => DropDownTreeComponent)
1596
- }
1597
- ],
1598
- selector: 'kendo-dropdowntree',
1599
- template: `
1600
- <ng-container kendoDropDownTreeLocalizedMessages
1601
- i18n-noDataText="kendo.dropdowntree.noDataText|The text displayed in the popup when there are no items"
1602
- noDataText="NO DATA FOUND"
1603
-
1604
- i18n-clearTitle="kendo.dropdowntree.clearTitle|The title of the clear button"
1605
- clearTitle="clear"
1606
-
1607
- i18n-selectButtonText="kendo.dropdowntree.selectButtonText|The text set as aria-label on the select button"
1608
- selectButtonText="Select"
1609
-
1610
- i18n-filterInputLabel="kendo.dropdowntree.filterInputLabel|The text set as aria-label on the filter input"
1611
- filterInputLabel="Filter"
1612
-
1613
- i18n-popupLabel="kendo.dropdowntree.popupLabel|The label of the popup element that contains the list of options when its role is 'region'"
1614
- popupLabel="Options list"
1615
-
1616
- i18n-adaptiveCloseButtonTitle="kendo.dropdowntree.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"
1617
- adaptiveCloseButtonTitle="Close"
1618
-
1619
- i18n-filterInputPlaceholder="kendo.dropdowntree.filterInputPlaceholder|The text for the input's placeholder when filtering is enabled"
1620
- filterInputPlaceholder="Filter"
1621
- >
1622
- </ng-container>
1623
- <span
1624
- [attr.id]="valueLabelId"
1625
- class="k-input-inner"
1626
- (click)="$event.preventDefault()"
1627
- >
1628
- @if (valueTemplate || text || placeholder) {
1629
- <span class="k-input-value-text">
1630
- @if (valueTemplate) {
1631
- <ng-template
1632
- [templateContext]="{
1633
- templateRef: valueTemplate.templateRef,
1634
- $implicit: dataItem
1635
- }">
1636
- </ng-template>
1637
- }
1638
- @if (!valueTemplate) {
1639
- {{ text || placeholder }}
1640
- }
1641
- </span>
1642
- }
1643
- </span>
1644
- @if (!loading && !readonly && clearButton && text?.length && !disabled) {
1645
- <span
1646
- class="k-clear-value"
1647
- [style.visibility]="clearButtonVisibility"
1648
- [attr.title]="messageFor('clearTitle')"
1649
- aria-hidden="true"
1650
- (click)="clearValue($event)"
1651
- >
1652
- <kendo-icon-wrapper
1653
- name="x"
1654
- [svgIcon]="xIcon"
1655
- >
1656
- </kendo-icon-wrapper>
1657
- </span>
1658
- }
1659
- @if (loading) {
1660
- <span class="k-i-loading k-input-loading-icon k-icon"></span>
1661
- }
1662
- <button
1663
- tabindex="-1"
1664
- type="button"
1665
- class="k-input-button k-button k-icon-button"
1666
- [ngClass]="selectButtonClasses"
1667
- [attr.aria-label]="messageFor('selectButtonText')"
1668
- [attr.disabled]="disabled ? '' : null"
1669
- >
1670
- <kendo-icon-wrapper
1671
- [name]="icon || 'caret-alt-down'"
1672
- innerCssClass="k-button-icon"
1673
- [svgIcon]="svgIcon || caretAltDownIcon"
1674
- >
1675
- </kendo-icon-wrapper>
1676
- </button>
1677
- <ng-template #popupTemplate>
1678
- <ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
1679
- </ng-template>
1680
- <ng-container #container></ng-container>
1681
-
1682
- <kendo-adaptive-renderer
1683
- [sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
1684
- [title]="adaptiveTitle"
1685
- [showTextInput]="filterable"
1686
- [subtitle]="adaptiveSubtitle"
1687
- (closePopup)="togglePopup(false)"
1688
- (textInputChange)="handleFilterInputChange($event)"
1689
- [placeholder]="placeholder"
1690
- [searchBarValue]="filter"
1691
- [filterable]="filterable">
1692
- </kendo-adaptive-renderer>
1693
-
1694
- <ng-template #sharedPopupActionSheetTemplate>
1695
- @if (filterable && !isActionSheetExpanded) {
1696
- <span
1697
- class="k-list-filter"
1698
- >
1699
- <span
1700
- class="k-textbox k-input"
1701
- [ngClass]="filterInputClasses"
1702
- >
1703
- <span class="k-input-prefix">
1704
- <kendo-icon-wrapper
1705
- class="k-icon"
1706
- name="search"
1707
- [svgIcon]="searchIcon"
1708
- >
1709
- </kendo-icon-wrapper>
1710
- </span>
1711
- <input
1712
- #filterInput
1713
- (input)="handleFilterInputChange($event.target)"
1714
- [filterInput]="filterable && !touchEnabled"
1715
- (keydown.arrowdown)="handleKeydown($event, filterInput)"
1716
- (keydown.alt.arrowup)="handleKeydown($event, filterInput)"
1717
- (keydown.escape)="handleKeydown($event, filterInput)"
1718
- [attr.aria-label]="messageFor('filterInputLabel')"
1719
- [value]="filter"
1720
- class="k-input-inner"
1721
- role="textbox"
1722
- [kendoEventsOutsideAngular]="{
1723
- blur: handleBlur
1724
- }"
1725
- [scope]="this"
1726
- >
1727
- </span>
1728
- </span>
1729
- }
1730
- <!--header template-->
1731
- @if (headerTemplate) {
1732
- <ng-template
1733
- [templateContext]="{
1734
- templateRef: headerTemplate?.templateRef
1735
- }">
1736
- </ng-template>
1737
- }
1738
- @if (data.length !== 0 && !allNodesHidden) {
1739
- <kendo-treeview
1740
- #treeview
1741
- [attr.id]="treeViewId"
1742
- [size]="windowSize !== 'large' ? 'large' : size"
1743
- [nodes]="data"
1744
- [style.maxHeight.px]="listHeight"
1745
- [animate]="false"
1746
- [(selectedKeys)]="selectedKeys"
1747
- [selectBy]="selectBy"
1748
- [textField]="textField"
1749
- kendoTreeViewSelectable
1750
- [children]="children"
1751
- [hasChildren]="hasChildren"
1752
- [loadOnDemand]="loadOnDemand"
1753
- [isExpanded]="isNodeExpanded"
1754
- [isDisabled]="itemDisabled"
1755
- [nodeTemplate]="nodeTemplate"
1756
- [filter]="filter"
1757
- [isVisible]="isNodeVisible"
1758
- (focusout)="handleBlur($event)"
1759
- (keydown)="handleKeydown($event)"
1760
- (selectionChange)="onSelectionChange($event)"
1761
- (expand)="nodeExpand.emit($event)"
1762
- (collapse)="nodeCollapse.emit($event)"
1763
- (childrenLoaded)="onChildrenLoaded()"
1764
- >
1765
- </kendo-treeview>
1766
- }
1767
- <!--footer template-->
1768
- @if (footerTemplate) {
1769
- <ng-template
1770
- [templateContext]="{
1771
- templateRef: footerTemplate?.templateRef
1772
- }">
1773
- </ng-template>
1774
- }
1775
- <!--no-data template-->
1776
- @if (data.length === 0 || allNodesHidden) {
1777
- <div class="k-no-data">
1778
- @if (noDataTemplate) {
1779
- <ng-template
1780
- [templateContext]="{
1781
- templateRef: noDataTemplate?.templateRef
1782
- }">
1783
- </ng-template>
1784
- }
1785
- @if (!noDataTemplate) {
1786
- <div>{{ messageFor('noDataText') }}</div>
1787
- }
1788
- </div>
1789
- }
1790
- </ng-template>
1791
-
1792
- @if (isOpen || isAdaptiveModeEnabled) {
1793
- <kendo-resize-sensor (resize)="onResize()"></kendo-resize-sensor>
1794
- }
1795
- `,
1796
- changeDetection: ChangeDetectionStrategy.OnPush,
1797
- standalone: true,
1798
- imports: [LocalizedMessagesDirective, TemplateContextDirective, IconWrapperComponent, NgClass, NgTemplateOutlet, AdaptiveRendererComponent, FilterInputDirective, EventsOutsideAngularDirective, TreeViewComponent, SelectDirective, ResizeSensorComponent]
1799
- }]
1800
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i0.ElementRef }, { type: i1.PopupService }, { type: i2.NavigationService }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i3.LocalizationService }, { type: i4.AdaptiveService }], propDecorators: { icon: [{
1801
- type: Input
1802
- }], svgIcon: [{
1803
- type: Input
1804
- }], adaptiveRendererComponent: [{
1805
- type: ViewChild,
1806
- args: [AdaptiveRendererComponent]
1807
- }], hostClasses: [{
1808
- type: HostBinding,
1809
- args: ['class.k-dropdowntree']
1810
- }, {
1811
- type: HostBinding,
1812
- args: ['class.k-picker']
1813
- }], isReadonly: [{
1814
- type: HostBinding,
1815
- args: ['attr.readonly']
1816
- }], hostAriaInvalid: [{
1817
- type: HostBinding,
1818
- args: ['attr.aria-invalid']
1819
- }], isDisabled: [{
1820
- type: HostBinding,
1821
- args: ['class.k-disabled']
1822
- }, {
1823
- type: HostBinding,
1824
- args: ['attr.aria-disabled']
1825
- }], isLoading: [{
1826
- type: HostBinding,
1827
- args: ['class.k-loading']
1828
- }], isBusy: [{
1829
- type: HostBinding,
1830
- args: ['attr.aria-busy']
1831
- }], hostAriaControls: [{
1832
- type: HostBinding,
1833
- args: ['attr.aria-controls']
1834
- }], id: [{
1835
- type: HostBinding,
1836
- args: ['attr.id']
1837
- }], direction: [{
1838
- type: HostBinding,
1839
- args: ['attr.dir']
1840
- }], hostTabIndex: [{
1841
- type: HostBinding,
1842
- args: ['attr.tabindex']
1843
- }], role: [{
1844
- type: HostBinding,
1845
- args: ['attr.role']
1846
- }], ariaHasPopup: [{
1847
- type: HostBinding,
1848
- args: ['attr.aria-haspopup']
1849
- }], isAriaExpanded: [{
1850
- type: HostBinding,
1851
- args: ['attr.aria-expanded']
1852
- }], hostAriaAutocomplete: [{
1853
- type: HostBinding,
1854
- args: ['attr.aria-autocomplete']
1855
- }], noDataTemplate: [{
1856
- type: ContentChild,
1857
- args: [NoDataTemplateDirective, { static: false }]
1858
- }], headerTemplate: [{
1859
- type: ContentChild,
1860
- args: [HeaderTemplateDirective, { static: false }]
1861
- }], footerTemplate: [{
1862
- type: ContentChild,
1863
- args: [FooterTemplateDirective, { static: false }]
1864
- }], nodeTemplate: [{
1865
- type: ContentChild,
1866
- args: [NodeTemplateDirective, { static: false }]
1867
- }], valueTemplate: [{
1868
- type: ContentChild,
1869
- args: [ValueTemplateDirective, { static: false }]
1870
- }], popupTemplate: [{
1871
- type: ViewChild,
1872
- args: ['popupTemplate', { static: true }]
1873
- }], container: [{
1874
- type: ViewChild,
1875
- args: ['container', { read: ViewContainerRef, static: true }]
1876
- }], treeview: [{
1877
- type: ViewChild,
1878
- args: ['treeview', { static: false }]
1879
- }], filterInput: [{
1880
- type: ViewChild,
1881
- args: ['filterInput', { static: false }]
1882
- }], open: [{
1883
- type: Output
1884
- }], opened: [{
1885
- type: Output
1886
- }], close: [{
1887
- type: Output
1888
- }], closed: [{
1889
- type: Output
1890
- }], nodeExpand: [{
1891
- type: Output
1892
- }], nodeCollapse: [{
1893
- type: Output
1894
- }], onFocus: [{
1895
- type: Output,
1896
- args: ['focus']
1897
- }], onBlur: [{
1898
- type: Output,
1899
- args: ['blur']
1900
- }], valueChange: [{
1901
- type: Output
1902
- }], filterChange: [{
1903
- type: Output
1904
- }], loading: [{
1905
- type: Input
1906
- }], clearButton: [{
1907
- type: Input
1908
- }], data: [{
1909
- type: Input
1910
- }], value: [{
1911
- type: Input
1912
- }], textField: [{
1913
- type: Input
1914
- }], valueField: [{
1915
- type: Input
1916
- }], valueDepth: [{
1917
- type: Input
1918
- }], hasChildren: [{
1919
- type: Input
1920
- }], fetchChildren: [{
1921
- type: Input
1922
- }], placeholder: [{
1923
- type: Input
1924
- }], popupSettings: [{
1925
- type: Input
1926
- }], dataItem: [{
1927
- type: Input
1928
- }], listHeight: [{
1929
- type: Input
1930
- }], disabled: [{
1931
- type: Input
1932
- }], readonly: [{
1933
- type: Input
1934
- }, {
1935
- type: HostBinding,
1936
- args: ['class.k-readonly']
1937
- }], valuePrimitive: [{
1938
- type: Input
1939
- }], tabindex: [{
1940
- type: Input
1941
- }], size: [{
1942
- type: Input
1943
- }], rounded: [{
1944
- type: Input
1945
- }], fillMode: [{
1946
- type: Input
1947
- }], itemDisabled: [{
1948
- type: Input
1949
- }], isNodeExpanded: [{
1950
- type: Input
1951
- }], isNodeVisible: [{
1952
- type: Input
1953
- }], loadOnDemand: [{
1954
- type: Input
1955
- }], filterable: [{
1956
- type: Input
1957
- }], filter: [{
1958
- type: Input
1959
- }], focusableId: [{
1960
- type: Input
1961
- }], adaptiveMode: [{
1962
- type: Input
1963
- }], adaptiveTitle: [{
1964
- type: Input
1965
- }], adaptiveSubtitle: [{
1966
- type: Input
1967
- }] } });