@ngneers/controls 0.0.1-pre1 → 0.0.1-pre2

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 (195) hide show
  1. package/LICENSE +21 -0
  2. package/fesm2022/ngneers-controls-accordion.mjs +194 -0
  3. package/fesm2022/ngneers-controls-accordion.mjs.map +1 -0
  4. package/fesm2022/ngneers-controls-api-ng.mjs +668 -0
  5. package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -0
  6. package/fesm2022/ngneers-controls-api.mjs +256 -227
  7. package/fesm2022/ngneers-controls-api.mjs.map +1 -1
  8. package/fesm2022/ngneers-controls-avatar.mjs +70 -0
  9. package/fesm2022/ngneers-controls-avatar.mjs.map +1 -0
  10. package/fesm2022/ngneers-controls-base.mjs +397 -0
  11. package/fesm2022/ngneers-controls-base.mjs.map +1 -0
  12. package/fesm2022/ngneers-controls-breadcrumb.mjs +74 -0
  13. package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -0
  14. package/fesm2022/ngneers-controls-button-group.mjs +51 -0
  15. package/fesm2022/ngneers-controls-button-group.mjs.map +1 -0
  16. package/fesm2022/ngneers-controls-button.mjs +62 -0
  17. package/fesm2022/ngneers-controls-button.mjs.map +1 -0
  18. package/fesm2022/ngneers-controls-calendar-time-C7UnIFzU.mjs +63 -0
  19. package/fesm2022/ngneers-controls-calendar-time-C7UnIFzU.mjs.map +1 -0
  20. package/fesm2022/ngneers-controls-calendar.mjs +468 -0
  21. package/fesm2022/ngneers-controls-calendar.mjs.map +1 -0
  22. package/fesm2022/ngneers-controls-checkbox.mjs +58 -0
  23. package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -0
  24. package/fesm2022/ngneers-controls-chip.mjs +52 -0
  25. package/fesm2022/ngneers-controls-chip.mjs.map +1 -0
  26. package/fesm2022/ngneers-controls-defer.mjs +43 -0
  27. package/fesm2022/ngneers-controls-defer.mjs.map +1 -0
  28. package/fesm2022/ngneers-controls-dialog.mjs +329 -33
  29. package/fesm2022/ngneers-controls-dialog.mjs.map +1 -1
  30. package/fesm2022/ngneers-controls-directives.mjs +443 -0
  31. package/fesm2022/ngneers-controls-directives.mjs.map +1 -0
  32. package/fesm2022/ngneers-controls-drawer.mjs +232 -0
  33. package/fesm2022/ngneers-controls-drawer.mjs.map +1 -0
  34. package/fesm2022/ngneers-controls-edit-inplace.mjs +120 -0
  35. package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -0
  36. package/fesm2022/ngneers-controls-filter.mjs +516 -0
  37. package/fesm2022/ngneers-controls-filter.mjs.map +1 -0
  38. package/fesm2022/ngneers-controls-i18n-de-CdTPeBiR.mjs +87 -0
  39. package/fesm2022/ngneers-controls-i18n-de-CdTPeBiR.mjs.map +1 -0
  40. package/fesm2022/ngneers-controls-i18n-en-Cfp2pOLY.mjs +87 -0
  41. package/fesm2022/ngneers-controls-i18n-en-Cfp2pOLY.mjs.map +1 -0
  42. package/fesm2022/ngneers-controls-i18n.mjs +57 -0
  43. package/fesm2022/ngneers-controls-i18n.mjs.map +1 -0
  44. package/fesm2022/ngneers-controls-icon-calendar-z5xA9wTT.mjs +4 -0
  45. package/fesm2022/ngneers-controls-icon-calendar-z5xA9wTT.mjs.map +1 -0
  46. package/fesm2022/ngneers-controls-icon-check-DdAQ9k-T.mjs +4 -0
  47. package/fesm2022/ngneers-controls-icon-check-DdAQ9k-T.mjs.map +1 -0
  48. package/fesm2022/ngneers-controls-icon-chevron_down-HO-z-xOr.mjs +4 -0
  49. package/fesm2022/ngneers-controls-icon-chevron_down-HO-z-xOr.mjs.map +1 -0
  50. package/fesm2022/ngneers-controls-icon-chevron_left-CC5psi16.mjs +4 -0
  51. package/fesm2022/ngneers-controls-icon-chevron_left-CC5psi16.mjs.map +1 -0
  52. package/fesm2022/ngneers-controls-icon-chevron_right-BRxlzx4G.mjs +4 -0
  53. package/fesm2022/ngneers-controls-icon-chevron_right-BRxlzx4G.mjs.map +1 -0
  54. package/fesm2022/ngneers-controls-icon-chevron_up-cqhPO7g2.mjs +4 -0
  55. package/fesm2022/ngneers-controls-icon-chevron_up-cqhPO7g2.mjs.map +1 -0
  56. package/fesm2022/ngneers-controls-icon-ellipsis-DXIGA1sk.mjs +4 -0
  57. package/fesm2022/ngneers-controls-icon-ellipsis-DXIGA1sk.mjs.map +1 -0
  58. package/fesm2022/ngneers-controls-icon-filter-oU7E6Xgr.mjs +4 -0
  59. package/fesm2022/ngneers-controls-icon-filter-oU7E6Xgr.mjs.map +1 -0
  60. package/fesm2022/ngneers-controls-icon-filter_solid-CqIKuR4N.mjs +4 -0
  61. package/fesm2022/ngneers-controls-icon-filter_solid-CqIKuR4N.mjs.map +1 -0
  62. package/fesm2022/ngneers-controls-icon-magnifying_glass-T4Hzbkig.mjs +4 -0
  63. package/fesm2022/ngneers-controls-icon-magnifying_glass-T4Hzbkig.mjs.map +1 -0
  64. package/fesm2022/ngneers-controls-icon-minus-oGDEFO4E.mjs +4 -0
  65. package/fesm2022/ngneers-controls-icon-minus-oGDEFO4E.mjs.map +1 -0
  66. package/fesm2022/ngneers-controls-icon-sort-CRD4tafz.mjs +4 -0
  67. package/fesm2022/ngneers-controls-icon-sort-CRD4tafz.mjs.map +1 -0
  68. package/fesm2022/ngneers-controls-icon-sort_down-DiFB1P6R.mjs +4 -0
  69. package/fesm2022/ngneers-controls-icon-sort_down-DiFB1P6R.mjs.map +1 -0
  70. package/fesm2022/ngneers-controls-icon-sort_up-Bq_q3hIi.mjs +4 -0
  71. package/fesm2022/ngneers-controls-icon-sort_up-Bq_q3hIi.mjs.map +1 -0
  72. package/fesm2022/ngneers-controls-icon-xmark-BZKZORiu.mjs +4 -0
  73. package/fesm2022/ngneers-controls-icon-xmark-BZKZORiu.mjs.map +1 -0
  74. package/fesm2022/ngneers-controls-icon.mjs +60 -18
  75. package/fesm2022/ngneers-controls-icon.mjs.map +1 -1
  76. package/fesm2022/ngneers-controls-inplace.mjs +107 -0
  77. package/fesm2022/ngneers-controls-inplace.mjs.map +1 -0
  78. package/fesm2022/ngneers-controls-input-field.mjs +141 -0
  79. package/fesm2022/ngneers-controls-input-field.mjs.map +1 -0
  80. package/fesm2022/ngneers-controls-input-mask.mjs +282 -0
  81. package/fesm2022/ngneers-controls-input-mask.mjs.map +1 -0
  82. package/fesm2022/ngneers-controls-input.mjs +69 -0
  83. package/fesm2022/ngneers-controls-input.mjs.map +1 -0
  84. package/fesm2022/ngneers-controls-item-view.mjs +441 -0
  85. package/fesm2022/ngneers-controls-item-view.mjs.map +1 -0
  86. package/fesm2022/ngneers-controls-list-box.mjs +157 -53
  87. package/fesm2022/ngneers-controls-list-box.mjs.map +1 -1
  88. package/fesm2022/ngneers-controls-menu.mjs +332 -0
  89. package/fesm2022/ngneers-controls-menu.mjs.map +1 -0
  90. package/fesm2022/ngneers-controls-message.mjs +29 -0
  91. package/fesm2022/ngneers-controls-message.mjs.map +1 -0
  92. package/fesm2022/ngneers-controls-paginator.mjs +111 -0
  93. package/fesm2022/ngneers-controls-paginator.mjs.map +1 -0
  94. package/fesm2022/ngneers-controls-popover.mjs +129 -40
  95. package/fesm2022/ngneers-controls-popover.mjs.map +1 -1
  96. package/fesm2022/ngneers-controls-progress.mjs +82 -0
  97. package/fesm2022/ngneers-controls-progress.mjs.map +1 -0
  98. package/fesm2022/ngneers-controls-scroller.mjs +155 -78
  99. package/fesm2022/ngneers-controls-scroller.mjs.map +1 -1
  100. package/fesm2022/ngneers-controls-select-button.mjs +55 -0
  101. package/fesm2022/ngneers-controls-select-button.mjs.map +1 -0
  102. package/fesm2022/ngneers-controls-select.mjs +313 -103
  103. package/fesm2022/ngneers-controls-select.mjs.map +1 -1
  104. package/fesm2022/ngneers-controls-slider.mjs +155 -0
  105. package/fesm2022/ngneers-controls-slider.mjs.map +1 -0
  106. package/fesm2022/ngneers-controls-spinner.mjs +169 -0
  107. package/fesm2022/ngneers-controls-spinner.mjs.map +1 -0
  108. package/fesm2022/ngneers-controls-splitter.mjs +717 -0
  109. package/fesm2022/ngneers-controls-splitter.mjs.map +1 -0
  110. package/fesm2022/ngneers-controls-switch.mjs +39 -0
  111. package/fesm2022/ngneers-controls-switch.mjs.map +1 -0
  112. package/fesm2022/ngneers-controls-table.mjs +379 -0
  113. package/fesm2022/ngneers-controls-table.mjs.map +1 -0
  114. package/fesm2022/ngneers-controls-tabs.mjs +287 -0
  115. package/fesm2022/ngneers-controls-tabs.mjs.map +1 -0
  116. package/fesm2022/ngneers-controls-tag.mjs +29 -0
  117. package/fesm2022/ngneers-controls-tag.mjs.map +1 -0
  118. package/fesm2022/ngneers-controls-toast.mjs +184 -0
  119. package/fesm2022/ngneers-controls-toast.mjs.map +1 -0
  120. package/fesm2022/ngneers-controls-toggle-button.mjs +65 -0
  121. package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -0
  122. package/fesm2022/ngneers-controls-tooltip.mjs +454 -0
  123. package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -0
  124. package/fesm2022/ngneers-controls-utils-ng.mjs +227 -0
  125. package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -0
  126. package/fesm2022/ngneers-controls-utils.mjs +217 -60
  127. package/fesm2022/ngneers-controls-utils.mjs.map +1 -1
  128. package/fesm2022/ngneers-controls.mjs.map +1 -1
  129. package/package.json +167 -32
  130. package/types/ngneers-controls-accordion.d.ts +114 -0
  131. package/types/ngneers-controls-api-ng.d.ts +291 -0
  132. package/types/ngneers-controls-api.d.ts +99 -0
  133. package/types/ngneers-controls-avatar.d.ts +50 -0
  134. package/types/ngneers-controls-base.d.ts +166 -0
  135. package/types/ngneers-controls-breadcrumb.d.ts +86 -0
  136. package/types/ngneers-controls-button-group.d.ts +30 -0
  137. package/types/ngneers-controls-button.d.ts +34 -0
  138. package/types/ngneers-controls-calendar.d.ts +275 -0
  139. package/types/ngneers-controls-checkbox.d.ts +38 -0
  140. package/types/ngneers-controls-chip.d.ts +37 -0
  141. package/types/ngneers-controls-defer.d.ts +22 -0
  142. package/types/ngneers-controls-dialog.d.ts +218 -0
  143. package/types/ngneers-controls-directives.d.ts +146 -0
  144. package/types/ngneers-controls-drawer.d.ts +220 -0
  145. package/types/ngneers-controls-edit-inplace.d.ts +182 -0
  146. package/types/ngneers-controls-filter.d.ts +304 -0
  147. package/types/ngneers-controls-i18n.d.ts +108 -0
  148. package/types/ngneers-controls-icon.d.ts +74 -0
  149. package/types/ngneers-controls-inplace.d.ts +95 -0
  150. package/types/ngneers-controls-input-field.d.ts +159 -0
  151. package/types/ngneers-controls-input-mask.d.ts +83 -0
  152. package/types/ngneers-controls-input.d.ts +27 -0
  153. package/types/ngneers-controls-item-view.d.ts +211 -0
  154. package/types/ngneers-controls-list-box.d.ts +216 -0
  155. package/types/ngneers-controls-menu.d.ts +178 -0
  156. package/types/ngneers-controls-message.d.ts +19 -0
  157. package/types/ngneers-controls-paginator.d.ts +162 -0
  158. package/types/ngneers-controls-popover.d.ts +101 -0
  159. package/types/ngneers-controls-progress.d.ts +44 -0
  160. package/types/ngneers-controls-scroller.d.ts +137 -0
  161. package/types/ngneers-controls-select-button.d.ts +37 -0
  162. package/types/ngneers-controls-select.d.ts +314 -0
  163. package/types/ngneers-controls-slider.d.ts +53 -0
  164. package/types/ngneers-controls-spinner.d.ts +105 -0
  165. package/types/ngneers-controls-splitter.d.ts +391 -0
  166. package/types/ngneers-controls-switch.d.ts +18 -0
  167. package/types/ngneers-controls-table.d.ts +157 -0
  168. package/types/ngneers-controls-tabs.d.ts +106 -0
  169. package/types/ngneers-controls-tag.d.ts +19 -0
  170. package/types/ngneers-controls-toast.d.ts +70 -0
  171. package/types/ngneers-controls-toggle-button.d.ts +46 -0
  172. package/types/ngneers-controls-tooltip.d.ts +188 -0
  173. package/types/ngneers-controls-utils-ng.d.ts +57 -0
  174. package/types/ngneers-controls-utils.d.ts +130 -0
  175. package/api/index.d.ts +0 -134
  176. package/custom-types/index.d.ts +0 -7
  177. package/dialog/index.d.ts +0 -43
  178. package/fesm2022/ngneers-controls-custom-types.mjs +0 -4
  179. package/fesm2022/ngneers-controls-custom-types.mjs.map +0 -1
  180. package/fesm2022/ngneers-controls-form-field.mjs +0 -33
  181. package/fesm2022/ngneers-controls-form-field.mjs.map +0 -1
  182. package/fesm2022/ngneers-controls-lazy-cacher.mjs +0 -30
  183. package/fesm2022/ngneers-controls-lazy-cacher.mjs.map +0 -1
  184. package/fesm2022/ngneers-controls-text-field.mjs +0 -23
  185. package/fesm2022/ngneers-controls-text-field.mjs.map +0 -1
  186. package/form-field/index.d.ts +0 -19
  187. package/icon/index.d.ts +0 -30
  188. package/lazy-cacher/index.d.ts +0 -14
  189. package/list-box/index.d.ts +0 -58
  190. package/popover/index.d.ts +0 -41
  191. package/scroller/index.d.ts +0 -95
  192. package/select/index.d.ts +0 -86
  193. package/text-field/index.d.ts +0 -10
  194. package/utils/index.d.ts +0 -36
  195. /package/{index.d.ts → types/ngneers-controls.d.ts} +0 -0
