@progress/kendo-angular-popup 5.0.2 → 11.0.0-develop.80

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 (67) hide show
  1. package/NOTICE.txt +3 -3
  2. package/README.md +4 -4
  3. package/{esm2015/main.js → esm2020/index.mjs} +1 -1
  4. package/{esm2015/models/align.interface.js → esm2020/models/align-element-settings.interface.mjs} +1 -1
  5. package/{esm2015/models/collision.type.js → esm2020/models/align.interface.mjs} +1 -1
  6. package/{esm2015/models/collision.interface.js → esm2020/models/collision.interface.mjs} +1 -1
  7. package/{esm2015/models/align-element-settings.interface.js → esm2020/models/collision.type.mjs} +1 -1
  8. package/esm2020/models/margin.interface.mjs +5 -0
  9. package/esm2020/models/offset.interface.mjs +5 -0
  10. package/esm2020/models/popup-animation.interface.mjs +5 -0
  11. package/esm2020/models/popup-ref.mjs +5 -0
  12. package/esm2020/models/popup-settings.mjs +5 -0
  13. package/esm2020/models/position-element-settings.interface.mjs +5 -0
  14. package/{esm2015/models/position-mode.js → esm2020/models/position-mode.mjs} +1 -1
  15. package/esm2020/models/position.interface.mjs +5 -0
  16. package/{esm2015/package-metadata.js → esm2020/package-metadata.mjs} +2 -2
  17. package/{esm2015/popup.component.js → esm2020/popup.component.mjs} +10 -10
  18. package/{esm2015/popup.module.js → esm2020/popup.module.mjs} +5 -5
  19. package/{esm2015/popup.service.js → esm2020/popup.service.mjs} +5 -5
  20. package/{esm2015/kendo-angular-popup.js → esm2020/progress-kendo-angular-popup.mjs} +2 -2
  21. package/{esm2015/scale.js → esm2020/scale.mjs} +1 -1
  22. package/{esm2015/services/align.service.js → esm2020/services/align.service.mjs} +5 -4
  23. package/{esm2015/services/animation.service.js → esm2020/services/animation.service.mjs} +5 -5
  24. package/{esm2015/services/dom.service.js → esm2020/services/dom.service.mjs} +9 -9
  25. package/{esm2015/services/position.service.js → esm2020/services/position.service.mjs} +5 -4
  26. package/{esm2015/services/resize.service.js → esm2020/services/resize.service.mjs} +6 -5
  27. package/{esm2015/services/scrollable.service.js → esm2020/services/scrollable.service.mjs} +6 -5
  28. package/{esm2015/util.js → esm2020/util.mjs} +7 -2
  29. package/fesm2015/progress-kendo-angular-popup.mjs +1374 -0
  30. package/{fesm2015/kendo-angular-popup.js → fesm2020/progress-kendo-angular-popup.mjs} +64 -59
  31. package/{main.d.ts → index.d.ts} +1 -1
  32. package/models/align-element-settings.interface.d.ts +1 -1
  33. package/models/align.interface.d.ts +1 -1
  34. package/models/collision.interface.d.ts +1 -1
  35. package/models/collision.type.d.ts +1 -1
  36. package/models/margin.interface.d.ts +1 -1
  37. package/models/offset.interface.d.ts +1 -1
  38. package/models/popup-animation.interface.d.ts +1 -1
  39. package/models/popup-ref.d.ts +1 -1
  40. package/models/popup-settings.d.ts +1 -1
  41. package/models/position-element-settings.interface.d.ts +1 -1
  42. package/models/position-mode.d.ts +1 -1
  43. package/models/position.interface.d.ts +1 -1
  44. package/package-metadata.d.ts +1 -1
  45. package/package.json +27 -54
  46. package/popup.component.d.ts +8 -8
  47. package/popup.module.d.ts +1 -1
  48. package/popup.service.d.ts +1 -1
  49. package/{kendo-angular-popup.d.ts → progress-kendo-angular-popup.d.ts} +2 -2
  50. package/scale.d.ts +1 -1
  51. package/schematics/ngAdd/index.js +1 -5
  52. package/services/align.service.d.ts +1 -1
  53. package/services/animation.service.d.ts +1 -1
  54. package/services/dom.service.d.ts +6 -6
  55. package/services/position.service.d.ts +1 -1
  56. package/services/resize.service.d.ts +2 -2
  57. package/services/scrollable.service.d.ts +2 -2
  58. package/util.d.ts +3 -3
  59. package/bundles/kendo-angular-popup.umd.js +0 -5
  60. package/esm2015/models/margin.interface.js +0 -5
  61. package/esm2015/models/offset.interface.js +0 -5
  62. package/esm2015/models/popup-animation.interface.js +0 -5
  63. package/esm2015/models/popup-ref.js +0 -5
  64. package/esm2015/models/popup-settings.js +0 -5
  65. package/esm2015/models/position-element-settings.interface.js +0 -5
  66. package/esm2015/models/position.interface.js +0 -5
  67. package/schematics/ngAdd/index.js.map +0 -1
