@valtimo/components 4.15.2-next-main.14 → 4.15.3-next-main.15

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 (202) hide show
  1. package/bundles/valtimo-components.umd.js +4795 -4793
  2. package/bundles/valtimo-components.umd.js.map +1 -1
  3. package/bundles/valtimo-components.umd.min.js +1 -1
  4. package/bundles/valtimo-components.umd.min.js.map +1 -1
  5. package/esm2015/lib/alert/alert.component.js +141 -141
  6. package/esm2015/lib/alert/alert.module.js +27 -27
  7. package/esm2015/lib/alert/alert.service.js +80 -80
  8. package/esm2015/lib/bpmn-js-diagram/bpmn-js-diagram.component.js +159 -159
  9. package/esm2015/lib/bpmn-js-diagram/bpmn-js-diagram.module.js +29 -29
  10. package/esm2015/lib/breadcrumb-navigation/breadcrumb-navigation.component.js +92 -92
  11. package/esm2015/lib/breadcrumb-navigation/breadcrumb-navigation.module.js +33 -33
  12. package/esm2015/lib/camunda/form/camunda-form.components.js +36 -36
  13. package/esm2015/lib/camunda/form/camunda-form.module.js +37 -37
  14. package/esm2015/lib/camunda/form/custom/camunda-custom-form.component.js +41 -41
  15. package/esm2015/lib/camunda/form/custom/camunda-custom-form.module.js +33 -33
  16. package/esm2015/lib/camunda/form/generated/camunda-generated-form.component.js +68 -68
  17. package/esm2015/lib/camunda/form/generated/camunda-generated-form.module.js +62 -62
  18. package/esm2015/lib/camunda/form/generated/formfield/boolean/camunda-boolean-formfield.component.js +27 -27
  19. package/esm2015/lib/camunda/form/generated/formfield/camunda-formfield-generator.directive.js +63 -63
  20. package/esm2015/lib/camunda/form/generated/formfield/camunda-formfield.service.js +66 -66
  21. package/esm2015/lib/camunda/form/generated/formfield/choicefield/camunda-choicefield-formfield.component.js +37 -37
  22. package/esm2015/lib/camunda/form/generated/formfield/date/camunda-date-formfield.component.js +65 -65
  23. package/esm2015/lib/camunda/form/generated/formfield/enum/camunda-enum-formfield.component.js +30 -30
  24. package/esm2015/lib/camunda/form/generated/formfield/formfield.model.js +15 -15
  25. package/esm2015/lib/camunda/form/generated/formfield/long/camunda-long-formfield.component.js +27 -27
  26. package/esm2015/lib/camunda/form/generated/formfield/string/camunda-string-formfield.component.js +27 -27
  27. package/esm2015/lib/camunda/form/generated/formfield/textarea/camunda-textarea-formfield.component.js +27 -27
  28. package/esm2015/lib/camunda/form/generated/formfield/validation/camunda-formfield-validation.component.js +35 -35
  29. package/esm2015/lib/camunda/form/generated/formfield/validation/date.validators.js +59 -59
  30. package/esm2015/lib/card/card.component.js +36 -36
  31. package/esm2015/lib/card/card.module.js +29 -29
  32. package/esm2015/lib/components.module.js +21 -21
  33. package/esm2015/lib/data-list/data-list.component.js +33 -33
  34. package/esm2015/lib/data-list/data-list.module.js +29 -29
  35. package/esm2015/lib/dropzone/dropzone.component.js +142 -142
  36. package/esm2015/lib/dropzone/dropzone.module.js +31 -31
  37. package/esm2015/lib/field-auto-focus/field-auto-focus.directive.js +34 -34
  38. package/esm2015/lib/field-auto-focus/field-auto-focus.module.js +31 -31
  39. package/esm2015/lib/file-size/file-size.module.js +29 -29
  40. package/esm2015/lib/file-size/file-size.pipe.js +44 -44
  41. package/esm2015/lib/filter-sidebar/filter-sidebar.component.js +45 -45
  42. package/esm2015/lib/filter-sidebar/filter-sidebar.module.js +29 -29
  43. package/esm2015/lib/form-io/form-io-builder.component.js +38 -38
  44. package/esm2015/lib/form-io/form-io-uploader/form-io-uploader-edit-form.js +89 -89
  45. package/esm2015/lib/form-io/form-io-uploader/form-io-uploader.component.js +71 -71
  46. package/esm2015/lib/form-io/form-io-uploader/form-io-uploader.formio.js +25 -25
  47. package/esm2015/lib/form-io/form-io.component.js +157 -157
  48. package/esm2015/lib/form-io/form-io.module.js +55 -55
  49. package/esm2015/lib/form-io/formio-config.js +21 -21
  50. package/esm2015/lib/form-io/services/form-io-dom.service.js +22 -22
  51. package/esm2015/lib/form-io/services/form-io-state.service.js +23 -23
  52. package/esm2015/lib/left-sidebar/left-sidebar.component.js +113 -113
  53. package/esm2015/lib/left-sidebar/left-sidebar.module.js +33 -33
  54. package/esm2015/lib/list/ListFilterPipe.directive.js +34 -34
  55. package/esm2015/lib/list/list.component.js +176 -176
  56. package/esm2015/lib/list/list.module.js +32 -32
  57. package/esm2015/lib/menu/menu-item-text.component.js +27 -27
  58. package/esm2015/lib/menu/menu-routing.module.js +28 -28
  59. package/esm2015/lib/menu/menu.component.js +64 -64
  60. package/esm2015/lib/menu/menu.init.js +33 -33
  61. package/esm2015/lib/menu/menu.module.js +38 -38
  62. package/esm2015/lib/menu/menu.service.js +126 -126
  63. package/esm2015/lib/menu/submenu-item-text.component.js +27 -27
  64. package/esm2015/lib/modal/modal.component.js +47 -47
  65. package/esm2015/lib/modal/modal.module.js +27 -27
  66. package/esm2015/lib/page-header/page-header.component.js +28 -28
  67. package/esm2015/lib/page-header/page-header.module.js +33 -33
  68. package/esm2015/lib/page-title/page-title.component.js +75 -75
  69. package/esm2015/lib/page-title/page-title.module.js +31 -31
  70. package/esm2015/lib/progress-bar/progress-bar.component.js +25 -25
  71. package/esm2015/lib/progress-bar/progress-bar.module.js +29 -29
  72. package/esm2015/lib/right-sidebar/right-sidebar.component.js +130 -130
  73. package/esm2015/lib/right-sidebar/right-sidebar.module.js +48 -48
  74. package/esm2015/lib/searchable-dropdown/searchable-dropdown.component.js +184 -184
  75. package/esm2015/lib/searchable-dropdown/searchable-dropdown.module.js +28 -28
  76. package/esm2015/lib/searchable-dropdown-select/searchable-dropdown-select.component.js +51 -51
  77. package/esm2015/lib/searchable-dropdown-select/searchable-dropdown-select.module.js +29 -29
  78. package/esm2015/lib/spinner/spinner.component.js +45 -43
  79. package/esm2015/lib/spinner/spinner.module.js +35 -35
  80. package/esm2015/lib/timeline/timeline.component.js +28 -28
  81. package/esm2015/lib/timeline/timeline.module.js +31 -31
  82. package/esm2015/lib/topbar/topbar.component.js +28 -28
  83. package/esm2015/lib/topbar/topbar.module.js +31 -31
  84. package/esm2015/lib/uploader/uploader-drag-drop.directive.js +48 -48
  85. package/esm2015/lib/uploader/uploader.component.js +69 -69
  86. package/esm2015/lib/uploader/uploader.module.js +32 -32
  87. package/esm2015/lib/version/version.service.js +37 -37
  88. package/esm2015/lib/view-content/type-converters/booleanTypeConverter.js +28 -28
  89. package/esm2015/lib/view-content/type-converters/dateTypeConverter.js +29 -29
  90. package/esm2015/lib/view-content/type-converters/enumTypeConverter.js +23 -23
  91. package/esm2015/lib/view-content/type-converters/relatedFilesTypeConverter.js +23 -23
  92. package/esm2015/lib/view-content/type-converters/stringReplaceUnderscoreTypeConverter.js +26 -26
  93. package/esm2015/lib/view-content/type-converters/stringTypeConverter.js +23 -23
  94. package/esm2015/lib/view-content/type-converters/type-converters.model.js +36 -36
  95. package/esm2015/lib/view-content/view-content.service.js +50 -50
  96. package/esm2015/lib/webcam/webcam.component.js +102 -102
  97. package/esm2015/lib/webcam/webcam.module.js +31 -31
  98. package/esm2015/lib/widget/widget.component.js +79 -79
  99. package/esm2015/lib/widget/widget.module.js +29 -29
  100. package/esm2015/public_api.js +83 -83
  101. package/esm2015/valtimo-components.js +26 -26
  102. package/fesm2015/valtimo-components.js +4303 -4301
  103. package/fesm2015/valtimo-components.js.map +1 -1
  104. package/lib/alert/alert.component.d.ts +21 -21
  105. package/lib/alert/alert.module.d.ts +2 -2
  106. package/lib/alert/alert.service.d.ts +21 -21
  107. package/lib/bpmn-js-diagram/bpmn-js-diagram.component.d.ts +27 -27
  108. package/lib/bpmn-js-diagram/bpmn-js-diagram.module.d.ts +2 -2
  109. package/lib/breadcrumb-navigation/breadcrumb-navigation.component.d.ts +14 -14
  110. package/lib/breadcrumb-navigation/breadcrumb-navigation.module.d.ts +2 -2
  111. package/lib/camunda/form/camunda-form.components.d.ts +9 -9
  112. package/lib/camunda/form/camunda-form.module.d.ts +2 -2
  113. package/lib/camunda/form/custom/camunda-custom-form.component.d.ts +8 -8
  114. package/lib/camunda/form/custom/camunda-custom-form.module.d.ts +2 -2
  115. package/lib/camunda/form/generated/camunda-generated-form.component.d.ts +19 -19
  116. package/lib/camunda/form/generated/camunda-generated-form.module.d.ts +2 -2
  117. package/lib/camunda/form/generated/formfield/boolean/camunda-boolean-formfield.component.d.ts +7 -7
  118. package/lib/camunda/form/generated/formfield/camunda-formfield-generator.directive.d.ts +13 -13
  119. package/lib/camunda/form/generated/formfield/camunda-formfield.service.d.ts +7 -7
  120. package/lib/camunda/form/generated/formfield/choicefield/camunda-choicefield-formfield.component.d.ts +12 -12
  121. package/lib/camunda/form/generated/formfield/date/camunda-date-formfield.component.d.ts +14 -14
  122. package/lib/camunda/form/generated/formfield/enum/camunda-enum-formfield.component.d.ts +10 -10
  123. package/lib/camunda/form/generated/formfield/formfield.model.d.ts +20 -20
  124. package/lib/camunda/form/generated/formfield/long/camunda-long-formfield.component.d.ts +7 -7
  125. package/lib/camunda/form/generated/formfield/string/camunda-string-formfield.component.d.ts +7 -7
  126. package/lib/camunda/form/generated/formfield/textarea/camunda-textarea-formfield.component.d.ts +7 -7
  127. package/lib/camunda/form/generated/formfield/validation/camunda-formfield-validation.component.d.ts +10 -10
  128. package/lib/camunda/form/generated/formfield/validation/date.validators.d.ts +3 -3
  129. package/lib/card/card.component.d.ts +16 -16
  130. package/lib/card/card.module.d.ts +2 -2
  131. package/lib/components.module.d.ts +2 -2
  132. package/lib/data-list/data-list.component.d.ts +7 -7
  133. package/lib/data-list/data-list.module.d.ts +2 -2
  134. package/lib/dropzone/dropzone.component.d.ts +38 -38
  135. package/lib/dropzone/dropzone.module.d.ts +2 -2
  136. package/lib/field-auto-focus/field-auto-focus.directive.d.ts +6 -6
  137. package/lib/field-auto-focus/field-auto-focus.module.d.ts +2 -2
  138. package/lib/file-size/file-size.module.d.ts +2 -2
  139. package/lib/file-size/file-size.pipe.d.ts +5 -5
  140. package/lib/filter-sidebar/filter-sidebar.component.d.ts +8 -8
  141. package/lib/filter-sidebar/filter-sidebar.module.d.ts +2 -2
  142. package/lib/form-io/form-io-builder.component.d.ts +8 -8
  143. package/lib/form-io/form-io-uploader/form-io-uploader-edit-form.d.ts +61 -61
  144. package/lib/form-io/form-io-uploader/form-io-uploader.component.d.ts +29 -29
  145. package/lib/form-io/form-io-uploader/form-io-uploader.formio.d.ts +3 -3
  146. package/lib/form-io/form-io.component.d.ts +44 -44
  147. package/lib/form-io/form-io.module.d.ts +2 -2
  148. package/lib/form-io/formio-config.d.ts +6 -6
  149. package/lib/form-io/services/form-io-dom.service.d.ts +6 -6
  150. package/lib/form-io/services/form-io-state.service.d.ts +10 -10
  151. package/lib/left-sidebar/left-sidebar.component.d.ts +34 -34
  152. package/lib/left-sidebar/left-sidebar.module.d.ts +2 -2
  153. package/lib/list/ListFilterPipe.directive.d.ts +4 -4
  154. package/lib/list/list.component.d.ts +43 -43
  155. package/lib/list/list.module.d.ts +2 -2
  156. package/lib/menu/menu-item-text.component.d.ts +4 -4
  157. package/lib/menu/menu-routing.module.d.ts +2 -2
  158. package/lib/menu/menu.component.d.ts +18 -18
  159. package/lib/menu/menu.init.d.ts +3 -3
  160. package/lib/menu/menu.module.d.ts +2 -2
  161. package/lib/menu/menu.service.d.ts +23 -23
  162. package/lib/menu/submenu-item-text.component.d.ts +4 -4
  163. package/lib/modal/modal.component.d.ts +12 -12
  164. package/lib/modal/modal.module.d.ts +2 -2
  165. package/lib/page-header/page-header.component.d.ts +5 -5
  166. package/lib/page-header/page-header.module.d.ts +2 -2
  167. package/lib/page-title/page-title.component.d.ts +19 -19
  168. package/lib/page-title/page-title.module.d.ts +2 -2
  169. package/lib/progress-bar/progress-bar.component.d.ts +2 -2
  170. package/lib/progress-bar/progress-bar.module.d.ts +2 -2
  171. package/lib/right-sidebar/right-sidebar.component.d.ts +34 -34
  172. package/lib/right-sidebar/right-sidebar.module.d.ts +2 -2
  173. package/lib/searchable-dropdown/searchable-dropdown.component.d.ts +39 -39
  174. package/lib/searchable-dropdown/searchable-dropdown.module.d.ts +2 -2
  175. package/lib/searchable-dropdown-select/searchable-dropdown-select.component.d.ts +19 -19
  176. package/lib/searchable-dropdown-select/searchable-dropdown-select.module.d.ts +2 -2
  177. package/lib/spinner/spinner.component.d.ts +10 -9
  178. package/lib/spinner/spinner.module.d.ts +2 -2
  179. package/lib/timeline/timeline.component.d.ts +4 -4
  180. package/lib/timeline/timeline.module.d.ts +2 -2
  181. package/lib/topbar/topbar.component.d.ts +3 -3
  182. package/lib/topbar/topbar.module.d.ts +2 -2
  183. package/lib/uploader/uploader-drag-drop.directive.d.ts +7 -7
  184. package/lib/uploader/uploader.component.d.ts +15 -15
  185. package/lib/uploader/uploader.module.d.ts +2 -2
  186. package/lib/version/version.service.d.ts +8 -8
  187. package/lib/view-content/type-converters/booleanTypeConverter.d.ts +5 -5
  188. package/lib/view-content/type-converters/dateTypeConverter.d.ts +5 -5
  189. package/lib/view-content/type-converters/enumTypeConverter.d.ts +5 -5
  190. package/lib/view-content/type-converters/relatedFilesTypeConverter.d.ts +5 -5
  191. package/lib/view-content/type-converters/stringReplaceUnderscoreTypeConverter.d.ts +6 -6
  192. package/lib/view-content/type-converters/stringTypeConverter.d.ts +5 -5
  193. package/lib/view-content/type-converters/type-converters.model.d.ts +5 -5
  194. package/lib/view-content/view-content.service.d.ts +8 -8
  195. package/lib/webcam/webcam.component.d.ts +20 -20
  196. package/lib/webcam/webcam.module.d.ts +2 -2
  197. package/lib/widget/widget.component.d.ts +28 -28
  198. package/lib/widget/widget.module.d.ts +2 -2
  199. package/package.json +1 -1
  200. package/public_api.d.ts +65 -65
  201. package/valtimo-components.d.ts +26 -26
  202. package/valtimo-components.metadata.json +1 -1