@@ -1,155 +1,365 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { viewChild, contentChild, input, computed, Component, linkedSignal, signal } from '@angular/core';
4
- import * as i1 from '@angular/forms';
5
- import { FormsModule } from '@angular/forms';
6
- import { ValueControlBase, templateTypesFn, transformToNgnItems, mapToItems, filterOptions, GetElementRef, NgnTemplate, valueControlBaseProvider } from '@ngneers/controls/api';
7
- import { FormField } from '@ngneers/controls/form-field';
8
- import { Icon } from '@ngneers/controls/icon';
9
- import { ListBox } from '@ngneers/controls/list-box';
10
- import { Popover } from '@ngneers/controls/popover';
11
- import { TextField } from '@ngneers/controls/text-field';
12
- import { asyncComputed } from '@ngneers/controls/utils';
3
+ import { viewChild, contentChild, input, computed, Directive, inject, booleanAttribute, linkedSignal, signal, effect, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { mapToItems } from '@ngneers/controls/api';
5
+ import { templateTypesFn, NgnTemplate } from '@ngneers/controls/api/ng';
6
+ import { ValueControlBase, NgnPt, provideSelf } from '@ngneers/controls/base';
7
+ import { I18n } from '@ngneers/controls/i18n';
8
+ import { NgnIcon } from '@ngneers/controls/icon';
9
+ import { NgnInput } from '@ngneers/controls/input';
10
+ import { NgnInputField } from '@ngneers/controls/input-field';
11
+ import { NgnItemView } from '@ngneers/controls/item-view';
12
+ import { NgnListBox } from '@ngneers/controls/list-box';
13
+ import { NgnPopover } from '@ngneers/controls/popover';
14
+ import { deepMerge, maybeCallback, NgnError } from '@ngneers/controls/utils';
15
+ import { selectControlTemplate } from '@ngneers/controls-themes/templates/select';
13
16
 
14
17
  class SelectTemplates extends ValueControlBase {
15
18
  // Item template
16
19
  _defaultItemTemplate = viewChild.required('defaultItemTemplate');
17
- _userItemTemplate = contentChild('item');
18
- templateItem = input(null);
19
- itemTemplate = computed(() => this._userItemTemplate() ?? this.templateItem() ?? this._defaultItemTemplate());
20
+ _userItemTemplate = contentChild('item', ...(ngDevMode ? [{ debugName: "_userItemTemplate" }] : []));
21
+ /**
22
+ * Set a custom template for an item of the select control.
23
+ * Can also be set using an `<ng-template>` element with `#item` template reference variable.
24
+ */
25
+ templateItem = input(null, ...(ngDevMode ? [{ debugName: "templateItem" }] : []));
26
+ itemTemplate = computed(() => this._userItemTemplate() ?? this.templateItem() ?? this._defaultItemTemplate(), ...(ngDevMode ? [{ debugName: "itemTemplate" }] : []));
20
27
  // Selected item template
21
28
  _defaultSelectedItemTemplate = viewChild.required('defaultSelectedItemTemplate');
22
- _userSelectedItemTemplate = contentChild('selectedItem');
23
- templateSelectedItem = input(null);
29
+ _userSelectedItemTemplate = contentChild('selectedItem', ...(ngDevMode ? [{ debugName: "_userSelectedItemTemplate" }] : []));
30
+ /**
31
+ * Set a custom template for the selected item of the select control.
32
+ * Can also be set using an `<ng-template>` element with `#selectedItem` template reference variable.
33
+ */
34
+ templateSelectedItem = input(null, ...(ngDevMode ? [{ debugName: "templateSelectedItem" }] : []));
24
35
  selectedItemTemplate = computed(() => this._userSelectedItemTemplate() ??
25
36
  this.templateSelectedItem() ??
26
- this._defaultSelectedItemTemplate());
37
+ this._defaultSelectedItemTemplate(), ...(ngDevMode ? [{ debugName: "selectedItemTemplate" }] : []));
38
+ // Selected items template
39
+ _defaultSelectedItemsTemplate = viewChild.required('defaultSelectedItemsTemplate');
40
+ _userSelectedItemsTemplate = contentChild('selectedItems', ...(ngDevMode ? [{ debugName: "_userSelectedItemsTemplate" }] : []));
41
+ /**
42
+ * Set a custom template for the selected items of the select control if {@link multiple} is `true`.
43
+ * Can also be set using an `<ng-template>` element with `#selectedItems` template reference variable.
44
+ */
45
+ templateSelectedItems = input(null, ...(ngDevMode ? [{ debugName: "templateSelectedItems" }] : []));
46
+ selectedItemsTemplate = computed(() => this._userSelectedItemsTemplate() ??
47
+ this.templateSelectedItems() ??
48
+ this._defaultSelectedItemsTemplate(), ...(ngDevMode ? [{ debugName: "selectedItemsTemplate" }] : []));
27
49
  // Group template
28
50
  _defaultGroupTemplate = viewChild.required('defaultGroupTemplate');
29
- _userGroupTemplate = contentChild('group');
30
- templateGroup = input(null);
31
- groupTemplate = computed(() => this._userGroupTemplate() ?? this.templateGroup() ?? this._defaultGroupTemplate());
51
+ _userGroupTemplate = contentChild('group', ...(ngDevMode ? [{ debugName: "_userGroupTemplate" }] : []));
52
+ /**
53
+ * Set a custom template for a group in the select control.
54
+ * Can also be set using an `<ng-template>` element with `#group` template reference variable.
55
+ */
56
+ templateGroup = input(null, ...(ngDevMode ? [{ debugName: "templateGroup" }] : []));
57
+ groupTemplate = computed(() => this._userGroupTemplate() ?? this.templateGroup() ?? this._defaultGroupTemplate(), ...(ngDevMode ? [{ debugName: "groupTemplate" }] : []));
58
+ // No items template
59
+ _userNoItemsTemplate = contentChild('noItems', ...(ngDevMode ? [{ debugName: "_userNoItemsTemplate" }] : []));
60
+ /**
61
+ * Set a custom template for the no items state of the select control.
62
+ * Can also be set using an `<ng-template>` element with `#noItems` template reference variable.
63
+ */
64
+ templateNoItems = input(null, ...(ngDevMode ? [{ debugName: "templateNoItems" }] : []));
65
+ noItemsTemplate = computed(() => this._userNoItemsTemplate() ?? this.templateNoItems(), ...(ngDevMode ? [{ debugName: "noItemsTemplate" }] : []));
32
66
  /**
33
67
  * Types for the dialog templates.
34
68
  */
35
69
  templateTypes = templateTypesFn();
36
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SelectTemplates, deps: null, target: i0.ɵɵFactoryTarget.Component });
37
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.5", type: SelectTemplates, isStandalone: true, selector: "ng-component", inputs: { templateItem: { classPropertyName: "templateItem", publicName: "templateItem", isSignal: true, isRequired: false, transformFunction: null }, templateSelectedItem: { classPropertyName: "templateSelectedItem", publicName: "templateSelectedItem", isSignal: true, isRequired: false, transformFunction: null }, templateGroup: { classPropertyName: "templateGroup", publicName: "templateGroup", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_userItemTemplate", first: true, predicate: ["item"], descendants: true, isSignal: true }, { propertyName: "_userSelectedItemTemplate", first: true, predicate: ["selectedItem"], descendants: true, isSignal: true }, { propertyName: "_userGroupTemplate", first: true, predicate: ["group"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_defaultItemTemplate", first: true, predicate: ["defaultItemTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultSelectedItemTemplate", first: true, predicate: ["defaultSelectedItemTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultGroupTemplate", first: true, predicate: ["defaultGroupTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
70
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SelectTemplates, deps: null, target: i0.ɵɵFactoryTarget.Directive });
71
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.1.0", type: SelectTemplates, isStandalone: true, inputs: { templateItem: { classPropertyName: "templateItem", publicName: "templateItem", isSignal: true, isRequired: false, transformFunction: null }, templateSelectedItem: { classPropertyName: "templateSelectedItem", publicName: "templateSelectedItem", isSignal: true, isRequired: false, transformFunction: null }, templateSelectedItems: { classPropertyName: "templateSelectedItems", publicName: "templateSelectedItems", isSignal: true, isRequired: false, transformFunction: null }, templateGroup: { classPropertyName: "templateGroup", publicName: "templateGroup", isSignal: true, isRequired: false, transformFunction: null }, templateNoItems: { classPropertyName: "templateNoItems", publicName: "templateNoItems", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_userItemTemplate", first: true, predicate: ["item"], descendants: true, isSignal: true }, { propertyName: "_userSelectedItemTemplate", first: true, predicate: ["selectedItem"], descendants: true, isSignal: true }, { propertyName: "_userSelectedItemsTemplate", first: true, predicate: ["selectedItems"], descendants: true, isSignal: true }, { propertyName: "_userGroupTemplate", first: true, predicate: ["group"], descendants: true, isSignal: true }, { propertyName: "_userNoItemsTemplate", first: true, predicate: ["noItems"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_defaultItemTemplate", first: true, predicate: ["defaultItemTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultSelectedItemTemplate", first: true, predicate: ["defaultSelectedItemTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultSelectedItemsTemplate", first: true, predicate: ["defaultSelectedItemsTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultGroupTemplate", first: true, predicate: ["defaultGroupTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
38
72
  }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: SelectTemplates, decorators: [{
40
- type: Component,
41
- args: [{
42
- imports: [],
43
- template: '',
44
- }]
45
- }] });
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SelectTemplates, decorators: [{
74
+ type: Directive
75
+ }], propDecorators: { _defaultItemTemplate: [{ type: i0.ViewChild, args: ['defaultItemTemplate', { isSignal: true }] }], _userItemTemplate: [{ type: i0.ContentChild, args: ['item', { isSignal: true }] }], templateItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateItem", required: false }] }], _defaultSelectedItemTemplate: [{ type: i0.ViewChild, args: ['defaultSelectedItemTemplate', { isSignal: true }] }], _userSelectedItemTemplate: [{ type: i0.ContentChild, args: ['selectedItem', { isSignal: true }] }], templateSelectedItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateSelectedItem", required: false }] }], _defaultSelectedItemsTemplate: [{ type: i0.ViewChild, args: ['defaultSelectedItemsTemplate', { isSignal: true }] }], _userSelectedItemsTemplate: [{ type: i0.ContentChild, args: ['selectedItems', { isSignal: true }] }], templateSelectedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateSelectedItems", required: false }] }], _defaultGroupTemplate: [{ type: i0.ViewChild, args: ['defaultGroupTemplate', { isSignal: true }] }], _userGroupTemplate: [{ type: i0.ContentChild, args: ['group', { isSignal: true }] }], templateGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateGroup", required: false }] }], _userNoItemsTemplate: [{ type: i0.ContentChild, args: ['noItems', { isSignal: true }] }], templateNoItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateNoItems", required: false }] }] } });
46
76
 