@@ -0,0 +1,1374 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2022 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import * as i0 from '@angular/core';
6
+ import { InjectionToken, Injectable, Inject, Optional, EventEmitter, isDevMode, Component, Input, Output, ViewChild, TemplateRef, NgModule } from '@angular/core';
7
+ import { siblingContainer, parents, addScroll, align, boundingOffset, offset, positionWithScroll, removeScroll, restrictToView, scrollPosition, getWindowViewPort } from '@progress/kendo-popup-common';
8
+ import * as i7 from '@progress/kendo-angular-common';
9
+ import { isDocumentAvailable, hasObservers, ResizeSensorComponent, ResizeSensorModule } from '@progress/kendo-angular-common';
10
+ import { fromEvent, merge, from } from 'rxjs';
11
+ import { auditTime } from 'rxjs/operators';
12
+ import * as i1 from '@angular/animations';
13
+ import { style, animate } from '@angular/animations';
14
+ import { validatePackage } from '@progress/kendo-licensing';
15
+ import * as i8 from '@angular/common';
16
+ import { CommonModule } from '@angular/common';
17
+
18
+ /**
19
+ * @hidden
20
+ */
21
+ const eitherRect = (rect, offset) => {
22
+ if (!rect) {
23
+ return { height: 0, left: offset.left, top: offset.top, width: 0 };
24
+ }
25
+ return rect;
26
+ };
27
+ /**
28
+ * @hidden
29
+ */
30
+ const replaceOffset = (rect, offset) => {
31
+ if (!offset) {
32
+ return rect;
33
+ }
34
+ const result = {
35
+ height: rect.height,
36
+ left: offset.left,
37
+ top: offset.top,
38
+ width: rect.width
39
+ };
40
+ return result;
41
+ };
42
+ /**
43
+ * @hidden
44
+ */
45
+ const removeStackingOffset = (rect, stackingOffset) => {
46
+ if (!stackingOffset) {
47
+ return rect;
48
+ }
49
+ const result = {
50
+ height: rect.height,
51
+ left: rect.left - stackingOffset.left,
52
+ top: rect.top - stackingOffset.top,
53
+ width: rect.width
54
+ };
55
+ return result;
56
+ };
57
+ /**
58
+ * @hidden
59
+ */
60
+ const isDifferentOffset = (oldOffset, newOffset) => {
61
+ const { left: oldLeft, top: oldTop } = oldOffset;
62
+ const { left: newLeft, top: newTop } = newOffset;
63
+ return Math.abs(oldLeft - newLeft) >= 1 || Math.abs(oldTop - newTop) >= 1;
64
+ };
65
+ /**
66
+ * @hidden
67
+ */
68
+ const isWindowAvailable = () => {
69
+ return typeof window !== 'undefined';
70
+ };
71
+ /**
72
+ * @hidden
73
+ */
74
+ const hasBoundingRect = (elem) => !!elem.getBoundingClientRect;
75
+ /**
76
+ * @hidden
77
+ */
78
+ const OVERFLOW_REGEXP = /auto|scroll/;
79
+ const overflowElementStyle = (element) => {
80
+ return `${element.style.overflow}${element.style.overflowX}${element.style.overflowY}`;
81
+ };
82
+ const overflowComputedStyle = (element) => {
83
+ const styles = window.getComputedStyle(element);
84
+ return `${styles.overflow}${styles.overflowX}${styles.overflowY}`;
85
+ };
86
+ const overflowStyle = (element) => {
87
+ return overflowElementStyle(element) || overflowComputedStyle(element);
88
+ };
89
+ /**
90
+ * @hidden
91
+ */
92
+ const scrollableParents = (element) => {
93
+ const parentElements = [];
94
+ if (!isDocumentAvailable() || !isWindowAvailable()) {
95
+ return parentElements;
96
+ }
97
+ let parent = element.parentElement;
98
+ while (parent) {
99
+ if (OVERFLOW_REGEXP.test(overflowStyle(parent)) || parent.hasAttribute('data-scrollable')) {
100
+ parentElements.push(parent);
101
+ }
102
+ parent = parent.parentElement;
103
+ }
104
+ parentElements.push(window);
105
+ return parentElements;
106
+ };
107
+ /**
108
+ * @hidden
109
+ */
110
+ const FRAME_DURATION = 1000 / 60; //1000ms divided by 60fps
111
+ // eslint-disable-next-line @typescript-eslint/ban-types
112
+ function memoize(fun) {
113
+ let result;
114
+ let called = false;
115
+ return (...args) => {
116
+ if (called) {
117
+ return result;
118
+ }
119
+ result = fun(...args);
120
+ called = true;
121
+ return result;
122
+ };
123
+ }
124
+ /**
125
+ * @hidden
126
+ */
127
+ const hasRelativeStackingContext = memoize(() => {
128
+ if (!isDocumentAvailable() && document.body !== null) {
129
+ return false;
130
+ }
131
+ const top = 10;
132
+ const parent = document.createElement("div");
133
+ parent.style.transform = "matrix(10, 0, 0, 10, 0, 0)";
134
+ const childElement = document.createElement("div");
135
+ childElement.style.position = 'fixed';
136
+ childElement.style.top = `${top}px`;
137
+ childElement.textContent = 'child';
138
+ parent.appendChild(childElement);
139
+ document.body.appendChild(parent);
140
+ const isDifferent = parent.children[0].getBoundingClientRect().top !== top;
141
+ document.body.removeChild(parent);
142
+ return isDifferent;
143
+ });
144
+ /**
145
+ * @hidden
146
+ */
147
+ const zIndex = (anchor, container) => {
148
+ if (!anchor || !isDocumentAvailable() || !isWindowAvailable()) {
149
+ return null;
150
+ }
151
+ const sibling = siblingContainer(anchor, container);
152
+ if (!sibling) {
153
+ return null;
154
+ }
155
+ const result = [anchor].concat(parents(anchor, sibling)).reduce((index, p) => {
156
+ const zIndexStyle = p.style.zIndex || window.getComputedStyle(p).zIndex;
157
+ const current = parseInt(zIndexStyle, 10);
158
+ return current > index ? current : index;
159
+ }, 0);
160
+ return result ? (result + 1) : null;
161
+ };
162
+ /**
163
+ * @hidden
164
+ */
165
+ const scaleRect = (rect, scale) => {
166
+ if (!rect || scale === 1) {
167
+ return rect;
168
+ }
169
+ return {
170
+ height: rect.height / scale,
171
+ left: rect.left / scale,
172
+ top: rect.top / scale,
173
+ width: rect.width / scale
174
+ };
175
+ };
176
+
177
+ /**
178
+ * Used to set the document scale when using a [scale transform](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/scale).
179
+ *
180
+ * The document or container scale is required to compute the popup position correctly. Detecting the scale is not reliable and must be set by providing a value for SCALE. See [Support for Document Scale]({% slug documentscale_popup %}).
181
+ *
182
+ * > Using this token is not necessary for user-applied browser zoom.
183
+ *
184
+ * {% meta height:300 %}
185
+ * {% embed_file scale/app.component.ts preview %}
186
+ * {% embed_file shared/app.module.ts %}
187
+ * {% embed_file shared/main.ts %}
188
+ * {% endmeta %}
189
+ *
190
+ *
191
+ */
192
+ const SCALE = new InjectionToken('Popup Document Scale');
193
+
194
+ const STYLES = [
195
+ 'font-size',
196
+ 'font-family',
197
+ 'font-stretch',
198
+ 'font-style',
199
+ 'font-weight',
200
+ 'line-height'
201
+ ];
202
+ /**
203
+ * @hidden
204
+ */
205
+ class DOMService {
206
+ addOffset(current, addition) {
207
+ return {
208
+ left: current.left + addition.left,
209
+ top: current.top + addition.top
210
+ };
211
+ }
212
+ addScroll(rect, scroll) {
213
+ return addScroll(rect, scroll);
214
+ }
215
+ align(settings) {
216
+ return align(settings);
217
+ }
218
+ boundingOffset(el) {
219
+ return boundingOffset(el);
220
+ }
221
+ getFontStyles(el) {
222
+ const window = this.getWindow();
223
+ if (!window || !el) {
224
+ return [];
225
+ }
226
+ const computedStyles = window.getComputedStyle(el);
227
+ return STYLES.map(key => ({ key: key, value: computedStyles[key] }));
228
+ }
229
+ getWindow() {
230
+ return isWindowAvailable() ? window : null;
231
+ }
232
+ hasOffsetParent(el) {
233
+ if (!el || !isDocumentAvailable()) {
234
+ return false;
235
+ }
236
+ return !!this.nativeElement(el).offsetParent;
237
+ }
238
+ offset(el) {
239
+ if (!el || !isDocumentAvailable()) {
240
+ return null;
241
+ }
242
+ return offset(el);
243
+ }
244
+ offsetAtPoint(el, currentLocation) {
245
+ if (!el || !isDocumentAvailable()) {
246
+ return null;
247
+ }
248
+ const element = this.nativeElement(el);
249
+ const { left, top, transition } = element.style;
250
+ element.style.transition = 'none';
251
+ element.style.left = `${currentLocation.left}px`;
252
+ element.style.top = `${currentLocation.top}px`;
253
+ const currentOffset = offset(element);
254
+ element.style.left = left;
255
+ element.style.top = top;
256
+ // prevents elements with transition to be animated because of the change
257
+ // eslint-disable-next-line no-unused-expressions
258
+ element.offsetHeight;
259
+ element.style.transition = transition;
260
+ return currentOffset;
261
+ }
262
+ nativeElement(el) {
263
+ if (!el || !isDocumentAvailable()) {
264
+ return null;
265
+ }
266
+ return el.nativeElement || el;
267
+ }
268
+ position(element, popup, scale = 1) {
269
+ if (!element || !popup) {
270
+ return null;
271
+ }
272
+ return positionWithScroll(element, this.nativeElement(popup), scale);
273
+ }
274
+ removeScroll(rect, scroll) {
275
+ return removeScroll(rect, scroll);
276
+ }
277
+ restrictToView(settings) {
278
+ return restrictToView(settings);
279
+ }
280
+ scrollPosition(el) {
281
+ return scrollPosition(this.nativeElement(el));
282
+ }
283
+ scrollableParents(el) {
284
+ return scrollableParents(el);
285
+ }
286
+ stackingElementOffset(el) {
287
+ const relativeContextElement = this.getRelativeContextElement(el);
288
+ if (!relativeContextElement) {
289
+ return null;
290
+ }
291
+ return offset(relativeContextElement);
292
+ }
293
+ stackingElementScroll(el) {
294
+ const relativeContextElement = this.getRelativeContextElement(el);
295
+ if (!relativeContextElement) {
296
+ return { x: 0, y: 0 };
297
+ }
298
+ return {
299
+ x: relativeContextElement.scrollLeft,
300
+ y: relativeContextElement.scrollTop
301
+ };
302
+ }
303
+ getRelativeContextElement(el) {
304
+ if (!el || !hasRelativeStackingContext()) {
305
+ return null;
306
+ }
307
+ let parent = this.nativeElement(el).parentElement;
308
+ while (parent) {
309
+ if (window.getComputedStyle(parent).transform !== 'none') {
310
+ return parent;
311
+ }
312
+ parent = parent.parentElement;
313
+ }
314
+ return null;
315
+ }
316
+ useRelativePosition(el) {
317
+ return !!this.getRelativeContextElement(el);
318
+ }
319
+ windowViewPort(el) {
320
+ return getWindowViewPort(this.nativeElement(el));
321
+ }
322
+ zIndex(anchor, container) {
323
+ return zIndex(anchor, this.nativeElement(container));
324
+ }
325
+ zoomLevel() {
326
+ if (!isDocumentAvailable() || !isWindowAvailable()) {
327
+ return 1;
328
+ }
329
+ return parseFloat((document.documentElement.clientWidth / window.innerWidth).toFixed(2)) || 1;
330
+ }
331
+ isZoomed() {
332
+ return this.zoomLevel() > 1;
333
+ }
334
+ }
335
+ DOMService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DOMService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
336
+ DOMService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DOMService });
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DOMService, decorators: [{
338
+ type: Injectable
339
+ }] });
340
+
341
+ /**
342
+ * @hidden
343
+ */
344
+ class AlignService {
345
+ constructor(_dom, scale = 1) {
346
+ this._dom = _dom;
347
+ this.scale = scale;
348
+ }
349
+ alignElement(settings) {
350
+ const { anchor, element, anchorAlign, elementAlign, margin, offset, positionMode } = settings;
351
+ const scale = this.scale || 1;
352
+ const fixedMode = positionMode === 'fixed' || !this._dom.hasOffsetParent(element);
353
+ const anchorRect = fixedMode ? this.absoluteRect(anchor, element, offset, scale) : this.relativeRect(anchor, element, offset, scale);
354
+ const elementRect = scaleRect(this._dom.offset(element.nativeElement), scale);
355
+ const result = this._dom.align({
356
+ anchorAlign: anchorAlign,
357
+ anchorRect: anchorRect,
358
+ elementAlign: elementAlign,
359
+ elementRect: elementRect,
360
+ margin
361
+ });
362
+ return result;
363
+ }
364
+ absoluteRect(anchor, element, offset, scale) {
365
+ const scrollPos = this.elementScrollPosition(anchor, element);
366
+ const rect = eitherRect(this._dom.offset(anchor), offset);
367
+ const stackScale = 2 * scale;
368
+ const stackScroll = this._dom.stackingElementScroll(element);
369
+ if (scale !== 1 && stackScroll) {
370
+ stackScroll.x /= stackScale;
371
+ stackScroll.y /= stackScale;
372
+ }
373
+ const stackOffset = this._dom.stackingElementOffset(element);
374
+ if (scale !== 1 && stackOffset) {
375
+ stackOffset.left /= stackScale;
376
+ stackOffset.top /= stackScale;
377
+ }
378
+ return this._dom.removeScroll(this._dom.addScroll(removeStackingOffset(scaleRect(rect, scale), stackOffset), stackScroll), scrollPos);
379
+ }
380
+ elementScrollPosition(anchor, element) {
381
+ return anchor ? { x: 0, y: 0 } : this._dom.scrollPosition(element);
382
+ }
383
+ relativeRect(anchor, element, offset, scale) {
384
+ const rect = eitherRect(this._dom.position(anchor, element, scale), offset);
385
+ return scaleRect(rect, scale);
386
+ }
387
+ }
388
+ AlignService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AlignService, deps: [{ token: DOMService }, { token: SCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
389
+ AlignService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AlignService });
390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AlignService, decorators: [{
391
+ type: Injectable
392
+ }], ctorParameters: function () {
393
+ return [{ type: DOMService }, { type: undefined, decorators: [{
394
+ type: Inject,
395
+ args: [SCALE]
396
+ }, {
397
+ type: Optional
398
+ }] }];
399
+ } });
400
+
401
+ /**
402
+ * @hidden
403
+ */
404
+ class PositionService {
405
+ constructor(_dom, scale = 1) {
406
+ this._dom = _dom;
407
+ this.scale = scale;
408
+ }
409
+ positionElement(settings) {
410
+ const { anchor, currentLocation, element, anchorAlign, elementAlign, collisions, margin } = settings;
411
+ const dom = this._dom;
412
+ const scale = this.scale || 1;
413
+ const elementOffset = dom.offsetAtPoint(element, currentLocation);
414
+ const elementRect = scaleRect(elementOffset, scale);
415
+ const anchorOffset = scaleRect(dom.offset(anchor), scale);
416
+ const anchorRect = eitherRect(anchorOffset, currentLocation);
417
+ const viewPort = settings.viewPort || dom.windowViewPort(element);
418
+ viewPort.width = viewPort.width / scale;
419
+ viewPort.height = viewPort.height / scale;
420
+ const result = dom.restrictToView({
421
+ anchorAlign,
422
+ anchorRect,
423
+ collisions,
424
+ elementAlign,
425
+ elementRect,
426
+ margin,
427
+ viewPort
428
+ });
429
+ const offset = dom.addOffset(currentLocation, result.offset);
430
+ return {
431
+ flip: result.flip,
432
+ flipped: result.flipped,
433
+ offset: offset
434
+ };
435
+ }
436
+ }
437
+ PositionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PositionService, deps: [{ token: DOMService }, { token: SCALE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
438
+ PositionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PositionService });
439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PositionService, decorators: [{
440
+ type: Injectable
441
+ }], ctorParameters: function () {
442
+ return [{ type: DOMService }, { type: undefined, decorators: [{
443
+ type: Inject,
444
+ args: [SCALE]
445
+ }, {
446
+ type: Optional
447
+ }] }];
448
+ } });
449
+
450
+ /**
451
+ * @hidden
452
+ */
453
+ class ResizeService {
454
+ constructor(_dom, _zone) {
455
+ this._dom = _dom;
456
+ this._zone = _zone;
457
+ }
458
+ subscribe(callback) {
459
+ if (!isDocumentAvailable()) {
460
+ return;
461
+ }
462
+ this._zone.runOutsideAngular(() => {
463
+ this.subscription = fromEvent(this._dom.getWindow(), "resize")
464
+ .pipe(auditTime(FRAME_DURATION))
465
+ .subscribe(() => callback());
466
+ });
467
+ }
468
+ unsubscribe() {
469
+ if (!this.subscription) {
470
+ return;
471
+ }
472
+ this.subscription.unsubscribe();
473
+ }
474
+ isUnsubscribed() {
475
+ return this.subscription && this.subscription.closed;
476
+ }
477
+ }
478
+ ResizeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ResizeService, deps: [{ token: DOMService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
479
+ ResizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ResizeService });
480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ResizeService, decorators: [{
481
+ type: Injectable
482
+ }], ctorParameters: function () { return [{ type: DOMService }, { type: i0.NgZone }]; } });
483
+
484
+ /**
485
+ * @hidden
486
+ */
487
+ const THRESHOLD_DIFF = 1;
488
+ /**
489
+ * @hidden
490
+ */
491
+ class ScrollableService {
492
+ constructor(_dom, _zone) {
493
+ this._dom = _dom;
494
+ this._zone = _zone;
495
+ }
496
+ forElement(element) {
497
+ this.unsubscribe();
498
+ this.element = element;
499
+ return this;
500
+ }
501
+ subscribe(callback) {
502
+ if (!callback || !isDocumentAvailable() || !this.element) {
503
+ return;
504
+ }
505
+ const parents = this._dom.scrollableParents(this.element);
506
+ this._zone.runOutsideAngular(() => {
507
+ const observables = parents.map(p => fromEvent(p, "scroll").pipe(auditTime(FRAME_DURATION)));
508
+ const subscriber = (e) => {
509
+ const target = e.target;
510
+ const isParent = parents.filter(p => p === target).length > 0;
511
+ const isDocument = target === document;
512
+ const isWindow = target === window;
513
+ if (isParent || isDocument || isWindow) {
514
+ callback(this.isVisible(this.element, target));
515
+ }
516
+ };
517
+ this.subscription = merge(...observables).subscribe(subscriber);
518
+ });
519
+ }
520
+ unsubscribe() {
521
+ if (!this.subscription) {
522
+ return;
523
+ }
524
+ this.subscription.unsubscribe();
525
+ }
526
+ isVisible(elem, container) {
527
+ const elemRect = this._dom.boundingOffset(elem);
528
+ const containerRect = this._dom.boundingOffset(this._dom.nativeElement(container));
529
+ if (THRESHOLD_DIFF < (containerRect.top - elemRect.bottom)) {
530
+ return false;
531
+ }
532
+ if (THRESHOLD_DIFF < (elemRect.top - containerRect.bottom)) {
533
+ return false;
534
+ }
535
+ if (THRESHOLD_DIFF < (elemRect.left - containerRect.right)) {
536
+ return false;
537
+ }
538
+ if (THRESHOLD_DIFF < (containerRect.left - elemRect.right)) {
539
+ return false;
540
+ }
541
+ return true;
542
+ }
543
+ }
544
+ ScrollableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ScrollableService, deps: [{ token: DOMService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
545
+ ScrollableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ScrollableService });
546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ScrollableService, decorators: [{
547
+ type: Injectable
548
+ }], ctorParameters: function () { return [{ type: DOMService }, { type: i0.NgZone }]; } });
549
+
550
+ const LEFT = 'left';
551
+ const RIGHT = 'right';
552
+ const DOWN = 'down';
553
+ const UP = 'up';
554
+ const DEFAULT_TYPE = 'slide';
555
+ const DEFAULT_DURATION = 100;
556
+ const animationTypes = {};
557
+ animationTypes.expand = (direction) => {
558
+ const scale = direction === UP || direction === DOWN ? 'scaleY' : 'scaleX';
559
+ const startScale = 0;
560
+ const endScale = 1;
561
+ let origin;
562
+ if (direction === DOWN) {
563
+ origin = 'top';
564
+ }
565
+ else if (direction === LEFT) {
566
+ origin = RIGHT;
567
+ }
568
+ else if (direction === RIGHT) {
569
+ origin = LEFT;
570
+ }
571
+ else {
572
+ origin = 'bottom';
573
+ }
574
+ return {
575
+ start: { transform: `${scale}(${startScale})`, transformOrigin: origin },
576
+ end: { transform: `${scale}(${endScale})` }
577
+ };
578
+ };
579
+ animationTypes.slide = (direction) => {
580
+ const translate = direction === LEFT || direction === RIGHT ? 'translateX' : 'translateY';
581
+ const start = direction === RIGHT || direction === DOWN ? -100 : 100;
582
+ const end = 0;
583
+ return {
584
+ start: { transform: `${translate}(${start}%)` },
585
+ end: { transform: `${translate}(${end}%)` }
586
+ };
587
+ };
588
+ animationTypes.fade = () => {
589
+ return {
590
+ start: { opacity: 0 },
591
+ end: { opacity: 1 }
592
+ };
593
+ };
594
+ animationTypes.zoom = () => {
595
+ const start = 0;
596
+ const end = 1;
597
+ return {
598
+ start: { transform: `scale(${start})` },
599
+ end: { transform: `scale(${end})` }
600
+ };
601
+ };
602
+ /**
603
+ * @hidden
604
+ */
605
+ class AnimationService {
606
+ constructor(animationBuilder) {
607
+ this.animationBuilder = animationBuilder;
608
+ this.start = new EventEmitter();
609
+ this.end = new EventEmitter();
610
+ }
611
+ play(element, options, flip) {
612
+ if (!this.flip || this.flip.horizontal !== flip.horizontal ||
613
+ this.flip.vertical !== flip.vertical) {
614
+ this.flip = flip;
615
+ const type = options.type || DEFAULT_TYPE;
616
+ const statesFn = animationTypes[type];
617
+ if (statesFn) {
618
+ const direction = this.getDirection(flip, options);
619
+ const states = statesFn(direction);
620
+ this.playStates(element, states, options);
621
+ }
622
+ else if (isDevMode()) {
623
+ throw new Error(`Unsupported animation type: "${type}". The supported types are slide, expand, fade and zoom.`);
624
+ }
625
+ }
626
+ }
627
+ ngOnDestroy() {
628
+ this.stopPlayer();
629
+ }
630
+ playStates(element, states, options) {
631
+ this.stopPlayer();
632
+ const duration = options.duration || DEFAULT_DURATION;
633
+ const factory = this.animationBuilder.build([
634
+ style(states.start),
635
+ animate(`${duration}ms ease-in`, style(states.end))
636
+ ]);
637
+ const player = this.player = factory.create(element);
638
+ player.onDone(() => {
639
+ this.end.emit();
640
+ this.stopPlayer();
641
+ });
642
+ this.start.emit();
643
+ player.play();
644
+ }
645
+ getDirection(flip, options) {
646
+ let direction = options.direction || DOWN;
647
+ if (flip.horizontal) {
648
+ if (direction === LEFT) {
649
+ direction = RIGHT;
650
+ }
651
+ else if (direction === RIGHT) {
652
+ direction = LEFT;
653
+ }
654
+ }
655
+ if (flip.vertical) {
656
+ if (direction === DOWN) {
657
+ direction = UP;
658
+ }
659
+ else if (direction === UP) {
660
+ direction = DOWN;
661
+ }
662
+ }
663
+ return direction;
664
+ }
665
+ stopPlayer() {
666
+ if (this.player) {
667
+ this.player.destroy();
668
+ this.player = null;
669
+ }
670
+ }
671
+ }
672
+ AnimationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AnimationService, deps: [{ token: i1.AnimationBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
673
+ AnimationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AnimationService });
674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AnimationService, decorators: [{
675
+ type: Injectable
676
+ }], ctorParameters: function () { return [{ type: i1.AnimationBuilder }]; } });
677
+
678
+ /**
679
+ * @hidden
680
+ */
681
+ const packageMetadata = {
682
+ name: '@progress/kendo-angular-popup',
683
+ productName: 'Kendo UI for Angular',
684
+ productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
685
+ publishDate: 1672394336,
686
+ version: '',
687
+ licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
688
+ };
689
+
690
+ const DEFAULT_OFFSET = { left: -10000, top: 0 };
691
+ const ANIMATION_CONTAINER = 'k-animation-container';
692
+ const ANIMATION_CONTAINER_FIXED = 'k-animation-container-fixed';
693
+ /**
694
+ * Represents the [Kendo UI Popup component for Angular]({% slug overview_popup %}).
695
+ *
696
+ * @example
697
+ * ```ts
698
+ * _@Component({
699
+ * selector: 'my-app',
700
+ * template: `
701
+ * <button #anchor (click)="show=!show">Toggle</button>
702
+ * <kendo-popup *ngIf="show" [anchor]="anchor">
703
+ * <strong>Popup content!</strong>
704
+ * </kendo-popup>
705
+ * `
706
+ * })
707
+ * class AppComponent {
708
+ * public show: boolean = false;
709
+ * }
710
+ * ```
711
+ */
712
+ class PopupComponent {
713
+ constructor(container, _alignService, domService, _positionService, _resizeService, _scrollableService, animationService, _renderer, _zone) {
714
+ this.container = container;
715
+ this._alignService = _alignService;
716
+ this.domService = domService;
717
+ this._positionService = _positionService;
718
+ this._resizeService = _resizeService;
719
+ this._scrollableService = _scrollableService;
720
+ this.animationService = animationService;
721
+ this._renderer = _renderer;
722
+ this._zone = _zone;
723
+ /**
724
+ * Controls the Popup animation. By default, the opening and closing animations
725
+ * are enabled ([see example]({% slug animations_popup %})).
726
+ */
727
+ this.animate = true;
728
+ /**
729
+ * Specifies the anchor pivot point
730
+ * ([see example]({% slug alignmentpositioning_popup %}#toc-positioning)).
731
+ */
732
+ this.anchorAlign = { horizontal: 'left', vertical: 'bottom' };
733
+ /**
734
+ * Configures the collision behavior of the Popup
735
+ * ([see example]({% slug viewportboundarydetection_popup %})).
736
+ */
737
+ this.collision = { horizontal: 'fit', vertical: 'flip' };
738
+ /**
739
+ * Specifies the pivot point of the Popup
740
+ * ([see example]({% slug alignmentpositioning_popup %}#toc-positioning)).
741
+ */
742
+ this.popupAlign = { horizontal: 'left', vertical: 'top' };
743
+ /**
744
+ * Controls whether the component will copy the `anchor` font styles.
745
+ */
746
+ this.copyAnchorStyles = false;
747
+ /**
748
+ * Specifies the position mode of the component. By default, the Popup uses fixed positioning.
749
+ * To make the Popup acquire absolute positioning, set this option to `absolute`.
750
+ *
751
+ * > If you need to support mobile browsers with the zoom option,
752
+ * use the `absolute` positioning of the Popup.
753
+ *
754
+ * @example
755
+ * ```html
756
+ * <style>
757
+ * .parent-content {
758
+ * position: relative;
759
+ * width: 200px;
760
+ * height: 200px;
761
+ * overflow: auto;
762
+ * margin: 200px auto;
763
+ * border: 1px solid red;
764
+ * }
765
+ * .content {
766
+ * position: relative;
767
+ * width: 100px;
768
+ * height: 100px;
769
+ * overflow: auto;
770
+ * margin: 300px;
771
+ * border: 1px solid blue;
772
+ * }
773
+ * .anchor {
774
+ * position: absolute;
775
+ * top: 200px;
776
+ * left: 200px;
777
+ * }
778
+ * </style>
779
+ * ```
780
+ * ```ts
781
+ * _@Component({
782
+ * selector: 'my-app',
783
+ * template: `
784
+ * <div class="example-config">
785
+ * Position mode:
786
+ * <label><input type="radio" value="fixed" [(ngModel)]="mode" /> Fixed</label>
787
+ * <label><input type="radio" value="absolute" [(ngModel)]="mode" /> Absolute</label>
788
+ * </div>
789
+ * <div class="example-config">
790
+ * Append to
791
+ * <label>
792
+ * <input type="radio" name="place" [value]="1" [(ngModel)]="checked" />
793
+ * Root component
794
+ * </label>
795
+ * <label>
796
+ * <input type="radio" name="place" [value]="2" [(ngModel)]="checked" />
797
+ * <span [style.color]="'red'">Red Container</span>
798
+ * </label>
799
+ * <label>
800
+ * <input type="radio" name="place" [value]="3" [(ngModel)]="checked" />
801
+ * <span [style.color]="'blue'">Blue Container</span>
802
+ * </label>
803
+ * </div>
804
+ * <div class="example">
805
+ * <div class="parent-content" [scrollLeft]="250" [scrollTop]="230">
806
+ * <div class="content" [scrollLeft]="170" [scrollTop]="165">
807
+ * <button #anchor class="anchor" (click)="show = !show">Toggle</button>
808
+ * <kendo-popup [positionMode]="mode" [anchor]="anchor" (anchorViewportLeave)="show=false" *ngIf="show && checked === 3">
809
+ * <ul>
810
+ * <li>Item1</li>
811
+ * <li>Item2</li>
812
+ * <li>Item3</li>
813
+ * </ul>
814
+ * </kendo-popup>
815
+ * <span [style.position]="'absolute'" [style.top.px]="400" [style.left.px]="400">Bottom/Right</span>
816
+ * </div>
817
+ * <kendo-popup [positionMode]="mode" [anchor]="anchor" (anchorViewportLeave)="show=false" *ngIf="show && checked === 2">
818
+ * <ul>
819
+ * <li>Item1</li>
820
+ * <li>Item2</li>
821
+ * <li>Item3</li>
822
+ * </ul>
823
+ * </kendo-popup>
824
+ * <span [style.position]="'absolute'" [style.top.px]="600" [style.left.px]="600">Bottom/Right</span>
825
+ * </div>
826
+ * <kendo-popup [positionMode]="mode" [anchor]="anchor" (anchorViewportLeave)="show=false" *ngIf="show && checked === 1">
827
+ * <ul>
828
+ * <li>Item1</li>
829
+ * <li>Item2</li>
830
+ * <li>Item3</li>
831
+ * </ul>
832
+ * </kendo-popup>
833
+ * </div>
834
+ * `
835
+ * })
836
+ * class AppComponent {
837
+ * public checked: number = 3;
838
+ * public mode: string = 'absolute';
839
+ * public show: boolean = true;
840
+ * }
841
+ * ```
842
+ */
843
+ this.positionMode = 'fixed';
844
+ /**
845
+ * Specifies the absolute position of the element
846
+ * ([see example]({% slug alignmentpositioning_popup %}#toc-aligning-to-absolute-points)).
847
+ * The Popup opens next to that point. The Popup pivot point is defined by the `popupAlign` configuration option.
848
+ * The boundary detection is applied by using the window viewport.
849
+ */
850
+ this.offset = DEFAULT_OFFSET;
851
+ /**
852
+ * Fires when the anchor is scrolled outside the screen boundaries.
853
+ * ([see example]({% slug closing_popup %}#toc-after-leaving-the-viewport)).
854
+ */
855
+ this.anchorViewportLeave = new EventEmitter();
856
+ /**
857
+ * Fires after the component is closed.
858
+ */
859
+ this.close = new EventEmitter();
860
+ /**
861
+ * Fires after the component is opened and the opening animation ends.
862
+ */
863
+ this.open = new EventEmitter();
864
+ /**
865
+ * Fires after the component is opened and the Popup is positioned.
866
+ */
867
+ this.positionChange = new EventEmitter();
868
+ this.resolvedPromise = Promise.resolve(null);
869
+ this.initialCheck = true;
870
+ validatePackage(packageMetadata);
871
+ this._renderer.addClass(container.nativeElement, ANIMATION_CONTAINER);
872
+ this.updateFixedClass();
873
+ }
874
+ ngOnInit() {
875
+ this.reposition = this.reposition.bind(this);
876
+ this._resizeService.subscribe(this.reposition);
877
+ this.animationSubscriptions = this.animationService.start.subscribe(this.onAnimationStart.bind(this));
878
+ this.animationSubscriptions.add(this.animationService.end.subscribe(this.onAnimationEnd.bind(this)));
879
+ this._scrollableService.forElement(this.domService.nativeElement(this.anchor) || this.container.nativeElement).subscribe(this.onScroll.bind(this));
880
+ this.currentOffset = DEFAULT_OFFSET;
881
+ this.setZIndex();
882
+ this.copyFontStyles();
883
+ this.updateFixedClass();
884
+ this.reposition();
885
+ }
886
+ ngOnChanges(changes) {
887
+ if (changes.copyAnchorStyles) {
888
+ this.copyFontStyles();
889
+ }
890
+ if (changes.positionMode) {
891
+ this.updateFixedClass();
892
+ }
893
+ }
894
+ ngAfterViewInit() {
895
+ if (!this.animate) {
896
+ this.resolvedPromise.then(() => {
897
+ this.onAnimationEnd();
898
+ });
899
+ }
900
+ }
901
+ ngAfterViewChecked() {
902
+ if (this.initialCheck) {
903
+ this.initialCheck = false;
904
+ return;
905
+ }
906
+ this._zone.runOutsideAngular(() => {
907
+ // workarounds https://github.com/angular/angular/issues/19094
908
+ // uses promise because it is executed synchronously after the content is updated
909
+ // does not use onStable in case the current zone is not the angular one.
910
+ this.unsubscribeReposition();
911
+ this.repositionSubscription = from(this.resolvedPromise)
912
+ .subscribe(this.reposition);
913
+ });
914
+ }
915
+ ngOnDestroy() {
916
+ this.anchorViewportLeave.complete();
917
+ this.positionChange.complete();
918
+ this.close.emit();
919
+ this.close.complete();
920
+ this._resizeService.unsubscribe();
921
+ this._scrollableService.unsubscribe();
922
+ this.animationSubscriptions.unsubscribe();
923
+ this.unsubscribeReposition();
924
+ }
925
+ /**
926
+ * @hidden
927
+ */
928
+ onResize() {
929
+ this.reposition();
930
+ }
931
+ onAnimationStart() {
932
+ this._renderer.removeClass(this.container.nativeElement, 'k-animation-container-shown');
933
+ }
934
+ onAnimationEnd() {
935
+ this._renderer.addClass(this.container.nativeElement, 'k-animation-container-shown');
936
+ this.open.emit();
937
+ this.open.complete();
938
+ }
939
+ get currentOffset() {
940
+ return this._currentOffset;
941
+ }
942
+ set currentOffset(offset) {
943
+ this.setContainerStyle('left', `${offset.left}px`);
944
+ this.setContainerStyle('top', `${offset.top}px`);
945
+ this._currentOffset = offset;
946
+ }
947
+ setZIndex() {
948
+ if (this.anchor) {
949
+ this.setContainerStyle('z-index', String(this.domService.zIndex(this.domService.nativeElement(this.anchor), this.container)));
950
+ }
951
+ }
952
+ reposition() {
953
+ if (!isDocumentAvailable()) {
954
+ return;
955
+ }
956
+ const { flip, offset } = this.position();
957
+ if (!this.currentOffset || isDifferentOffset(this.currentOffset, offset)) {
958
+ this.currentOffset = offset;
959
+ if (hasObservers(this.positionChange)) {
960
+ this._zone.run(() => this.positionChange.emit({ offset, flip }));
961
+ }
962
+ }
963
+ if (this.animate) {
964
+ this.animationService.play(this.contentContainer.nativeElement, this.animate, flip);
965
+ }
966
+ this.resizeSensor.acceptSize();
967
+ }
968
+ position() {
969
+ const alignedOffset = this._alignService.alignElement({
970
+ anchor: this.domService.nativeElement(this.anchor),
971
+ anchorAlign: this.anchorAlign,
972
+ element: this.container,
973
+ elementAlign: this.popupAlign,
974
+ margin: this.margin,
975
+ offset: this.offset,
976
+ positionMode: this.positionMode
977
+ });
978
+ return this._positionService.positionElement({
979
+ anchor: this.domService.nativeElement(this.anchor),
980
+ anchorAlign: this.anchorAlign,
981
+ collisions: this.collision,
982
+ currentLocation: alignedOffset,
983
+ element: this.container,
984
+ elementAlign: this.popupAlign,
985
+ margin: this.margin
986
+ });
987
+ }
988
+ onScroll(isInViewPort) {
989
+ const hasLeaveObservers = hasObservers(this.anchorViewportLeave);
990
+ if (isInViewPort || !hasLeaveObservers) {
991
+ this.reposition();
992
+ }
993
+ else if (hasLeaveObservers) {
994
+ this._zone.run(() => {
995
+ this.anchorViewportLeave.emit();
996
+ });
997
+ }
998
+ }
999
+ copyFontStyles() {
1000
+ if (!this.anchor || !this.copyAnchorStyles) {
1001
+ return;
1002
+ }
1003
+ this.domService.getFontStyles(this.domService.nativeElement(this.anchor))
1004
+ .forEach((s) => this.setContainerStyle(s.key, s.value));
1005
+ }
1006
+ updateFixedClass() {
1007
+ const action = this.positionMode === 'fixed' ? 'addClass' : 'removeClass';
1008
+ this._renderer[action](this.container.nativeElement, ANIMATION_CONTAINER_FIXED);
1009
+ }
1010
+ setContainerStyle(name, value) {
1011
+ this._renderer.setStyle(this.container.nativeElement, name, value);
1012
+ }
1013
+ unsubscribeReposition() {
1014
+ if (this.repositionSubscription) {
1015
+ this.repositionSubscription.unsubscribe();
1016
+ }
1017
+ }
1018
+ }
1019
+ PopupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupComponent, deps: [{ token: i0.ElementRef }, { token: AlignService }, { token: DOMService }, { token: PositionService }, { token: ResizeService }, { token: ScrollableService }, { token: AnimationService }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
1020
+ PopupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PopupComponent, selector: "kendo-popup", inputs: { animate: "animate", anchor: "anchor", anchorAlign: "anchorAlign", collision: "collision", popupAlign: "popupAlign", copyAnchorStyles: "copyAnchorStyles", popupClass: "popupClass", positionMode: "positionMode", offset: "offset", margin: "margin" }, outputs: { anchorViewportLeave: "anchorViewportLeave", close: "close", open: "open", positionChange: "positionChange" }, providers: [AlignService, AnimationService, DOMService, PositionService, ResizeService, ScrollableService], viewQueries: [{ propertyName: "contentContainer", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "resizeSensor", first: true, predicate: ResizeSensorComponent, descendants: true, static: true }], exportAs: ["kendo-popup"], usesOnChanges: true, ngImport: i0, template: `
1021
+ <div class="k-popup" [ngClass]="popupClass" #container>
1022
+ <ng-content></ng-content>
1023
+ <ng-template [ngTemplateOutlet]="content" [ngIf]="content"></ng-template>
1024
+ <kendo-resize-sensor [rateLimit]="100" (resize)="onResize()">
1025
+ </kendo-resize-sensor>
1026
+ </div>
1027
+ `, isInline: true, components: [{ type: i7.ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }], directives: [{ type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1028
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupComponent, decorators: [{
1029
+ type: Component,
1030
+ args: [{
1031
+ exportAs: 'kendo-popup',
1032
+ providers: [AlignService, AnimationService, DOMService, PositionService, ResizeService, ScrollableService],
1033
+ selector: 'kendo-popup',
1034
+ template: `
1035
+ <div class="k-popup" [ngClass]="popupClass" #container>
1036
+ <ng-content></ng-content>
1037
+ <ng-template [ngTemplateOutlet]="content" [ngIf]="content"></ng-template>
1038
+ <kendo-resize-sensor [rateLimit]="100" (resize)="onResize()">
1039
+ </kendo-resize-sensor>
1040
+ </div>
1041
+ `
1042
+ }]
1043
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: AlignService }, { type: DOMService }, { type: PositionService }, { type: ResizeService }, { type: ScrollableService }, { type: AnimationService }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { animate: [{
1044
+ type: Input
1045
+ }], anchor: [{
1046
+ type: Input
1047
+ }], anchorAlign: [{
1048
+ type: Input
1049
+ }], collision: [{
1050
+ type: Input
1051
+ }], popupAlign: [{
1052
+ type: Input
1053
+ }], copyAnchorStyles: [{
1054
+ type: Input
1055
+ }], popupClass: [{
1056
+ type: Input
1057
+ }], positionMode: [{
1058
+ type: Input
1059
+ }], offset: [{
1060
+ type: Input
1061
+ }], margin: [{
1062
+ type: Input
1063
+ }], anchorViewportLeave: [{
1064
+ type: Output
1065
+ }], close: [{
1066
+ type: Output
1067
+ }], open: [{
1068
+ type: Output
1069
+ }], positionChange: [{
1070
+ type: Output
1071
+ }], contentContainer: [{
1072
+ type: ViewChild,
1073
+ args: ['container', { static: true }]
1074
+ }], resizeSensor: [{
1075
+ type: ViewChild,
1076
+ args: [ResizeSensorComponent, { static: true }]
1077
+ }] } });
1078
+
1079
+ const removeElement = (element) => {
1080
+ if (element && element.parentNode) {
1081
+ element.parentNode.removeChild(element);
1082
+ }
1083
+ };
1084
+ /**
1085
+ * Used to inject the Popup container. If not provided, the first root component of
1086
+ * the application is used.
1087
+ *
1088
+ * > The `POPUP_CONTAINER` can be used only with the [`PopupService`]({% slug service_popup %}) class.
1089
+ *
1090
+ * @example
1091
+ *
1092
+ * ```ts-no-run
1093
+ * // Import the Popup module
1094
+ * import { PopupModule, POPUP_CONTAINER } from '@progress/kendo-angular-popup';
1095
+ *
1096
+ * // The browser platform with a compiler
1097
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
1098
+ *
1099
+ * import { ElementRef, NgModule } from '@angular/core';
1100
+ *
1101
+ * // Import the app component
1102
+ * import { AppComponent } from './app.component';
1103
+ *
1104
+ * // Define the app module
1105
+ * _@NgModule({
1106
+ * declarations: [AppComponent], // declare app component
1107
+ * imports: [BrowserModule, PopupModule], // import Popup module
1108
+ * bootstrap: [AppComponent],
1109
+ * providers: [{
1110
+ * provide: POPUP_CONTAINER,
1111
+ * useFactory: () => {
1112
+ * //return the container ElementRef, where the popup will be injected
1113
+ * return { nativeElement: document.body } as ElementRef;
1114
+ * }
1115
+ * }]
1116
+ * })
1117
+ * export class AppModule {}
1118
+ *
1119
+ * // Compile and launch the module
1120
+ * platformBrowserDynamic().bootstrapModule(AppModule);
1121
+ * ```
1122
+ */
1123
+ const POPUP_CONTAINER = new InjectionToken('Popup Container');
1124
+ /**
1125
+ * A service for opening Popup components dynamically
1126
+ * ([see example]({% slug service_popup %})).
1127
+ *
1128
+ * @export
1129
+ * @class PopupService
1130
+ */
1131
+ class PopupService {
1132
+ constructor(applicationRef, componentFactoryResolver, injector, container) {
1133
+ this.applicationRef = applicationRef;
1134
+ this.componentFactoryResolver = componentFactoryResolver;
1135
+ this.injector = injector;
1136
+ this.container = container;
1137
+ }
1138
+ /**
1139
+ * Gets the root view container into which the component will be injected.
1140
+ *
1141
+ * @returns {ComponentRef<any>}
1142
+ */
1143
+ get rootViewContainer() {
1144
+ // https://github.com/angular/angular/blob/4.0.x/packages/core/src/application_ref.ts#L571
1145
+ const rootComponents = this.applicationRef.components || [];
1146
+ if (rootComponents[0]) {
1147
+ return rootComponents[0];
1148
+ }
1149
+ throw new Error(`
1150
+ View Container not found! Inject the POPUP_CONTAINER or define a specific ViewContainerRef via the appendTo option.
1151
+ See http://www.telerik.com/kendo-angular-ui/components/popup/api/POPUP_CONTAINER/ for more details.
1152
+ `);
1153
+ }
1154
+ /**
1155
+ * Sets or gets the HTML element of the root component container.
1156
+ *
1157
+ * @returns {HTMLElement}
1158
+ */
1159
+ get rootViewContainerNode() {
1160
+ return this.container ? this.container.nativeElement : this.getComponentRootNode(this.rootViewContainer);
1161
+ }
1162
+ /**
1163
+ * Opens a Popup component. Created Popups are mounted
1164
+ * in the DOM directly in the root application component.
1165
+ *
1166
+ * @param {PopupSettings} options - The options which define the Popup.
1167
+ * @returns {ComponentRef<PopupComponent>} - A reference to the Popup object.
1168
+ *
1169
+ * @example
1170
+ *
1171
+ * ```ts-no-run
1172
+ * _@Component({
1173
+ * selector: 'my-app',
1174
+ * template: `
1175
+ * <ng-template #template>
1176
+ * Popup content
1177
+ * </ng-template>
1178
+ * <button #anchor kendoButton (click)="open(anchor, template)">Open</button>
1179
+ * `
1180
+ * })
1181
+ * export class AppComponent {
1182
+ * public popupRef: PopupRef;
1183
+ *
1184
+ * constructor( private popupService: PopupService ) {}
1185
+ *
1186
+ * public open(anchor: ElementRef, template: TemplateRef<any>): void {
1187
+ * if (this.popupRef) {
1188
+ * this.popupRef.close();
1189
+ * this.popupRef = null;
1190
+ * return;
1191
+ * }
1192
+ *
1193
+ * this.popupRef = this.popupService.open({
1194
+ * anchor: anchor,
1195
+ * content: template
1196
+ * });
1197
+ * }
1198
+ * }
1199
+ * ```
1200
+ */
1201
+ open(options = {}) {
1202
+ const { component, nodes } = this.contentFrom(options.content);
1203
+ const popupComponentRef = this.appendPopup(nodes, options.appendTo);
1204
+ const popupInstance = popupComponentRef.instance;
1205
+ this.projectComponentInputs(popupComponentRef, options);
1206
+ popupComponentRef.changeDetectorRef.detectChanges();
1207
+ if (component) {
1208
+ component.changeDetectorRef.detectChanges();
1209
+ }
1210
+ const popupElement = this.getComponentRootNode(popupComponentRef);
1211
+ return {
1212
+ close: () => {
1213
+ if (component) {
1214
+ component.destroy();
1215
+ }
1216
+ popupComponentRef.destroy();
1217
+ // Angular will not remove the element unless the change detection is triggered
1218
+ removeElement(popupElement);
1219
+ },
1220
+ content: component,
1221
+ popup: popupComponentRef,
1222
+ popupAnchorViewportLeave: popupInstance.anchorViewportLeave,
1223
+ popupClose: popupInstance.close,
1224
+ popupElement: popupElement,
1225
+ popupOpen: popupInstance.open,
1226
+ popupPositionChange: popupInstance.positionChange
1227
+ };
1228
+ }
1229
+ appendPopup(nodes, container) {
1230
+ const popupComponentRef = this.createComponent(PopupComponent, nodes, container);
1231
+ if (!container) {
1232
+ this.rootViewContainerNode.appendChild(this.getComponentRootNode(popupComponentRef));
1233
+ }
1234
+ return popupComponentRef;
1235
+ }
1236
+ /**
1237
+ * Gets the HTML element for a component reference.
1238
+ *
1239
+ * @param {ComponentRef<any>} componentRef
1240
+ * @returns {HTMLElement}
1241
+ */
1242
+ getComponentRootNode(componentRef) {
1243
+ return componentRef.location.nativeElement;
1244
+ }
1245
+ /**
1246
+ * Gets the `ComponentFactory` instance by its type.
1247
+ *
1248
+ * @param {*} componentClass
1249
+ * @param {*} nodes
1250
+ * @returns {ComponentRef<any>}
1251
+ */
1252
+ getComponentFactory(componentClass) {
1253
+ return this.componentFactoryResolver.resolveComponentFactory(componentClass);
1254
+ }
1255
+ /**
1256
+ * Creates a component reference from a `Component` type class.
1257
+ *
1258
+ * @param {*} componentClass
1259
+ * @param {*} nodes
1260
+ * @returns {ComponentRef<any>}
1261
+ */
1262
+ createComponent(componentClass, nodes, container) {
1263
+ const factory = this.getComponentFactory(componentClass);
1264
+ if (container) {
1265
+ return container.createComponent(factory, undefined, this.injector, nodes);
1266
+ }
1267
+ else {
1268
+ const component = factory.create(this.injector, nodes);
1269
+ this.applicationRef.attachView(component.hostView);
1270
+ return component;
1271
+ }
1272
+ }
1273
+ /**
1274
+ * Projects the inputs on the component.
1275
+ *
1276
+ * @param {ComponentRef<any>} component
1277
+ * @param {*} options
1278
+ * @returns {ComponentRef<any>}
1279
+ */
1280
+ projectComponentInputs(component, options) {
1281
+ Object.getOwnPropertyNames(options)
1282
+ .filter(prop => prop !== 'content' || options.content instanceof TemplateRef)
1283
+ .map((prop) => {
1284
+ component.instance[prop] = options[prop];
1285
+ });
1286
+ return component;
1287
+ }
1288
+ /**
1289
+ * Gets the component and the nodes to append from the `content` option.
1290
+ *
1291
+ * @param {*} content
1292
+ * @returns {any}
1293
+ */
1294
+ contentFrom(content) {
1295
+ if (!content || content instanceof TemplateRef) {
1296
+ return { component: null, nodes: [[]] };
1297
+ }
1298
+ const component = this.createComponent(content);
1299
+ const nodes = component ? [component.location.nativeElement] : [];
1300
+ return {
1301
+ component: component,
1302
+ nodes: [
1303
+ nodes // <ng-content>
1304
+ ]
1305
+ };
1306
+ }
1307
+ }
1308
+ PopupService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupService, deps: [{ token: i0.ApplicationRef }, { token: i0.ComponentFactoryResolver }, { token: i0.Injector }, { token: POPUP_CONTAINER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1309
+ PopupService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupService });
1310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupService, decorators: [{
1311
+ type: Injectable
1312
+ }], ctorParameters: function () {
1313
+ return [{ type: i0.ApplicationRef }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: i0.ElementRef, decorators: [{
1314
+ type: Inject,
1315
+ args: [POPUP_CONTAINER]
1316
+ }, {
1317
+ type: Optional
1318
+ }] }];
1319
+ } });
1320
+
1321
+ const POPUP_DIRECTIVES = [PopupComponent];
1322
+ /**
1323
+ * Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
1324
+ * definition for the Popup component.
1325
+ *
1326
+ * @example
1327
+ *
1328
+ * ```ts-no-run
1329
+ * // Import the Popup module
1330
+ * import { PopupModule } from '@progress/kendo-angular-popup';
1331
+ *
1332
+ * // The browser platform with a compiler
1333
+ * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
1334
+ *
1335
+ * import { NgModule } from '@angular/core';
1336
+ *
1337
+ * // Import the app component
1338
+ * import { AppComponent } from './app.component';
1339
+ *
1340
+ * // Define the app module
1341
+ * _@NgModule({
1342
+ * declarations: [AppComponent], // declare app component
1343
+ * imports: [BrowserModule, PopupModule], // import Popup module
1344
+ * bootstrap: [AppComponent]
1345
+ * })
1346
+ * export class AppModule {}
1347
+ *
1348
+ * // Compile and launch the module
1349
+ * platformBrowserDynamic().bootstrapModule(AppModule);
1350
+ *
1351
+ * ```
1352
+ */
1353
+ class PopupModule {
1354
+ }
1355
+ PopupModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1356
+ PopupModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupModule, declarations: [PopupComponent], imports: [CommonModule, ResizeSensorModule], exports: [PopupComponent] });
1357
+ PopupModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupModule, providers: [PopupService], imports: [[CommonModule, ResizeSensorModule]] });
1358
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PopupModule, decorators: [{
1359
+ type: NgModule,
1360
+ args: [{
1361
+ declarations: [POPUP_DIRECTIVES],
1362
+ entryComponents: [POPUP_DIRECTIVES],
1363
+ exports: [POPUP_DIRECTIVES],
1364
+ imports: [CommonModule, ResizeSensorModule],
1365
+ providers: [PopupService]
1366
+ }]
1367
+ }] });
1368
+
1369
+ /**
1370
+ * Generated bundle index. Do not edit.
1371
+ */
1372
+
1373
+ export { POPUP_CONTAINER, PopupComponent, PopupModule, PopupService, SCALE };
1374
+