@@ -1,185 +1,185 @@
1
- /*
2
- * Copyright 2015-2020 Ritense BV, the Netherlands.
3
- *
4
- * Licensed under EUPL, Version 1.2 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" basis,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { Component, EventEmitter, HostListener, Input, Output, QueryList, ViewChildren } from '@angular/core';
17
- import { FormControl } from '@angular/forms';
18
- import { BehaviorSubject, combineLatest, fromEvent } from 'rxjs';
19
- import { debounceTime, take } from 'rxjs/operators';
20
- export class SearchableDropdownComponent {
21
- constructor() {
22
- this.width = 250;
23
- this.itemSelected = new EventEmitter();
24
- this.searchId = 'search';
25
- this.searchTerm = new FormControl('');
26
- this.focusedItemId$ = new BehaviorSubject(this.searchId);
27
- this.open$ = new BehaviorSubject(false);
28
- this.filteredItems$ = new BehaviorSubject(undefined);
29
- this.wasInside = false;
30
- this.mouseOnList$ = new BehaviorSubject(false);
31
- }
32
- clickInside() {
33
- this.wasInside = true;
34
- }
35
- clickout() {
36
- if (!this.wasInside) {
37
- this.closeDropdown();
38
- }
39
- this.wasInside = false;
40
- }
41
- ngOnInit() {
42
- this.openKeysSubscription();
43
- this.openSearchSubscription();
44
- }
45
- ngOnChanges(changes) {
46
- const itemChanges = changes.items;
47
- const currenItems = itemChanges.currentValue;
48
- if (itemChanges && !itemChanges.previousValue && currenItems) {
49
- this.filteredItems$.next(currenItems);
50
- }
51
- }
52
- ngOnDestroy() {
53
- this.keySubscription.unsubscribe();
54
- this.searchSubscription.unsubscribe();
55
- }
56
- openDropdown() {
57
- this.open$.next(true);
58
- }
59
- hoverOverButton(id) {
60
- this.focusedItemId$.next(id);
61
- }
62
- mouseEnterList() {
63
- this.mouseOnList$.next(true);
64
- }
65
- mouseLeaveList() {
66
- this.mouseOnList$.next(false);
67
- }
68
- resetFocus() {
69
- this.focusedItemId$.next(this.searchId);
70
- }
71
- submit(id) {
72
- this.itemSelected.emit(id);
73
- }
74
- closeDropdown() {
75
- this.searchTerm.setValue('');
76
- this.resetFocus();
77
- this.open$.next(false);
78
- }
79
- openKeysSubscription() {
80
- this.keySubscription = fromEvent(document, 'keyup')
81
- .pipe(debounceTime(50))
82
- .subscribe((event) => {
83
- combineLatest([this.mouseOnList$, this.filteredItems$, this.focusedItemId$])
84
- .pipe(take(1))
85
- .subscribe(([mouseOnList, items, focusedId]) => {
86
- const length = items.length;
87
- const focusedIndex = items.findIndex((item) => item.id === focusedId);
88
- const code = event.code;
89
- const shiftKey = event.shiftKey;
90
- const down = 'ArrowDown';
91
- const tab = 'Tab';
92
- const up = 'ArrowUp';
93
- const enter = 'Enter';
94
- const escape = 'Escape';
95
- // close dropdown on pressing escape
96
- if (code === escape) {
97
- this.closeDropdown();
98
- }
99
- // submit item when focus is on an item in the list and enter is pressed
100
- if (code === enter && focusedId !== this.searchId) {
101
- this.submit(focusedId);
102
- }
103
- // only handle tab or arrow keypresses when items are shown and the mouse is not on the list
104
- if (length > 0 && !mouseOnList) {
105
- // handle moving down in the list with arrow down or tab
106
- if (code === down || (code === tab && !shiftKey)) {
107
- // move focus to first item in the list when focus is on search box
108
- if (focusedId === this.searchId) {
109
- this.focusedItemId$.next(items[0].id);
110
- this.scrollButtonIntoView(focusedId);
111
- // move focus to next item in the list if focus is not on last item
112
- }
113
- else if (focusedIndex + 1 < length) {
114
- this.focusedItemId$.next(items[focusedIndex + 1].id);
115
- this.scrollButtonIntoView(focusedId);
116
- }
117
- // handle moving up in the list with up arrow up or shift+tab
118
- }
119
- else if ((code === up || (code === tab && shiftKey)) && focusedId !== this.searchId) {
120
- // move to previous item if focus is not on the first item in the list
121
- if (focusedIndex > 0) {
122
- this.focusedItemId$.next(items[focusedIndex - 1].id);
123
- this.scrollButtonIntoView(focusedId);
124
- // move focus to search box if focus is on first item in the list
125
- }
126
- else {
127
- this.resetFocus();
128
- }
129
- }
130
- }
131
- });
132
- });
133
- }
134
- openSearchSubscription() {
135
- this.searchSubscription = this.searchTerm.valueChanges.subscribe((searchTerm) => {
136
- this.focusedItemId$.pipe(take(1)).subscribe((focusedItemId) => {
137
- if (!searchTerm) {
138
- this.filteredItems$.next(this.items);
139
- }
140
- else {
141
- const filteredItems = this.items.filter((item) => item.text.toUpperCase().includes(searchTerm.toUpperCase()));
142
- this.filteredItems$.next(filteredItems);
143
- // move focus to search box if filtered list length is 0 or previously focused item is not in filtered list anymore
144
- if (filteredItems.length === 0 || !filteredItems.some((item) => item.id === focusedItemId)) {
145
- this.resetFocus();
146
- }
147
- }
148
- // move scrolling button into view to end of queue, so that DOM can be updated first
149
- setTimeout(() => {
150
- this.scrollButtonIntoView(focusedItemId);
151
- });
152
- });
153
- });
154
- }
155
- scrollButtonIntoView(id) {
156
- this.filteredItems$.pipe(take(1)).subscribe((items) => {
157
- const focusItemIndex = items.findIndex((item) => item.id === id);
158
- const focusedButton = this.buttons.toArray()[focusItemIndex];
159
- if (focusedButton) {
160
- focusedButton.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
161
- }
162
- });
163
- }
164
- }
165
- SearchableDropdownComponent.decorators = [
166
- { type: Component, args: [{
167
- selector: 'valtimo-searchable-dropdown',
168
- template: "<ng-container *ngIf=\"buttonText && items\">\n <ng-container [ngTemplateOutlet]=\"(open$ | async) ? opened : closed\"> </ng-container>\n</ng-container>\n\n<ng-template #closed>\n <ng-container *ngIf=\"style === 'button' || !style\">\n <button class=\"btn btn-primary btn-sm dropdown-size\" (click)=\"openDropdown()\" [style.width.px]=\"width\">\n {{ buttonText }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"style === 'underlinedText'\">\n <h5 class=\"underline-button\" (click)=\"openDropdown()\" [style.width.px]=\"width\">\n <b>\n {{ buttonText }}\n </b>\n </h5>\n </ng-container>\n</ng-template>\n\n<ng-template #opened>\n <div class=\"dropdown-container\" [style.width.px]=\"width\">\n <div class=\"dropdown-size search\" [style.width.px]=\"width\">\n <input #search [ngClass]=\"{ disabled: disabled }\" [placeholder]=\"searchText\" [formControl]=\"searchTerm\" />\n {{ search.focus() }}\n </div>\n <div class=\"dropdown-list\" (mouseenter)=\"mouseEnterList()\" (mouseleave)=\"mouseLeaveList()\">\n <ng-container *ngIf=\"filteredItems$ | async as filteredItems\">\n <ng-container *ngIf=\"filteredItems.length > 0 && focusedItemId$ | async as focusedItemId; else noResults\">\n <button\n #button\n *ngFor=\"let item of filteredItems\"\n [ngClass]=\"{ focus: focusedItemId === item.id, disabled: disabled }\"\n class=\"dropdown-button dropdown-size\"\n (click)=\"submit(item.id)\"\n (mouseenter)=\"hoverOverButton(item.id)\"\n (mouseleave)=\"resetFocus()\"\n [style.width.px]=\"width\"\n >\n <span class=\"dropdown-button-text\">\n {{ item.text }}\n </span>\n </button>\n </ng-container>\n </ng-container>\n </div>\n </div>\n <ng-container [ngTemplateOutlet]=\"space\"> </ng-container>\n</ng-template>\n\n<ng-template #noResults>\n <div class=\"dropdown-button dropdown-size disabled\" [style.width.px]=\"width\">\n <span class=\"dropdown-button-text\">{{ noResultsText }}</span>\n </div>\n</ng-template>\n\n<ng-template #space>\n <div *ngIf=\"style === 'button' || !style\" class=\"dropdown-size\" [style.width.px]=\"width\"></div>\n <h5 *ngIf=\"style === 'underlinedText'\" class=\"underline-button\"><b>-</b></h5>\n</ng-template>\n",
169
- styles: [".dropdown-size{height:34px;width:250px}.underline-button{cursor:pointer;text-decoration:underline;width:250px}.dropdown-container{background-color:#fff;border:1px solid #e3e3e3;border-radius:3px;box-shadow:0 0 6px 0 rgba(0,0,0,.12);display:flex;flex-direction:column;max-height:300px;overflow:hidden;padding:7px 0;position:fixed;width:250px;z-index:999}.dropdown-list{list-style:none;margin:0;overflow:auto;overflow-x:hidden;padding:0;z-index:9999}.search{align-items:center;border-bottom:1px solid #dee2e6;display:flex;flex-shrink:0;height:44px;padding:8px 24px}.search input{padding:0;width:100%}.dropdown-button,.search input,.search input:focus{border:none;outline:none}.dropdown-button{align-items:center;background-color:#fff;color:#504e4e;cursor:pointer;display:flex;font-size:1rem;font-weight:400;padding:8px 24px}.dropdown-button.focus{background-color:#f5f5f5}.dropdown-button-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.disabled{color:#959595;cursor:default;pointer-events:none}"]
170
- },] }
171
- ];
172
- SearchableDropdownComponent.propDecorators = {
173
- style: [{ type: Input }],
174
- items: [{ type: Input }],
175
- buttonText: [{ type: Input }],
176
- searchText: [{ type: Input }],
177
- noResultsText: [{ type: Input }],
178
- disabled: [{ type: Input }],
179
- width: [{ type: Input }],
180
- itemSelected: [{ type: Output }],
181
- buttons: [{ type: ViewChildren, args: ['button',] }],
182
- clickInside: [{ type: HostListener, args: ['click',] }],
183
- clickout: [{ type: HostListener, args: ['document:click',] }]
184
- };
1
+ /*
2
+ * Copyright 2015-2020 Ritense BV, the Netherlands.
3
+ *
4
+ * Licensed under EUPL, Version 1.2 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Component, EventEmitter, HostListener, Input, Output, QueryList, ViewChildren } from '@angular/core';
17
+ import { FormControl } from '@angular/forms';
18
+ import { BehaviorSubject, combineLatest, fromEvent } from 'rxjs';
19
+ import { debounceTime, take } from 'rxjs/operators';
20
+ export class SearchableDropdownComponent {
21
+ constructor() {
22
+ this.width = 250;
23
+ this.itemSelected = new EventEmitter();
24
+ this.searchId = 'search';
25
+ this.searchTerm = new FormControl('');
26
+ this.focusedItemId$ = new BehaviorSubject(this.searchId);
27
+ this.open$ = new BehaviorSubject(false);
28
+ this.filteredItems$ = new BehaviorSubject(undefined);
29
+ this.wasInside = false;
30
+ this.mouseOnList$ = new BehaviorSubject(false);
31
+ }
32
+ clickInside() {
33
+ this.wasInside = true;
34
+ }
35
+ clickout() {
36
+ if (!this.wasInside) {
37
+ this.closeDropdown();
38
+ }
39
+ this.wasInside = false;
40
+ }
41
+ ngOnInit() {
42
+ this.openKeysSubscription();
43
+ this.openSearchSubscription();
44
+ }
45
+ ngOnChanges(changes) {
46
+ const itemChanges = changes.items;
47
+ const currenItems = itemChanges.currentValue;
48
+ if (itemChanges && !itemChanges.previousValue && currenItems) {
49
+ this.filteredItems$.next(currenItems);
50
+ }
51
+ }
52
+ ngOnDestroy() {
53
+ this.keySubscription.unsubscribe();
54
+ this.searchSubscription.unsubscribe();
55
+ }
56
+ openDropdown() {
57
+ this.open$.next(true);
58
+ }
59
+ hoverOverButton(id) {
60
+ this.focusedItemId$.next(id);
61
+ }
62
+ mouseEnterList() {
63
+ this.mouseOnList$.next(true);
64
+ }
65
+ mouseLeaveList() {
66
+ this.mouseOnList$.next(false);
67
+ }
68
+ resetFocus() {
69
+ this.focusedItemId$.next(this.searchId);
70
+ }
71
+ submit(id) {
72
+ this.itemSelected.emit(id);
73
+ }
74
+ closeDropdown() {
75
+ this.searchTerm.setValue('');
76
+ this.resetFocus();
77
+ this.open$.next(false);
78
+ }
79
+ openKeysSubscription() {
80
+ this.keySubscription = fromEvent(document, 'keyup')
81
+ .pipe(debounceTime(50))
82
+ .subscribe((event) => {
83
+ combineLatest([this.mouseOnList$, this.filteredItems$, this.focusedItemId$])
84
+ .pipe(take(1))
85
+ .subscribe(([mouseOnList, items, focusedId]) => {
86
+ const length = items.length;
87
+ const focusedIndex = items.findIndex((item) => item.id === focusedId);
88
+ const code = event.code;
89
+ const shiftKey = event.shiftKey;
90
+ const down = 'ArrowDown';
91
+ const tab = 'Tab';
92
+ const up = 'ArrowUp';
93
+ const enter = 'Enter';
94
+ const escape = 'Escape';
95
+ // close dropdown on pressing escape
96
+ if (code === escape) {
97
+ this.closeDropdown();
98
+ }
99
+ // submit item when focus is on an item in the list and enter is pressed
100
+ if (code === enter && focusedId !== this.searchId) {
101
+ this.submit(focusedId);
102
+ }
103
+ // only handle tab or arrow keypresses when items are shown and the mouse is not on the list
104
+ if (length > 0 && !mouseOnList) {
105
+ // handle moving down in the list with arrow down or tab
106
+ if (code === down || (code === tab && !shiftKey)) {
107
+ // move focus to first item in the list when focus is on search box
108
+ if (focusedId === this.searchId) {
109
+ this.focusedItemId$.next(items[0].id);
110
+ this.scrollButtonIntoView(focusedId);
111
+ // move focus to next item in the list if focus is not on last item
112
+ }
113
+ else if (focusedIndex + 1 < length) {
114
+ this.focusedItemId$.next(items[focusedIndex + 1].id);
115
+ this.scrollButtonIntoView(focusedId);
116
+ }
117
+ // handle moving up in the list with up arrow up or shift+tab
118
+ }
119
+ else if ((code === up || (code === tab && shiftKey)) && focusedId !== this.searchId) {
120
+ // move to previous item if focus is not on the first item in the list
121
+ if (focusedIndex > 0) {
122
+ this.focusedItemId$.next(items[focusedIndex - 1].id);
123
+ this.scrollButtonIntoView(focusedId);
124
+ // move focus to search box if focus is on first item in the list
125
+ }
126
+ else {
127
+ this.resetFocus();
128
+ }
129
+ }
130
+ }
131
+ });
132
+ });
133
+ }
134
+ openSearchSubscription() {
135
+ this.searchSubscription = this.searchTerm.valueChanges.subscribe((searchTerm) => {
136
+ this.focusedItemId$.pipe(take(1)).subscribe((focusedItemId) => {
137
+ if (!searchTerm) {
138
+ this.filteredItems$.next(this.items);
139
+ }
140
+ else {
141
+ const filteredItems = this.items.filter((item) => item.text.toUpperCase().includes(searchTerm.toUpperCase()));
142
+ this.filteredItems$.next(filteredItems);
143
+ // move focus to search box if filtered list length is 0 or previously focused item is not in filtered list anymore
144
+ if (filteredItems.length === 0 || !filteredItems.some((item) => item.id === focusedItemId)) {
145
+ this.resetFocus();
146
+ }
147
+ }
148
+ // move scrolling button into view to end of queue, so that DOM can be updated first
149
+ setTimeout(() => {
150
+ this.scrollButtonIntoView(focusedItemId);
151
+ });
152
+ });
153
+ });
154
+ }
155
+ scrollButtonIntoView(id) {
156
+ this.filteredItems$.pipe(take(1)).subscribe((items) => {
157
+ const focusItemIndex = items.findIndex((item) => item.id === id);
158
+ const focusedButton = this.buttons.toArray()[focusItemIndex];
159
+ if (focusedButton) {
160
+ focusedButton.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
161
+ }
162
+ });
163
+ }
164
+ }
165
+ SearchableDropdownComponent.decorators = [
166
+ { type: Component, args: [{
167
+ selector: 'valtimo-searchable-dropdown',
168
+ template: "<ng-container *ngIf=\"buttonText && items\">\n <ng-container [ngTemplateOutlet]=\"(open$ | async) ? opened : closed\"> </ng-container>\n</ng-container>\n\n<ng-template #closed>\n <ng-container *ngIf=\"style === 'button' || !style\">\n <button class=\"btn btn-primary btn-sm dropdown-size\" (click)=\"openDropdown()\" [style.width.px]=\"width\">\n {{ buttonText }}\n </button>\n </ng-container>\n <ng-container *ngIf=\"style === 'underlinedText'\">\n <h5 class=\"underline-button\" (click)=\"openDropdown()\" [style.width.px]=\"width\">\n <b>\n {{ buttonText }}\n </b>\n </h5>\n </ng-container>\n</ng-template>\n\n<ng-template #opened>\n <div class=\"dropdown-container\" [style.width.px]=\"width\">\n <div class=\"dropdown-size search\" [style.width.px]=\"width\">\n <input #search [ngClass]=\"{ disabled: disabled }\" [placeholder]=\"searchText\" [formControl]=\"searchTerm\" />\n {{ search.focus() }}\n </div>\n <div class=\"dropdown-list\" (mouseenter)=\"mouseEnterList()\" (mouseleave)=\"mouseLeaveList()\">\n <ng-container *ngIf=\"filteredItems$ | async as filteredItems\">\n <ng-container *ngIf=\"filteredItems.length > 0 && focusedItemId$ | async as focusedItemId; else noResults\">\n <button\n #button\n *ngFor=\"let item of filteredItems\"\n [ngClass]=\"{ focus: focusedItemId === item.id, disabled: disabled }\"\n class=\"dropdown-button dropdown-size\"\n (click)=\"submit(item.id)\"\n (mouseenter)=\"hoverOverButton(item.id)\"\n (mouseleave)=\"resetFocus()\"\n [style.width.px]=\"width\"\n >\n <span class=\"dropdown-button-text\">\n {{ item.text }}\n </span>\n </button>\n </ng-container>\n </ng-container>\n </div>\n </div>\n <ng-container [ngTemplateOutlet]=\"space\"> </ng-container>\n</ng-template>\n\n<ng-template #noResults>\n <div class=\"dropdown-button dropdown-size disabled\" [style.width.px]=\"width\">\n <span class=\"dropdown-button-text\">{{ noResultsText }}</span>\n </div>\n</ng-template>\n\n<ng-template #space>\n <div *ngIf=\"style === 'button' || !style\" class=\"dropdown-size\" [style.width.px]=\"width\"></div>\n <h5 *ngIf=\"style === 'underlinedText'\" class=\"underline-button\"><b>-</b></h5>\n</ng-template>\n",
169
+ styles: [".dropdown-size{height:34px;width:250px}.underline-button{cursor:pointer;text-decoration:underline;width:250px}.dropdown-container{background-color:#fff;border:1px solid #e3e3e3;border-radius:3px;box-shadow:0 0 6px 0 rgba(0,0,0,.12);display:flex;flex-direction:column;max-height:300px;overflow:hidden;padding:7px 0;position:fixed;width:250px;z-index:999}.dropdown-list{list-style:none;margin:0;overflow:auto;overflow-x:hidden;padding:0;z-index:9999}.search{align-items:center;border-bottom:1px solid #dee2e6;display:flex;flex-shrink:0;height:44px;padding:8px 24px}.search input{padding:0;width:100%}.dropdown-button,.search input,.search input:focus{border:none;outline:none}.dropdown-button{align-items:center;background-color:#fff;color:#504e4e;cursor:pointer;display:flex;font-size:1rem;font-weight:400;padding:8px 24px}.dropdown-button.focus{background-color:#f5f5f5}.dropdown-button-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.disabled{color:#959595;cursor:default;pointer-events:none}"]
170
+ },] }
171
+ ];
172
+ SearchableDropdownComponent.propDecorators = {
173
+ style: [{ type: Input }],
174
+ items: [{ type: Input }],
175
+ buttonText: [{ type: Input }],
176
+ searchText: [{ type: Input }],
177
+ noResultsText: [{ type: Input }],
178
+ disabled: [{ type: Input }],
179
+ width: [{ type: Input }],
180
+ itemSelected: [{ type: Output }],
181
+ buttons: [{ type: ViewChildren, args: ['button',] }],
182
+ clickInside: [{ type: HostListener, args: ['click',] }],
183
+ clickout: [{ type: HostListener, args: ['document:click',] }]
184
+ };
185
185
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoYWJsZS1kcm9wZG93bi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92YWx0aW1vL2NvbXBvbmVudHMvc3JjL2xpYi9zZWFyY2hhYmxlLWRyb3Bkb3duL3NlYXJjaGFibGUtZHJvcGRvd24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUgsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBQ04sU0FBUyxFQUVULFlBQVksRUFDYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUMvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBT3BELE1BQU0sT0FBTywyQkFBMkI7SUFMeEM7UUFZVyxVQUFLLEdBQUcsR0FBRyxDQUFDO1FBRVgsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBSTNCLGFBQVEsR0FBRyxRQUFRLENBQUM7UUFFNUIsZUFBVSxHQUFHLElBQUksV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWpDLG1CQUFjLEdBQUcsSUFBSSxlQUFlLENBQVMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTVELFVBQUssR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUU1QyxtQkFBYyxHQUFHLElBQUksZUFBZSxDQUFzQixTQUFTLENBQUMsQ0FBQztRQUV0RSxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBTVQsaUJBQVksR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztJQXlKdEUsQ0FBQztJQXRKQyxX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QkFDTCxLQUFLO3VCQUNMLEtBQUs7b0JBQ0wsS0FBSzsyQkFFTCxNQUFNO3NCQUVOLFlBQVksU0FBQyxRQUFROzBCQW9CckIsWUFBWSxTQUFDLE9BQU87dUJBS3BCLFlBQVksU0FBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMTUtMjAyMCBSaXRlbnNlIEJWLCB0aGUgTmV0aGVybGFuZHMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgRVVQTCwgVmVyc2lvbiAxLjIgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwczovL2pvaW51cC5lYy5ldXJvcGEuZXUvY29sbGVjdGlvbi9ldXBsL2V1cGwtdGV4dC1ldXBsLTEyXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIGJhc2lzLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZHJlblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRHJvcGRvd25CdXR0b25TdHlsZSwgRHJvcGRvd25JdGVtIH0gZnJvbSAnQHZhbHRpbW8vY29udHJhY3QnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBmcm9tRXZlbnQsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWx0aW1vLXNlYXJjaGFibGUtZHJvcGRvd24nLFxuICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoYWJsZS1kcm9wZG93bi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NlYXJjaGFibGUtZHJvcGRvd24uY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBTZWFyY2hhYmxlRHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgc3R5bGU6IERyb3Bkb3duQnV0dG9uU3R5bGU7XG4gIEBJbnB1dCgpIGl0ZW1zOiBBcnJheTxEcm9wZG93bkl0ZW0+O1xuICBASW5wdXQoKSBidXR0b25UZXh0OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHNlYXJjaFRleHQ6IHN0cmluZztcbiAgQElucHV0KCkgbm9SZXN1bHRzVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbjtcbiAgQElucHV0KCkgd2lkdGggPSAyNTA7XG5cbiAgQE91dHB1dCgpIGl0ZW1TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAVmlld0NoaWxkcmVuKCdidXR0b24nKSBidXR0b25zOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzZWFyY2hJZCA9ICdzZWFyY2gnO1xuXG4gIHJlYWRvbmx5IHNlYXJjaFRlcm0gPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuXG4gIHJlYWRvbmx5IGZvY3VzZWRJdGVtSWQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KHRoaXMuc2VhcmNoSWQpO1xuXG4gIHJlYWRvbmx5IG9wZW4kID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgcmVhZG9ubHkgZmlsdGVyZWRJdGVtcyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEFycmF5PERyb3Bkb3duSXRlbT4+KHVuZGVmaW5lZCk7XG5cbiAgcHJpdmF0ZSB3YXNJbnNpZGUgPSBmYWxzZTtcblxuICBwcml2YXRlIGtleVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIHByaXZhdGUgc2VhcmNoU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgcHJpdmF0ZSByZWFkb25seSBtb3VzZU9uTGlzdCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICBASG9zdExpc3RlbmVyKCdjbGljaycpXG4gIGNsaWNrSW5zaWRlKCkge1xuICAgIHRoaXMud2FzSW5zaWRlID0gdHJ1ZTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJylcbiAgY2xpY2tvdXQoKSB7XG4gICAgaWYgKCF0aGlzLndhc0luc2lkZSkge1xuICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgfVxuICAgIHRoaXMud2FzSW5zaWRlID0gZmFsc2U7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm9wZW5LZXlzU3Vic2NyaXB0aW9uKCk7XG4gICAgdGhpcy5vcGVuU2VhcmNoU3Vic2NyaXB0aW9uKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgaXRlbUNoYW5nZXMgPSBjaGFuZ2VzLml0ZW1zO1xuICAgIGNvbnN0IGN1cnJlbkl0ZW1zID0gaXRlbUNoYW5nZXMuY3VycmVudFZhbHVlO1xuICAgIGlmIChpdGVtQ2hhbmdlcyAmJiAhaXRlbUNoYW5nZXMucHJldmlvdXNWYWx1ZSAmJiBjdXJyZW5JdGVtcykge1xuICAgICAgdGhpcy5maWx0ZXJlZEl0ZW1zJC5uZXh0KGN1cnJlbkl0ZW1zKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmtleVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuc2VhcmNoU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBvcGVuRHJvcGRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuJC5uZXh0KHRydWUpO1xuICB9XG5cbiAgaG92ZXJPdmVyQnV0dG9uKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzZWRJdGVtSWQkLm5leHQoaWQpO1xuICB9XG5cbiAgbW91c2VFbnRlckxpc3QoKTogdm9pZCB7XG4gICAgdGhpcy5tb3VzZU9uTGlzdCQubmV4dCh0cnVlKTtcbiAgfVxuXG4gIG1vdXNlTGVhdmVMaXN0KCk6IHZvaWQge1xuICAgIHRoaXMubW91c2VPbkxpc3QkLm5leHQoZmFsc2UpO1xuICB9XG5cbiAgcmVzZXRGb2N1cygpOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzZWRJdGVtSWQkLm5leHQodGhpcy5zZWFyY2hJZCk7XG4gIH1cblxuICBzdWJtaXQoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuaXRlbVNlbGVjdGVkLmVtaXQoaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZURyb3Bkb3duKCk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXRWYWx1ZSgnJyk7XG4gICAgdGhpcy5yZXNldEZvY3VzKCk7XG4gICAgdGhpcy5vcGVuJC5uZXh0KGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgb3BlbktleXNTdWJzY3JpcHRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5rZXlTdWJzY3JpcHRpb24gPSBmcm9tRXZlbnQoZG9jdW1lbnQsICdrZXl1cCcpXG4gICAgICAucGlwZShkZWJvdW5jZVRpbWUoNTApKVxuICAgICAgLnN1YnNjcmliZSgoZXZlbnQ6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgY29tYmluZUxhdGVzdChbdGhpcy5tb3VzZU9uTGlzdCQsIHRoaXMuZmlsdGVyZWRJdGVtcyQsIHRoaXMuZm9jdXNlZEl0ZW1JZCRdKVxuICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgLnN1YnNjcmliZSgoW21vdXNlT25MaXN0LCBpdGVtcywgZm9jdXNlZElkXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgZm9jdXNlZEluZGV4ID0gaXRlbXMuZmluZEluZGV4KChpdGVtKSA9PiBpdGVtLmlkID09PSBmb2N1c2VkSWQpO1xuICAgICAgICAgICAgY29uc3QgY29kZSA9IGV2ZW50LmNvZGU7XG4gICAgICAgICAgICBjb25zdCBzaGlmdEtleSA9IGV2ZW50LnNoaWZ0S2V5O1xuICAgICAgICAgICAgY29uc3QgZG93biA9ICdBcnJvd0Rvd24nO1xuICAgICAgICAgICAgY29uc3QgdGFiID0gJ1RhYic7XG4gICAgICAgICAgICBjb25zdCB1cCA9ICdBcnJvd1VwJztcbiAgICAgICAgICAgIGNvbnN0IGVudGVyID0gJ0VudGVyJztcbiAgICAgICAgICAgIGNvbnN0IGVzY2FwZSA9ICdFc2NhcGUnO1xuXG4gICAgICAgICAgICAvLyBjbG9zZSBkcm9wZG93biBvbiBwcmVzc2luZyBlc2NhcGVcbiAgICAgICAgICAgIGlmIChjb2RlID09PSBlc2NhcGUpIHtcbiAgICAgICAgICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHN1Ym1pdCBpdGVtIHdoZW4gZm9jdXMgaXMgb24gYW4gaXRlbSBpbiB0aGUgbGlzdCBhbmQgZW50ZXIgaXMgcHJlc3NlZFxuICAgICAgICAgICAgaWYgKGNvZGUgPT09IGVudGVyICYmIGZvY3VzZWRJZCAhPT0gdGhpcy5zZWFyY2hJZCkge1xuICAgICAgICAgICAgICB0aGlzLnN1Ym1pdChmb2N1c2VkSWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBvbmx5IGhhbmRsZSB0YWIgb3IgYXJyb3cga2V5cHJlc3NlcyB3aGVuIGl0ZW1zIGFyZSBzaG93biBhbmQgdGhlIG1vdXNlIGlzIG5vdCBvbiB0aGUgbGlzdFxuICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDAgJiYgIW1vdXNlT25MaXN0KSB7XG4gICAgICAgICAgICAgIC8vIGhhbmRsZSBtb3ZpbmcgZG93biBpbiB0aGUgbGlzdCB3aXRoIGFycm93IGRvd24gb3IgdGFiXG4gICAgICAgICAgICAgIGlmIChjb2RlID09PSBkb3duIHx8IChjb2RlID09PSB0YWIgJiYgIXNoaWZ0S2V5KSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgZm9jdXMgdG8gZmlyc3QgaXRlbSBpbiB0aGUgbGlzdCB3aGVuIGZvY3VzIGlzIG9uIHNlYXJjaCBib3hcbiAgICAgICAgICAgICAgICBpZiAoZm9jdXNlZElkID09PSB0aGlzLnNlYXJjaElkKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRJdGVtSWQkLm5leHQoaXRlbXNbMF0uaWQpO1xuICAgICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxCdXR0b25JbnRvVmlldyhmb2N1c2VkSWQpO1xuICAgICAgICAgICAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBuZXh0IGl0ZW0gaW4gdGhlIGxpc3QgaWYgZm9jdXMgaXMgbm90IG9uIGxhc3QgaXRlbVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9jdXNlZEluZGV4ICsgMSA8IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5mb2N1c2VkSXRlbUlkJC5uZXh0KGl0ZW1zW2ZvY3VzZWRJbmRleCArIDFdLmlkKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsQnV0dG9uSW50b1ZpZXcoZm9jdXNlZElkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gaGFuZGxlIG1vdmluZyB1cCBpbiB0aGUgbGlzdCB3aXRoIHVwIGFycm93IHVwIG9yIHNoaWZ0K3RhYlxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKChjb2RlID09PSB1cCB8fCAoY29kZSA9PT0gdGFiICYmIHNoaWZ0S2V5KSkgJiYgZm9jdXNlZElkICE9PSB0aGlzLnNlYXJjaElkKSB7XG4gICAgICAgICAgICAgICAgLy8gbW92ZSB0byBwcmV2aW91cyBpdGVtIGlmIGZvY3VzIGlzIG5vdCBvbiB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgbGlzdFxuICAgICAgICAgICAgICAgIGlmIChmb2N1c2VkSW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRJdGVtSWQkLm5leHQoaXRlbXNbZm9jdXNlZEluZGV4IC0gMV0uaWQpO1xuICAgICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxCdXR0b25JbnRvVmlldyhmb2N1c2VkSWQpO1xuICAgICAgICAgICAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBzZWFyY2ggYm94IGlmIGZvY3VzIGlzIG9uIGZpcnN0IGl0ZW0gaW4gdGhlIGxpc3RcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5yZXNldEZvY3VzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb3BlblNlYXJjaFN1YnNjcmlwdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaFN1YnNjcmlwdGlvbiA9IHRoaXMuc2VhcmNoVGVybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKChzZWFyY2hUZXJtKSA9PiB7XG4gICAgICB0aGlzLmZvY3VzZWRJdGVtSWQkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKChmb2N1c2VkSXRlbUlkKSA9PiB7XG4gICAgICAgIGlmICghc2VhcmNoVGVybSkge1xuICAgICAgICAgIHRoaXMuZmlsdGVyZWRJdGVtcyQubmV4dCh0aGlzLml0ZW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXJlZEl0ZW1zID0gdGhpcy5pdGVtcy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0udGV4dC50b1VwcGVyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRlcm0udG9VcHBlckNhc2UoKSkpO1xuXG4gICAgICAgICAgdGhpcy5maWx0ZXJlZEl0ZW1zJC5uZXh0KGZpbHRlcmVkSXRlbXMpO1xuXG4gICAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBzZWFyY2ggYm94IGlmIGZpbHRlcmVkIGxpc3QgbGVuZ3RoIGlzIDAgb3IgcHJldmlvdXNseSBmb2N1c2VkIGl0ZW0gaXMgbm90IGluIGZpbHRlcmVkIGxpc3QgYW55bW9yZVxuICAgICAgICAgIGlmIChmaWx0ZXJlZEl0ZW1zLmxlbmd0aCA9PT0gMCB8fCAhZmlsdGVyZWRJdGVtcy5zb21lKChpdGVtKSA9PiBpdGVtLmlkID09PSBmb2N1c2VkSXRlbUlkKSkge1xuICAgICAgICAgICAgdGhpcy5yZXNldEZvY3VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gbW92ZSBzY3JvbGxpbmcgYnV0dG9uIGludG8gdmlldyB0byBlbmQgb2YgcXVldWUsIHNvIHRoYXQgRE9NIGNhbiBiZSB1cGRhdGVkIGZpcnN0XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2Nyb2xsQnV0dG9uSW50b1ZpZXcoZm9jdXNlZEl0ZW1JZCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbEJ1dHRvbkludG9WaWV3KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlcmVkSXRlbXMkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKChpdGVtcykgPT4ge1xuICAgICAgY29uc3QgZm9jdXNJdGVtSW5kZXggPSBpdGVtcy5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0uaWQgPT09IGlkKTtcbiAgICAgIGNvbnN0IGZvY3VzZWRCdXR0b24gPSB0aGlzLmJ1dHRvbnMudG9BcnJheSgpW2ZvY3VzSXRlbUluZGV4XTtcblxuICAgICAgaWYgKGZvY3VzZWRCdXR0b24pIHtcbiAgICAgICAgZm9jdXNlZEJ1dHRvbi5uYXRpdmVFbGVtZW50LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ2NlbnRlcicgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,29 +1,29 @@
1
- /*
2
- * Copyright 2015-2020 Ritense BV, the Netherlands.
3
- *
4
- * Licensed under EUPL, Version 1.2 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" basis,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { CommonModule } from '@angular/common';
17
- import { NgModule } from '@angular/core';
18
- import { ReactiveFormsModule } from '@angular/forms';
19
- import { SearchableDropdownComponent } from './searchable-dropdown.component';
20
- export class SearchableDropdownModule {
21
- }
22
- SearchableDropdownModule.decorators = [
23
- { type: NgModule, args: [{
24
- declarations: [SearchableDropdownComponent],
25
- imports: [CommonModule, ReactiveFormsModule],
26
- exports: [SearchableDropdownComponent]
27
- },] }
28
- ];
1
+ /*
2
+ * Copyright 2015-2020 Ritense BV, the Netherlands.
3
+ *
4
+ * Licensed under EUPL, Version 1.2 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { CommonModule } from '@angular/common';
17
+ import { NgModule } from '@angular/core';
18
+ import { ReactiveFormsModule } from '@angular/forms';
19
+ import { SearchableDropdownComponent } from './searchable-dropdown.component';
20
+ export class SearchableDropdownModule {
21
+ }
22
+ SearchableDropdownModule.decorators = [
23
+ { type: NgModule, args: [{
24
+ declarations: [SearchableDropdownComponent],
25
+ imports: [CommonModule, ReactiveFormsModule],
26
+ exports: [SearchableDropdownComponent]
27
+ },] }
28
+ ];
29
29
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoYWJsZS1kcm9wZG93bi5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy92YWx0aW1vL2NvbXBvbmVudHMvc3JjL2xpYi9zZWFyY2hhYmxlLWRyb3Bkb3duL3NlYXJjaGFibGUtZHJvcGRvd24ubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFPOUUsTUFBTSxPQUFPLHdCQUF3Qjs7O1lBTHBDLFFBQVEsU0FBQztnQkFDUixZQUFZLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQztnQkFDM0MsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLG1CQUFtQixDQUFDO2dCQUM1QyxPQUFPLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQzthQUN2QyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAxNS0yMDIwIFJpdGVuc2UgQlYsIHRoZSBOZXRoZXJsYW5kcy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciBFVVBMLCBWZXJzaW9uIDEuMiAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHBzOi8vam9pbnVwLmVjLmV1cm9wYS5ldS9jb2xsZWN0aW9uL2V1cGwvZXVwbC10ZXh0LWV1cGwtMTJcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgYmFzaXMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNlYXJjaGFibGVEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4vc2VhcmNoYWJsZS1kcm9wZG93bi5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtTZWFyY2hhYmxlRHJvcGRvd25Db21wb25lbnRdLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgZXhwb3J0czogW1NlYXJjaGFibGVEcm9wZG93bkNvbXBvbmVudF1cbn0pXG5leHBvcnQgY2xhc3MgU2VhcmNoYWJsZURyb3Bkb3duTW9kdWxlIHt9XG4iXX0=
@@ -1,52 +1,52 @@
1
- /*
2
- * Copyright 2015-2020 Ritense BV, the Netherlands.
3
- *
4
- * Licensed under EUPL, Version 1.2 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" basis,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { Component, EventEmitter, Input, Output, } from '@angular/core';
17
- export class SearchableDropdownSelectComponent {
18
- constructor() {
19
- this.width = 250;
20
- this.itemSelected = new EventEmitter();
21
- this.clearSelection = new EventEmitter();
22
- }
23
- onSelect(id) {
24
- this.itemSelected.emit(id);
25
- }
26
- onClearSelection() {
27
- this.clearSelection.emit();
28
- }
29
- }
30
- SearchableDropdownSelectComponent.decorators = [
31
- { type: Component, args: [{
32
- selector: 'valtimo-searchable-dropdown-select',
33
- template: "<valtimo-searchable-dropdown\n *ngIf=\"!hasSelection; else selection\"\n [style]=\"style\"\n [items]=\"items\"\n [buttonText]=\"buttonText\"\n [searchText]=\"searchText\"\n [noResultsText]=\"noResultsText\"\n [disabled]=\"disabled\"\n [width]=\"width\"\n (itemSelected)=\"onSelect($event)\"\n>\n</valtimo-searchable-dropdown>\n\n<ng-template #selection>\n <div class=\"d-flex flex-row align-items-center\" [style.height.px]=\"style === 'button' ? 34 : null\">\n <h5 class=\"selected-text\">{{ selectedText }} <b>{{ selectedTextValue }}</b></h5>\n <button\n type=\"button\"\n class=\"close p-0 m-0 ml-2 d-flex text-danger\"\n aria-label=\"Close\"\n (click)=\"onClearSelection()\"\n [title]=\"clearSelectionButtonTitle\"\n >\n <i class=\"clear-icon fa fa-times text-danger\"></i>\n </button>\n </div>\n</ng-template>\n\n",
34
- styles: [".selected-text{margin:0}.clear-icon{font-size:13px}"]
35
- },] }
36
- ];
37
- SearchableDropdownSelectComponent.propDecorators = {
38
- style: [{ type: Input }],
39
- items: [{ type: Input }],
40
- buttonText: [{ type: Input }],
41
- searchText: [{ type: Input }],
42
- noResultsText: [{ type: Input }],
43
- disabled: [{ type: Input }],
44
- selectedText: [{ type: Input }],
45
- selectedTextValue: [{ type: Input }],
46
- clearSelectionButtonTitle: [{ type: Input }],
47
- hasSelection: [{ type: Input }],
48
- width: [{ type: Input }],
49
- itemSelected: [{ type: Output }],
50
- clearSelection: [{ type: Output }]
51
- };
1
+ /*
2
+ * Copyright 2015-2020 Ritense BV, the Netherlands.
3
+ *
4
+ * Licensed under EUPL, Version 1.2 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Component, EventEmitter, Input, Output, } from '@angular/core';
17
+ export class SearchableDropdownSelectComponent {
18
+ constructor() {
19
+ this.width = 250;
20
+ this.itemSelected = new EventEmitter();
21
+ this.clearSelection = new EventEmitter();
22
+ }
23
+ onSelect(id) {
24
+ this.itemSelected.emit(id);
25
+ }
26
+ onClearSelection() {
27
+ this.clearSelection.emit();
28
+ }
29
+ }
30
+ SearchableDropdownSelectComponent.decorators = [
31
+ { type: Component, args: [{
32
+ selector: 'valtimo-searchable-dropdown-select',
33
+ template: "<valtimo-searchable-dropdown\n *ngIf=\"!hasSelection; else selection\"\n [style]=\"style\"\n [items]=\"items\"\n [buttonText]=\"buttonText\"\n [searchText]=\"searchText\"\n [noResultsText]=\"noResultsText\"\n [disabled]=\"disabled\"\n [width]=\"width\"\n (itemSelected)=\"onSelect($event)\"\n>\n</valtimo-searchable-dropdown>\n\n<ng-template #selection>\n <div class=\"d-flex flex-row align-items-center\" [style.height.px]=\"style === 'button' ? 34 : null\">\n <h5 class=\"selected-text\">{{ selectedText }} <b>{{ selectedTextValue }}</b></h5>\n <button\n type=\"button\"\n class=\"close p-0 m-0 ml-2 d-flex text-danger\"\n aria-label=\"Close\"\n (click)=\"onClearSelection()\"\n [title]=\"clearSelectionButtonTitle\"\n >\n <i class=\"clear-icon fa fa-times text-danger\"></i>\n </button>\n </div>\n</ng-template>\n\n",
34
+ styles: [".selected-text{margin:0}.clear-icon{font-size:13px}"]
35
+ },] }
36
+ ];
37
+ SearchableDropdownSelectComponent.propDecorators = {
38
+ style: [{ type: Input }],
39
+ items: [{ type: Input }],
40
+ buttonText: [{ type: Input }],
41
+ searchText: [{ type: Input }],
42
+ noResultsText: [{ type: Input }],
43
+ disabled: [{ type: Input }],
44
+ selectedText: [{ type: Input }],
45
+ selectedTextValue: [{ type: Input }],
46
+ clearSelectionButtonTitle: [{ type: Input }],
47
+ hasSelection: [{ type: Input }],
48
+ width: [{ type: Input }],
49
+ itemSelected: [{ type: Output }],
50
+ clearSelection: [{ type: Output }]
51
+ };
52
52
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoYWJsZS1kcm9wZG93bi1zZWxlY3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdmFsdGltby9jb21wb25lbnRzL3NyYy9saWIvc2VhcmNoYWJsZS1kcm9wZG93bi1zZWxlY3Qvc2VhcmNoYWJsZS1kcm9wZG93bi1zZWxlY3QuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUgsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQVF2QixNQUFNLE9BQU8saUNBQWlDO0lBTDlDO1FBZ0JXLFVBQUssR0FBRyxHQUFHLENBQUM7UUFFWCxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDbEMsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0lBU2hELENBQUM7SUFQQyxRQUFRLENBQUMsRUFBVTtRQUNqQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQsZ0JBQWdCO1FBQ2QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM3QixDQUFDOzs7WUEzQkYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxvQ0FBb0M7Z0JBQzlDLG0zQkFBMEQ7O2FBRTNEOzs7b0JBRUUsS0FBSztvQkFDTCxLQUFLO3lCQUNMLEtBQUs7eUJBQ0wsS0FBSzs0QkFDTCxLQUFLO3VCQUNMLEtBQUs7MkJBQ0wsS0FBSztnQ0FDTCxLQUFLO3dDQUNMLEtBQUs7MkJBQ0wsS0FBSztvQkFDTCxLQUFLOzJCQUVMLE1BQU07NkJBQ04sTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAxNS0yMDIwIFJpdGVuc2UgQlYsIHRoZSBOZXRoZXJsYW5kcy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciBFVVBMLCBWZXJzaW9uIDEuMiAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHBzOi8vam9pbnVwLmVjLmV1cm9wYS5ldS9jb2xsZWN0aW9uL2V1cGwvZXVwbC10ZXh0LWV1cGwtMTJcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgYmFzaXMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7RHJvcGRvd25CdXR0b25TdHlsZSwgRHJvcGRvd25JdGVtfSBmcm9tICdAdmFsdGltby9jb250cmFjdCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbHRpbW8tc2VhcmNoYWJsZS1kcm9wZG93bi1zZWxlY3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vc2VhcmNoYWJsZS1kcm9wZG93bi1zZWxlY3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zZWFyY2hhYmxlLWRyb3Bkb3duLXNlbGVjdC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIFNlYXJjaGFibGVEcm9wZG93blNlbGVjdENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIHN0eWxlOiBEcm9wZG93bkJ1dHRvblN0eWxlO1xuICBASW5wdXQoKSBpdGVtczogQXJyYXk8RHJvcGRvd25JdGVtPjtcbiAgQElucHV0KCkgYnV0dG9uVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBzZWFyY2hUZXh0OiBzdHJpbmc7XG4gIEBJbnB1dCgpIG5vUmVzdWx0c1RleHQ6IHN0cmluZztcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNlbGVjdGVkVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBzZWxlY3RlZFRleHRWYWx1ZTogc3RyaW5nO1xuICBASW5wdXQoKSBjbGVhclNlbGVjdGlvbkJ1dHRvblRpdGxlOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGhhc1NlbGVjdGlvbjogYm9vbGVhbjtcbiAgQElucHV0KCkgd2lkdGggPSAyNTA7XG5cbiAgQE91dHB1dCgpIGl0ZW1TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGNsZWFyU2VsZWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIG9uU2VsZWN0KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLml0ZW1TZWxlY3RlZC5lbWl0KGlkKTtcbiAgfVxuXG4gIG9uQ2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbi5lbWl0KCk7XG4gIH1cbn1cbiJdfQ==