47
- class Select extends SelectTemplates {
48
- _popover = viewChild.required(Popover);
49
- popoverOptions = input({});
50
- appliedPopoverOptions = computed(() => ({
51
- ...this.popoverOptions(),
77
+ /**
78
+ * @category control
79
+ */
80
+ class NgnSelect extends SelectTemplates {
81
+ theme = this.injectThemeTemplate(selectControlTemplate, 'root');
82
+ i18n = inject(I18n).translations;
83
+ _popover = viewChild.required(NgnPopover);
84
+ _customEditableInput = contentChild(NgnInput, ...(ngDevMode ? [{ debugName: "_customEditableInput" }] : []));
85
+ _customEditableSub;
86
+ /**
87
+ * Options for the popover.
88
+ */
89
+ popoverOptions = input({}, ...(ngDevMode ? [{ debugName: "popoverOptions" }] : []));
90
+ appliedPopoverOptions = computed(() => deepMerge({
52
91
  sizeConstraints: {
53
92
  width: 1,
54
93
  maxWidth: 1,
55
- ...this.popoverOptions().sizeConstraints,
94
+ minHeight: '250px',
95
+ maxHeight: '700px',
56
96
  },
57
- }));
58
- options = input([]);
59
- fields = input();
60
- filter = input();
61
- filterText = input();
62
- filterIcon = input();
63
- virtual = input(false);
64
- itemHeight = input();
65
- _listbox = viewChild(ListBox);
66
- filterTextInternal = linkedSignal(this.filterText);
67
- currentHighlightedValue = signal(null);
68
- _options = computed(() => {
69
- const fields = this.fields();
70
- const options = this.options();
71
- if (!fields) {
72
- return options;
73
- }
74
- return transformToNgnItems(options, fields);
75
- });
76
- _flatOptions = computed(() => mapToItems(this._options()));
77
- _appliedFilterOptions = computed(() => {
78
- const filter = this.filter();
79
- if (!filter) {
80
- return null;
97
+ }, this.popoverOptions()), ...(ngDevMode ? [{ debugName: "appliedPopoverOptions" }] : []));
98
+ /**
99
+ * The available options to choose from. They can either be
100
+ * * A list of {@link NgnItem} objects
101
+ * * A list of plain objects. You'll have to provide a {@link fields} input to specify how to map the plain objects to {@link NgnItem} objects.
102
+ */
103
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
104
+ /**
105
+ * Accepts a boolean value that determines whether the filter is enabled.
106
+ * Alternatively, you can provide `SelectFilterOptions` to customize the filter behavior.
107
+ * @default `false`
108
+ */
109
+ filter = input(false, ...(ngDevMode ? [{ debugName: "filter" }] : []));
110
+ /**
111
+ * Manually set the filter text.
112
+ */
113
+ filterText = input(null, ...(ngDevMode ? [{ debugName: "filterText" }] : []));
114
+ /**
115
+ * The icon to display in the filter input.
116
+ */
117
+ filterIcon = input(...(ngDevMode ? [undefined, { debugName: "filterIcon" }] : []));
118
+ /**
119
+ * The icon to display in the dropdown.
120
+ */
121
+ dropdownIcon = input(...(ngDevMode ? [undefined, { debugName: "dropdownIcon" }] : []));
122
+ /**
123
+ * Whether the select is virtualized.
124
+ * @default `false`
125
+ */
126
+ virtual = input(false, { ...(ngDevMode ? { debugName: "virtual" } : {}), transform: booleanAttribute });
127
+ /**
128
+ * When {@link virtual} is enabled, this property defines the height of each item in the list.
129
+ */
130
+ itemHeight = input(...(ngDevMode ? [undefined, { debugName: "itemHeight" }] : []));
131
+ /**
132
+ * Enable this to allow the user to type in a value that is not in the list.
133
+ * When enabled, the value of the control becomes the label of a selected item or the typed value.
134
+ *
135
+ * Cannot be used with
136
+ * * {@link multiple} selection
137
+ * * {@link filter} without also setting {@link editableAutoFilter} to `false`
138
+ *
139
+ * @default `false`
140
+ */
141
+ editable = input(...(ngDevMode ? [undefined, { debugName: "editable" }] : []));
142
+ /**
143
+ * Whether to automatically filter the options based on the user's input in the {@link editable} input.
144
+ * @default `true`
145
+ */
146
+ editableAutoFilter = input(true, { ...(ngDevMode ? { debugName: "editableAutoFilter" } : {}), transform: booleanAttribute });
147
+ /**
148
+ * Enable this to allow the user to select multiple values.
149
+ * When enabled, the value of the control becomes an array of selected items.
150
+ *
151
+ * This is only applicable when {@link editable} is `false`.
152
+ * @default `false`
153
+ */
154
+ multiple = input(...(ngDevMode ? [undefined, { debugName: "multiple" }] : []));
155
+ /**
156
+ * Whether to scroll to the selected item when the dropdown is opened.
157
+ * @default `true`
158
+ */
159
+ scrollToSelectedItemOnOpen = input(true, ...(ngDevMode ? [{ debugName: "scrollToSelectedItemOnOpen" }] : []));
160
+ /**
161
+ * Tabindex for the select control.
162
+ * @default `0`
163
+ */
164
+ tabindex = input(0, ...(ngDevMode ? [{ debugName: "tabindex" }] : []));
165
+ /**
166
+ * Whether to use a checkbox to indicate selection state.
167
+ *
168
+ * This option is true per default when {@link multiple} is `true`.
169
+ * @default multiple()
170
+ */
171
+ checkbox = input(...(ngDevMode ? [undefined, { debugName: "checkbox" }] : []));
172
+ maybeCallback = maybeCallback;
173
+ _listbox = viewChild(NgnListBox, ...(ngDevMode ? [{ debugName: "_listbox" }] : []));
174
+ _userChangedEditableInput = false;
175
+ filterTextInternal = linkedSignal(this.filterText, ...(ngDevMode ? [{ debugName: "filterTextInternal" }] : []));
176
+ currentHighlightedValue = signal(null, ...(ngDevMode ? [{ debugName: "currentHighlightedValue" }] : []));
177
+ valueStr = computed(() => {
178
+ const v = this.value();
179
+ return typeof v === 'string' ? v : null;
180
+ }, ...(ngDevMode ? [{ debugName: "valueStr" }] : []));
181
+ valueArray = computed(() => {
182
+ const v = this.value();
183
+ return Array.isArray(v) ? v : v ? [v] : [];
184
+ }, ...(ngDevMode ? [{ debugName: "valueArray" }] : []));
185
+ appliedFilter = computed(() => this.filter() || this.editable() || false, ...(ngDevMode ? [{ debugName: "appliedFilter" }] : []));
186
+ _flatOptions = computed(() => mapToItems(this.options()), ...(ngDevMode ? [{ debugName: "_flatOptions" }] : []));
187
+ selectedItems = computed(() => {
188
+ if (this.editable()) {
189
+ return [this._flatOptions().find(option => option.label === this.value())];
81
190
  }
82
- const providedFilterArgs = typeof filter === 'boolean' ? {} : filter;
83
- const options = {
84
- filterFieldsCallback: item => item.label,
85
- fieldItems: 'items',
86
- splitWords: true,
87
- caseSensitive: false,
88
- clearFilterOnClose: true,
89
- filterFn: 'contains',
90
- ...providedFilterArgs,
91
- };
92
- return options;
93
- });
94
- // Replace with resource API when previous value persists
95
- filteredOptions = asyncComputed(async () => {
96
- const filter = this._appliedFilterOptions();
97
- const filterText = this.filterTextInternal();
98
- if (!filter || !filterText) {
99
- return this._options();
191
+ else {
192
+ return this.valueArray().map(value => this._flatOptions().find(option => option.value === value));
100
193
  }
101
- return await filterOptions(this._options(), filterText, filter);
102
- }, []);
103
- filterIsExecuting = this.filteredOptions.isRunning;
104
- selectedItem = computed(() => this._flatOptions().find(option => option.value === this.value()));
194
+ }, ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
195
+ selectedItemsValues = computed(() => this.selectedItems().map(item => item?.value), ...(ngDevMode ? [{ debugName: "selectedItemsValues" }] : []));
196
+ constructor() {
197
+ super();
198
+ effect(() => {
199
+ if (this.editable() && this.multiple()) {
200
+ throw new NgnError('select', 'Editable and multiple selection cannot be used together');
201
+ }
202
+ if (this.editable() && this.filter()) {
203
+ throw new NgnError('select', 'Editable and filtering cannot be used together');
204
+ }
205
+ });
206
+ effect(() => {
207
+ this._customEditableSub?.unsubscribe();
208
+ const editable = this.editable();
209
+ const customEditableInput = this._customEditableInput();
210
+ if (!editable || !customEditableInput) {
211
+ return;
212
+ }
213
+ this._customEditableSub = customEditableInput.value.subscribe(value => {
214
+ this.onEditableChange(value);
215
+ });
216
+ // Set ARIA attributes for accessibility
217
+ customEditableInput.element.nativeElement.setAttribute('aria-autocomplete', 'list');
218
+ customEditableInput.element.nativeElement.setAttribute('aria-expanded', `${this._popover().open()}`);
219
+ customEditableInput.element.nativeElement.setAttribute('aria-haspopup', 'listbox');
220
+ customEditableInput.element.nativeElement.setAttribute('aria-controls', `${this.inputId()}_listbox`);
221
+ });
222
+ effect(() => {
223
+ if (!this.editable()) {
224
+ return;
225
+ }
226
+ const valueSig = this._customEditableInput()?.value;
227
+ if (valueSig) {
228
+ valueSig.set(this.value() || '');
229
+ }
230
+ });
231
+ effect(() => {
232
+ if (!this.editable()) {
233
+ return;
234
+ }
235
+ const hasOptions = !!this._listbox()?.displayedItems().length;
236
+ if (!this._userChangedEditableInput) {
237
+ return;
238
+ }
239
+ this._userChangedEditableInput = false;
240
+ if (hasOptions) {
241
+ this.show();
242
+ }
243
+ else {
244
+ this.hide();
245
+ }
246
+ });
247
+ }
105
248
  onKeyDown(event) {
106
249
  this._listbox()?.onKeyDown(event);
107
250
  // if event is not handled by the listbox, we can handle it here
108
251
  if (!event.defaultPrevented) {
109
- if (event.key === 'Enter' || event.key === ' ') {
252
+ if (event.key === 'Enter') {
253
+ if (this.readonly() || this.disabled()) {
254
+ return;
255
+ }
110
256
  this._popover().toggle();
111
257
  event.stopPropagation();
112
258
  event.preventDefault();
113
259
  }
260
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
261
+ if (this.readonly() || this.disabled()) {
262
+ return;
263
+ }
264
+ const currentIndex = this.options().findIndex(option => option.value === this.value());
265
+ let newIndex = event.key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1;
266
+ if (newIndex < 0) {
267
+ newIndex = 0;
268
+ }
269
+ if (newIndex >= this.options().length) {
270
+ newIndex = this.options().length - 1;
271
+ }
272
+ const newValue = this.options()[newIndex]?.value;
273
+ if (newValue !== undefined) {
274
+ this.onSelect(newValue);
275
+ }
276
+ }
114
277
  }
115
278
  }
116
279
  onPopoverClosed() {
280
+ this.potentiallyBlurred();
117
281
  this.currentHighlightedValue.set(null);
118
- if (this._appliedFilterOptions()?.clearFilterOnClose) {
119
- this.filterTextInternal.set('');
282
+ const filter = this.filter();
283
+ if (filter === true || (typeof filter === 'object' && filter.clearFilterOnClose)) {
284
+ if (!this.editable()) {
285
+ this.filterTextInternal.set('');
286
+ }
120
287
  }
121
288
  }
122
289
  onSelect(value) {
123
- if (this.value() !== value) {
124
- this.value.set(value);
125
- this.onChange(value);
290
+ if (this.editable()) {
291
+ const item = this._flatOptions().find(option => option.value === value);
292
+ if (item) {
293
+ this.value.set(maybeCallback(item.label));
294
+ }
295
+ }
296
+ else {
297
+ const v = value;
298
+ if (this.value() !== v) {
299
+ this.value.set(v);
300
+ }
301
+ }
302
+ }
303
+ onItemClicked() {
304
+ if (!this.multiple()) {
305
+ this.hide();
306
+ }
307
+ }
308
+ /**
309
+ * Shows the select dropdown.
310
+ */
311
+ show() {
312
+ if (this.disabled() || this.readonly()) {
313
+ return;
126
314
  }
127
- this.close();
315
+ this._popover().show();
316
+ }
317
+ /**
318
+ * Hides the select dropdown.
319
+ */
320
+ hide() {
321
+ this._popover().hide();
128
322
  }
129
- close() {
130
- this._popover().close();
323
+ onEditableChange(value) {
324
+ if (this.editable()) {
325
+ this.value.set(maybeCallback(value));
326
+ this._userChangedEditableInput = true;
327
+ if (this.editableAutoFilter()) {
328
+ this.filterTextInternal.set(value);
329
+ }
330
+ }
331
+ }
332
+ potentiallyBlurred() {
333
+ setTimeout(() => {
334
+ if (this.element.nativeElement.contains(document.activeElement) || this._popover().open()) {
335
+ return;
336
+ }
337
+ this.touched.set(true);
338
+ });
131
339
  }
132
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: Select, deps: null, target: i0.ɵɵFactoryTarget.Component });
133
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.5", type: Select, isStandalone: true, selector: "ngn-select", inputs: { popoverOptions: { classPropertyName: "popoverOptions", publicName: "popoverOptions", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, fields: { classPropertyName: "fields", publicName: "fields", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterText: { classPropertyName: "filterText", publicName: "filterText", isSignal: true, isRequired: false, transformFunction: null }, filterIcon: { classPropertyName: "filterIcon", publicName: "filterIcon", isSignal: true, isRequired: false, transformFunction: null }, virtual: { classPropertyName: "virtual", publicName: "virtual", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null } }, providers: [valueControlBaseProvider(Select)], viewQueries: [{ propertyName: "_popover", first: true, predicate: Popover, descendants: true, isSignal: true }, { propertyName: "_listbox", first: true, predicate: ListBox, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ngn-form-field\r\n (click)=\"popover.open()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n ngnElementRef\r\n #field=\"ngnElementRef\"\r\n [label]=\"label()\"\r\n [inputId]=\"inputId()\"\r\n>\r\n <div class=\"ngn-select-trigger\" tabindex=\"0\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"selectedItemTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItem(),\r\n }\"\r\n ></ng-template>\r\n </div>\r\n</ngn-form-field>\r\n<ngn-popover\r\n #popover\r\n class=\"ngn-select-popover\"\r\n [options]=\"appliedPopoverOptions()\"\r\n [anchor]=\"field.nativeElement\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (closed)=\"onPopoverClosed()\"\r\n ngnElementRef\r\n #popoverElement=\"ngnElementRef\"\r\n>\r\n <ng-template #lazy>\r\n @if (filter()) {\r\n <ngn-form-field>\r\n <ngn-text-field\r\n [ngModel]=\"filterTextInternal()\"\r\n (ngModelChange)=\"filterTextInternal.set($event)\"\r\n />\r\n <ngn-icon defaultIcon=\"fa-solid fa-magnifying-glass\" [icon]=\"filterIcon()\" />\r\n @if (filterIsExecuting()) {\r\n <!-- TODO: replace with spinner -->\r\n <ngn-icon defaultIcon=\"fa-solid fa-spinner fa-spin\" />\r\n }\r\n </ngn-form-field>\r\n }\r\n <ngn-list-box\r\n [highlightable]=\"false\"\r\n [selectable]=\"true\"\r\n [items]=\"filteredOptions()\"\r\n [itemHeight]=\"itemHeight()\"\r\n [virtual]=\"virtual()\"\r\n [templateItem]=\"itemTemplate()\"\r\n [templateGroup]=\"groupTemplate()\"\r\n [fields]=\"{\r\n groupItems: 'items',\r\n value: 'value',\r\n label: 'label',\r\n testId: 'testId',\r\n }\"\r\n [ngModel]=\"selectedItem()?.value\"\r\n (ngModelChange)=\"onSelect($event)\"\r\n />\r\n </ng-template>\r\n</ngn-popover>\r\n\r\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">{{ item?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n\r\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\r\n <span [attr.data-testid]=\"group?.testId\">{{ group?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">{{ item?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n", dependencies: [{ kind: "component", type: FormField, selector: "ngn-form-field", inputs: ["label", "inputId"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ListBox, selector: "ngn-list-box", inputs: ["items", "fields", "selectable", "highlightable", "virtual", "itemHeight"] }, { kind: "component", type: TextField, selector: "ngn-text-field" }, { kind: "component", type: Popover, selector: "ngn-popover", inputs: ["anchor", "options"], outputs: ["opened", "closed"] }, { kind: "directive", type: GetElementRef, selector: "[ngnElementRef]", exportAs: ["ngnElementRef"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgnTemplate, selector: "ng-template[ngnTemplate]", inputs: ["ngnTemplate"] }, { kind: "component", type: Icon, selector: "ngn-icon", inputs: ["defaultIcon", "icon"] }] });
340
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NgnSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: NgnSelect, isStandalone: true, selector: "ngn-select", inputs: { popoverOptions: { classPropertyName: "popoverOptions", publicName: "popoverOptions", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterText: { classPropertyName: "filterText", publicName: "filterText", isSignal: true, isRequired: false, transformFunction: null }, filterIcon: { classPropertyName: "filterIcon", publicName: "filterIcon", isSignal: true, isRequired: false, transformFunction: null }, dropdownIcon: { classPropertyName: "dropdownIcon", publicName: "dropdownIcon", isSignal: true, isRequired: false, transformFunction: null }, virtual: { classPropertyName: "virtual", publicName: "virtual", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, editableAutoFilter: { classPropertyName: "editableAutoFilter", publicName: "editableAutoFilter", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, scrollToSelectedItemOnOpen: { classPropertyName: "scrollToSelectedItemOnOpen", publicName: "scrollToSelectedItemOnOpen", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", isSignal: true, isRequired: false, transformFunction: null }, checkbox: { classPropertyName: "checkbox", publicName: "checkbox", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: block;" }, providers: [provideSelf(NgnSelect)], queries: [{ propertyName: "_customEditableInput", first: true, predicate: NgnInput, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_popover", first: true, predicate: NgnPopover, descendants: true, isSignal: true }, { propertyName: "_listbox", first: true, predicate: NgnListBox, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ngn-input-field\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n input: true,\r\n 'input-editable': editable(),\r\n }\"\r\n (click)=\"show()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n #field\r\n [label]=\"label()\"\r\n [labelledBy]=\"labelledBy()\"\r\n [inputId]=\"inputId()\"\r\n [invalid]=\"invalid()\"\r\n [readonly]=\"readonly()\"\r\n [disabled]=\"disabled()\"\r\n [tabindex]=\"editable() || disabled() ? -1 : tabindex()\"\r\n (focusout)=\"potentiallyBlurred()\"\r\n>\r\n @if (editable()) {\r\n <ng-content select=\"[ngnInput]\">\r\n <input\r\n ngnInput\r\n autocomplete=\"list\"\r\n [aria-expanded]=\"popover.open()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-controls]=\"inputId() + '_listbox'\"\r\n [id]=\"inputId()\"\r\n [value]=\"valueStr() || ''\"\r\n (valueChange)=\"onEditableChange($event)\"\r\n [readOnly]=\"readonly()\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </ng-content>\r\n } @else {\r\n <div\r\n role=\"combobox\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'combobox'\"\r\n [aria-expanded]=\"popover.open()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-controls]=\"inputId() + '_listbox'\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n [id]=\"inputId()\"\r\n >\r\n @if (multiple()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"selectedItemsTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItems(),\r\n }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"selectedItemTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItems()[0],\r\n }\"\r\n />\r\n }\r\n </div>\r\n }\r\n <ngn-icon [ptInt]=\"this\" [ptClass]=\"'icon'\" [icon]=\"dropdownIcon()\" defaultIcon=\"chevron_down\" />\r\n</ngn-input-field>\r\n<ngn-popover\r\n #popover\r\n [options]=\"appliedPopoverOptions()\"\r\n [anchor]=\"field.element.nativeElement\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (closed)=\"onPopoverClosed()\"\r\n [id]=\"inputId() + '_popover'\"\r\n [hasShrinkableContent]=\"true\"\r\n>\r\n <ng-template #lazy>\r\n <div [ptInt]=\"this\" [ptClass]=\"'popover-content'\">\r\n @if (filter()) {\r\n <ngn-input-field [ptInt]=\"this\" [ptClass]=\"'filter'\">\r\n <input\r\n ngnInput\r\n [value]=\"filterTextInternal()\"\r\n (valueChange)=\"filterTextInternal.set($event)\"\r\n />\r\n <ngn-icon\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'filter-icon'\"\r\n defaultIcon=\"magnifying_glass\"\r\n [icon]=\"filterIcon()\"\r\n />\r\n </ngn-input-field>\r\n }\r\n <ngn-list-box\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n 'list-box': true,\r\n }\"\r\n style=\"height: 100%; min-height: 0\"\r\n [focussable]=\"false\"\r\n [selectable]=\"true\"\r\n [filter]=\"appliedFilter()\"\r\n [filterText]=\"filterTextInternal()\"\r\n [items]=\"options()\"\r\n [itemHeight]=\"itemHeight()\"\r\n [virtual]=\"virtual()\"\r\n [templateItem]=\"itemTemplate()\"\r\n [templateGroup]=\"groupTemplate()\"\r\n [multiple]=\"multiple()\"\r\n [value]=\"multiple() ? selectedItemsValues() : selectedItemsValues()[0]\"\r\n [scrollToSelectedItemOnInit]=\"scrollToSelectedItemOnOpen()\"\r\n (valueChange)=\"onSelect($event)\"\r\n (itemClicked)=\"onItemClicked()\"\r\n [inputId]=\"inputId() + '_listbox'\"\r\n [templateEmpty]=\"noItemsTemplate()\"\r\n [checkbox]=\"checkbox()\"\r\n />\r\n </div>\r\n </ng-template>\r\n</ngn-popover>\r\n\r\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">\r\n @let label = item?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\r\n <span [attr.data-testid]=\"group?.testId\">\r\n @let label = group?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"group?.testId\">{{ maybeCallback(label) }}</span>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n @let label = item?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\r\n } @else {\r\n <span [attr.data-testid]=\"item?.testId\">&ZeroWidthSpace;</span>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemsTemplate [ngnTemplate]=\"templateTypes.selectedItems\" let-items>\r\n <ngn-item-view\r\n #itemView\r\n [items]=\"items\"\r\n [idField]=\"'value'\"\r\n [separator]=\"true\"\r\n style=\"margin-right: 8px\"\r\n >\r\n <ng-template #item let-item [ngnTemplate]=\"itemView.templateTypes.item\">\r\n <ng-container\r\n *ngTemplateOutlet=\"selectedItemTemplate(); context: { $implicit: item }\"\r\n ></ng-container>\r\n </ng-template>\r\n </ngn-item-view>\r\n @if (items.length < 1) {\r\n &ZeroWidthSpace;\r\n }\r\n</ng-template>\r\n", dependencies: [{ kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass"] }, { kind: "component", type: NgnInputField, selector: "ngn-input-field", inputs: ["label", "labelledBy", "labelKind", "inputId", "showClearButton", "iconClearButton", "tabindex", "invalid", "readonly", "disabled"] }, { kind: "component", type: NgnListBox, selector: "ngn-list-box", inputs: ["items", "scrollToSelectedItemOnInit", "selectable", "selectOnHover", "focussable", "virtual", "itemHeight", "multiple", "checkbox", "filter", "filterText"], outputs: ["itemClicked"] }, { kind: "component", type: NgnPopover, selector: "ngn-popover", inputs: ["open", "anchor", "options", "hasShrinkableContent", "closeBy"], outputs: ["closed", "closing", "openChange"] }, { kind: "directive", type: NgnInput, selector: "input[ngnInput], textarea[ngnInput]", inputs: ["invalid", "value"], outputs: ["valueChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgnTemplate, selector: "ng-template[ngnTemplate]", inputs: ["ngnTemplate"] }, { kind: "component", type: NgnItemView, selector: "ngn-item-view", inputs: ["idField", "items", "separator", "iconItemSeparator", "overflowStrategy", "overflowStrategyFreezeCount", "overflowStrategyIndex", "sameWidthItems"] }, { kind: "component", type: NgnIcon, selector: "ngn-icon", inputs: ["defaultIcon", "icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
134
342
  }
135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: Select, decorators: [{
343
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NgnSelect, decorators: [{
136
344
  type: Component,
137
- args: [{ selector: 'ngn-select', imports: [
138
- FormField,
139
- FormsModule,
140
- ListBox,
141
- TextField,
142
- Popover,
143
- GetElementRef,
345
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngn-select', imports: [
346
+ NgnPt,
347
+ NgnInputField,
348
+ NgnListBox,
349
+ NgnPopover,
350
+ NgnInput,
144
351
  NgTemplateOutlet,
145
352
  NgnTemplate,
146
- Icon,
147
- ], providers: [valueControlBaseProvider(Select)], template: "<ngn-form-field\r\n (click)=\"popover.open()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n ngnElementRef\r\n #field=\"ngnElementRef\"\r\n [label]=\"label()\"\r\n [inputId]=\"inputId()\"\r\n>\r\n <div class=\"ngn-select-trigger\" tabindex=\"0\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"selectedItemTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItem(),\r\n }\"\r\n ></ng-template>\r\n </div>\r\n</ngn-form-field>\r\n<ngn-popover\r\n #popover\r\n class=\"ngn-select-popover\"\r\n [options]=\"appliedPopoverOptions()\"\r\n [anchor]=\"field.nativeElement\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (closed)=\"onPopoverClosed()\"\r\n ngnElementRef\r\n #popoverElement=\"ngnElementRef\"\r\n>\r\n <ng-template #lazy>\r\n @if (filter()) {\r\n <ngn-form-field>\r\n <ngn-text-field\r\n [ngModel]=\"filterTextInternal()\"\r\n (ngModelChange)=\"filterTextInternal.set($event)\"\r\n />\r\n <ngn-icon defaultIcon=\"fa-solid fa-magnifying-glass\" [icon]=\"filterIcon()\" />\r\n @if (filterIsExecuting()) {\r\n <!-- TODO: replace with spinner -->\r\n <ngn-icon defaultIcon=\"fa-solid fa-spinner fa-spin\" />\r\n }\r\n </ngn-form-field>\r\n }\r\n <ngn-list-box\r\n [highlightable]=\"false\"\r\n [selectable]=\"true\"\r\n [items]=\"filteredOptions()\"\r\n [itemHeight]=\"itemHeight()\"\r\n [virtual]=\"virtual()\"\r\n [templateItem]=\"itemTemplate()\"\r\n [templateGroup]=\"groupTemplate()\"\r\n [fields]=\"{\r\n groupItems: 'items',\r\n value: 'value',\r\n label: 'label',\r\n testId: 'testId',\r\n }\"\r\n [ngModel]=\"selectedItem()?.value\"\r\n (ngModelChange)=\"onSelect($event)\"\r\n />\r\n </ng-template>\r\n</ngn-popover>\r\n\r\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">{{ item?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n\r\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\r\n <span [attr.data-testid]=\"group?.testId\">{{ group?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">{{ item?.label }}&ZeroWidthSpace;</span>\r\n</ng-template>\r\n" }]
148
- }] });
353
+ NgnItemView,
354
+ NgnIcon,
355
+ ], providers: [provideSelf(NgnSelect)], host: {
356
+ style: 'display: block;',
357
+ }, template: "<ngn-input-field\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n input: true,\r\n 'input-editable': editable(),\r\n }\"\r\n (click)=\"show()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n #field\r\n [label]=\"label()\"\r\n [labelledBy]=\"labelledBy()\"\r\n [inputId]=\"inputId()\"\r\n [invalid]=\"invalid()\"\r\n [readonly]=\"readonly()\"\r\n [disabled]=\"disabled()\"\r\n [tabindex]=\"editable() || disabled() ? -1 : tabindex()\"\r\n (focusout)=\"potentiallyBlurred()\"\r\n>\r\n @if (editable()) {\r\n <ng-content select=\"[ngnInput]\">\r\n <input\r\n ngnInput\r\n autocomplete=\"list\"\r\n [aria-expanded]=\"popover.open()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-controls]=\"inputId() + '_listbox'\"\r\n [id]=\"inputId()\"\r\n [value]=\"valueStr() || ''\"\r\n (valueChange)=\"onEditableChange($event)\"\r\n [readOnly]=\"readonly()\"\r\n [disabled]=\"disabled()\"\r\n />\r\n </ng-content>\r\n } @else {\r\n <div\r\n role=\"combobox\"\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'combobox'\"\r\n [aria-expanded]=\"popover.open()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-controls]=\"inputId() + '_listbox'\"\r\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\r\n [attr.aria-readonly]=\"readonly() ? 'true' : null\"\r\n [attr.disabled]=\"disabled() ? '' : null\"\r\n [id]=\"inputId()\"\r\n >\r\n @if (multiple()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"selectedItemsTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItems(),\r\n }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"selectedItemTemplate()\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: selectedItems()[0],\r\n }\"\r\n />\r\n }\r\n </div>\r\n }\r\n <ngn-icon [ptInt]=\"this\" [ptClass]=\"'icon'\" [icon]=\"dropdownIcon()\" defaultIcon=\"chevron_down\" />\r\n</ngn-input-field>\r\n<ngn-popover\r\n #popover\r\n [options]=\"appliedPopoverOptions()\"\r\n [anchor]=\"field.element.nativeElement\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (closed)=\"onPopoverClosed()\"\r\n [id]=\"inputId() + '_popover'\"\r\n [hasShrinkableContent]=\"true\"\r\n>\r\n <ng-template #lazy>\r\n <div [ptInt]=\"this\" [ptClass]=\"'popover-content'\">\r\n @if (filter()) {\r\n <ngn-input-field [ptInt]=\"this\" [ptClass]=\"'filter'\">\r\n <input\r\n ngnInput\r\n [value]=\"filterTextInternal()\"\r\n (valueChange)=\"filterTextInternal.set($event)\"\r\n />\r\n <ngn-icon\r\n [ptInt]=\"this\"\r\n [ptClass]=\"'filter-icon'\"\r\n defaultIcon=\"magnifying_glass\"\r\n [icon]=\"filterIcon()\"\r\n />\r\n </ngn-input-field>\r\n }\r\n <ngn-list-box\r\n [ptInt]=\"this\"\r\n [ptClass]=\"{\r\n 'list-box': true,\r\n }\"\r\n style=\"height: 100%; min-height: 0\"\r\n [focussable]=\"false\"\r\n [selectable]=\"true\"\r\n [filter]=\"appliedFilter()\"\r\n [filterText]=\"filterTextInternal()\"\r\n [items]=\"options()\"\r\n [itemHeight]=\"itemHeight()\"\r\n [virtual]=\"virtual()\"\r\n [templateItem]=\"itemTemplate()\"\r\n [templateGroup]=\"groupTemplate()\"\r\n [multiple]=\"multiple()\"\r\n [value]=\"multiple() ? selectedItemsValues() : selectedItemsValues()[0]\"\r\n [scrollToSelectedItemOnInit]=\"scrollToSelectedItemOnOpen()\"\r\n (valueChange)=\"onSelect($event)\"\r\n (itemClicked)=\"onItemClicked()\"\r\n [inputId]=\"inputId() + '_listbox'\"\r\n [templateEmpty]=\"noItemsTemplate()\"\r\n [checkbox]=\"checkbox()\"\r\n />\r\n </div>\r\n </ng-template>\r\n</ngn-popover>\r\n\r\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n <span [attr.data-testid]=\"item?.testId\">\r\n @let label = item?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\r\n <span [attr.data-testid]=\"group?.testId\">\r\n @let label = group?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"group?.testId\">{{ maybeCallback(label) }}</span>\r\n }\r\n </span>\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\r\n @let label = item?.label;\r\n @if (label) {\r\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\r\n } @else {\r\n <span [attr.data-testid]=\"item?.testId\">&ZeroWidthSpace;</span>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultSelectedItemsTemplate [ngnTemplate]=\"templateTypes.selectedItems\" let-items>\r\n <ngn-item-view\r\n #itemView\r\n [items]=\"items\"\r\n [idField]=\"'value'\"\r\n [separator]=\"true\"\r\n style=\"margin-right: 8px\"\r\n >\r\n <ng-template #item let-item [ngnTemplate]=\"itemView.templateTypes.item\">\r\n <ng-container\r\n *ngTemplateOutlet=\"selectedItemTemplate(); context: { $implicit: item }\"\r\n ></ng-container>\r\n </ng-template>\r\n </ngn-item-view>\r\n @if (items.length < 1) {\r\n &ZeroWidthSpace;\r\n }\r\n</ng-template>\r\n" }]
358
+ }], ctorParameters: () => [], propDecorators: { _popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgnPopover), { isSignal: true }] }], _customEditableInput: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NgnInput), { isSignal: true }] }], popoverOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverOptions", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterText: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterText", required: false }] }], filterIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterIcon", required: false }] }], dropdownIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropdownIcon", required: false }] }], virtual: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtual", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], editableAutoFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "editableAutoFilter", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], scrollToSelectedItemOnOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToSelectedItemOnOpen", required: false }] }], tabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabindex", required: false }] }], checkbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkbox", required: false }] }], _listbox: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgnListBox), { isSignal: true }] }] } });
149
359
 
150
360
  /**
151
361
  * Generated bundle index. Do not edit.
152
362
  */
153
363
 
154
- export { Select };
364
+ export { NgnSelect };
155
365
  //# sourceMappingURL=ngneers-controls-select.mjs.map