@a11y-ngx/overlay-base 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1477 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators')) :
3
+ typeof define === 'function' && define.amd ? define('@a11y-ngx/overlay-base', ['exports', 'rxjs', 'rxjs/operators'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.a11yNGx = global.a11yNGx || {}, global.a11yNGx.overlayBase = {}), global.rxjs, global.rxjs.operators));
5
+ })(this, (function (exports, rxjs, operators) { 'use strict';
6
+
7
+ exports.POSITION = void 0;
8
+ (function (POSITION) {
9
+ POSITION["TOP"] = "top";
10
+ POSITION["BOTTOM"] = "bottom";
11
+ POSITION["LEFT"] = "left";
12
+ POSITION["RIGHT"] = "right";
13
+ })(exports.POSITION || (exports.POSITION = {}));
14
+ exports.ALIGNMENT = void 0;
15
+ (function (ALIGNMENT) {
16
+ ALIGNMENT["START"] = "start";
17
+ ALIGNMENT["END"] = "end";
18
+ ALIGNMENT["CENTER"] = "center";
19
+ })(exports.ALIGNMENT || (exports.ALIGNMENT = {}));
20
+ exports.POSITION_STRATEGY = void 0;
21
+ (function (POSITION_STRATEGY) {
22
+ POSITION_STRATEGY["FIXED"] = "fixed";
23
+ POSITION_STRATEGY["ABSOLUTE"] = "absolute";
24
+ })(exports.POSITION_STRATEGY || (exports.POSITION_STRATEGY = {}));
25
+ var OVERLAY_BASE_DEFAULTS = {
26
+ offsetSize: 5,
27
+ fluidAlignment: false,
28
+ fluidSize: true,
29
+ position: [exports.POSITION.TOP, exports.ALIGNMENT.CENTER],
30
+ positionStrategy: exports.POSITION_STRATEGY.FIXED,
31
+ positionsAllowed: [exports.POSITION.TOP, exports.POSITION.BOTTOM, exports.POSITION.LEFT, exports.POSITION.RIGHT],
32
+ alignmentsAllowed: [exports.ALIGNMENT.CENTER, exports.ALIGNMENT.START, exports.ALIGNMENT.END],
33
+ safeSpace: { top: 0, bottom: 0, left: 0, right: 0 },
34
+ allowScrollListener: true,
35
+ };
36
+
37
+ var formatConsoleMsg = function (msg) { return msg.replace(/ {2,}/g, ''); };
38
+ var ERROR_NO_TRIGGER_PROVIDED = function () {
39
+ var msg = "\n A11y Overlay Base:\n No Trigger element or DOMRect provided!\n ";
40
+ return formatConsoleMsg(msg);
41
+ };
42
+
43
+ var uid = 0;
44
+ var OverlayBase = /** @class */ (function () {
45
+ function OverlayBase() {
46
+ var _this = this;
47
+ this.uid = uid++;
48
+ this.overlayConfig = {};
49
+ this.boundaryRect = new DOMRect(0, 0, this.viewportSize.width, this.viewportSize.height);
50
+ this.isAttached = false;
51
+ this.resize$ = new rxjs.Subject();
52
+ this.resizeFn = function () { return _this.resize$.next(); };
53
+ this.scroll$ = new rxjs.Subject();
54
+ this.scrollFn = function () { return _this.scroll$.next(); };
55
+ this.boundaryScroll$ = new rxjs.Subject();
56
+ this.boundaryScrollFn = function () { return _this.boundaryScroll$.next(); };
57
+ /**
58
+ * @description
59
+ * Allowed Positions & Alignments provided by the user.
60
+ */
61
+ this.allowed = {
62
+ positions: OVERLAY_BASE_DEFAULTS.positionsAllowed,
63
+ alignments: OVERLAY_BASE_DEFAULTS.alignmentsAllowed,
64
+ };
65
+ /**
66
+ * @description
67
+ * An array of the listeners (for repositioning purposes).
68
+ */
69
+ this.listeners = [];
70
+ /**
71
+ * @description
72
+ * To allow listening on page scrolling for repositioning.
73
+ */
74
+ this.allowScrollListener = true;
75
+ /**
76
+ * @description
77
+ * Max `width` & `height` values allowed for the Overlay to perform
78
+ * proper calculations in case `fluidSize` is active.
79
+ */
80
+ this.maxSize = {
81
+ width: null,
82
+ height: null,
83
+ };
84
+ /**
85
+ * @description
86
+ * This will provide the side of the Viewport/Boundary where the Overlay would be out of
87
+ * in case `fluidAlignment` is active and the Overlay, by the chosen alignment, is out of the visible area.
88
+ */
89
+ this.overlayOutside = undefined;
90
+ }
91
+ Object.defineProperty(OverlayBase.prototype, "viewportSize", {
92
+ /**
93
+ * @description
94
+ * The Viewport size (without the scrollbars into consideration).
95
+ */
96
+ get: function () {
97
+ return {
98
+ width: document.documentElement.clientWidth,
99
+ height: document.documentElement.clientHeight,
100
+ };
101
+ },
102
+ enumerable: false,
103
+ configurable: true
104
+ });
105
+ Object.defineProperty(OverlayBase.prototype, "viewportSizeSafe", {
106
+ /**
107
+ * @description
108
+ * The Viewport safe size.
109
+ * This will return width/height values taking into consideration a given custom Boundary and/or Safe Space.
110
+ */
111
+ get: function () {
112
+ return this.viewportSafe;
113
+ },
114
+ enumerable: false,
115
+ configurable: true
116
+ });
117
+ Object.defineProperty(OverlayBase.prototype, "getCurrentPosition", {
118
+ /**
119
+ * @description
120
+ * The chosen Position by the calculations.
121
+ */
122
+ get: function () {
123
+ return this.currentPosition;
124
+ },
125
+ enumerable: false,
126
+ configurable: true
127
+ });
128
+ Object.defineProperty(OverlayBase.prototype, "getCurrentAlignment", {
129
+ /**
130
+ * @description
131
+ * The chosen Alignment by the calculations.
132
+ */
133
+ get: function () {
134
+ return this.currentAlignment;
135
+ },
136
+ enumerable: false,
137
+ configurable: true
138
+ });
139
+ /**
140
+ * @description
141
+ * Checks that either TOP or BOTTOM positions are inside or outside the visible area.
142
+ *
143
+ * @param { number } valueTop - The numeric value for TOP position.
144
+ * @param { number } valueBottom - The numeric value for BOTTOM position.
145
+ */
146
+ OverlayBase.prototype.overlayOutsideCheckY = function (valueTop, valueBottom) {
147
+ this.overlayOutside = valueTop < 0 ? exports.POSITION.TOP : valueBottom < 0 ? exports.POSITION.BOTTOM : undefined;
148
+ };
149
+ /**
150
+ * @description
151
+ * Checks that either LEFT or RIGHT positions are inside or outside the visible area.
152
+ *
153
+ * @param { number } valueLeft - The numeric value for LEFT position.
154
+ * @param { number } valueRight - The numeric value for RIGHT position.
155
+ */
156
+ OverlayBase.prototype.overlayOutsideCheckX = function (valueLeft, valueRight) {
157
+ this.overlayOutside = valueLeft < 0 ? exports.POSITION.LEFT : valueRight < 0 ? exports.POSITION.RIGHT : undefined;
158
+ };
159
+ Object.defineProperty(OverlayBase.prototype, "triggerElement", {
160
+ /**
161
+ * @description
162
+ * The Trigger element to which the Overlay will be attached to.
163
+ */
164
+ get: function () {
165
+ return this.overlayConfig.trigger;
166
+ },
167
+ set: function (triggerElement) {
168
+ this.overlayConfig.trigger = triggerElement;
169
+ },
170
+ enumerable: false,
171
+ configurable: true
172
+ });
173
+ Object.defineProperty(OverlayBase.prototype, "overlayElement", {
174
+ /**
175
+ * @description
176
+ * The Overlay element.
177
+ */
178
+ get: function () {
179
+ return this.overlayMainElement;
180
+ },
181
+ set: function (overlayElement) {
182
+ var overlayInnerElement = overlayElement === null || overlayElement === void 0 ? void 0 : overlayElement.querySelector('[overlay-wrapper]');
183
+ this.overlayMainElement = (overlayInnerElement || overlayElement);
184
+ },
185
+ enumerable: false,
186
+ configurable: true
187
+ });
188
+ Object.defineProperty(OverlayBase.prototype, "overlayPosition", {
189
+ /**
190
+ * @description
191
+ * Process and save the desired position & alignment.
192
+ */
193
+ set: function (position) {
194
+ var _a, _b, _c, _d, _e, _f;
195
+ var defaultValues = OVERLAY_BASE_DEFAULTS.position;
196
+ if (!position)
197
+ position = [undefined, undefined];
198
+ if (typeof position === 'string') {
199
+ position = position.split('-').map(function (pos) { return pos.toLowerCase().trim(); });
200
+ }
201
+ if (!position[0])
202
+ position[0] = (_b = (_a = this.desiredPosition) !== null && _a !== void 0 ? _a : this.allowed.positions[0]) !== null && _b !== void 0 ? _b : defaultValues[0];
203
+ if (!position[1])
204
+ position[1] = (_d = (_c = this.desiredAlignment) !== null && _c !== void 0 ? _c : this.allowed.alignments[0]) !== null && _d !== void 0 ? _d : defaultValues[1];
205
+ var isValidPosition = this.isValidPosition(position[0]) && this.isPositionAllowed(position[0]);
206
+ this.desiredPosition = isValidPosition ? position[0] : (_e = this.allowed.positions[0]) !== null && _e !== void 0 ? _e : exports.POSITION.TOP;
207
+ var isValidAlignment = this.isValidAlignment(position[1]) && this.isAlignmentAllowed(position[1]);
208
+ var defaultAlignment = this.isAlignmentCenterAllowed
209
+ ? exports.ALIGNMENT.CENTER
210
+ : exports.ALIGNMENT.START;
211
+ this.desiredAlignment = isValidAlignment ? position[1] : (_f = this.allowed.alignments[0]) !== null && _f !== void 0 ? _f : defaultAlignment;
212
+ },
213
+ enumerable: false,
214
+ configurable: true
215
+ });
216
+ /**
217
+ * @description
218
+ * Verifies if the given position is a valid value.
219
+ *
220
+ * @param { string } position - A given position (top, bottom, left, right).
221
+ * @returns { boolean }
222
+ */
223
+ OverlayBase.prototype.isValidPosition = function (position) {
224
+ return Object.values(exports.POSITION).includes(position);
225
+ };
226
+ /**
227
+ * @description
228
+ * Verifies if the given alignment is a valid value.
229
+ *
230
+ * @param { string } alignment - A given alignment (start, center, end).
231
+ * @returns { boolean }
232
+ */
233
+ OverlayBase.prototype.isValidAlignment = function (alignment) {
234
+ return Object.values(exports.ALIGNMENT).includes(alignment);
235
+ };
236
+ Object.defineProperty(OverlayBase.prototype, "positionStrategy", {
237
+ /**
238
+ * @description
239
+ * The position strategy to use (Fixed or Absolute).
240
+ */
241
+ get: function () {
242
+ var _a;
243
+ return ((_a = this.overlayConfig.positionStrategy) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.positionStrategy);
244
+ },
245
+ set: function (positionStrategy) {
246
+ positionStrategy = positionStrategy === null || positionStrategy === void 0 ? void 0 : positionStrategy.toLowerCase().trim();
247
+ this.overlayConfig.positionStrategy = Object.values(exports.POSITION_STRATEGY).includes(positionStrategy)
248
+ ? positionStrategy
249
+ : OVERLAY_BASE_DEFAULTS.positionStrategy;
250
+ },
251
+ enumerable: false,
252
+ configurable: true
253
+ });
254
+ Object.defineProperty(OverlayBase.prototype, "positionsAllowed", {
255
+ /**
256
+ * @description
257
+ * Sets the allowed positions.
258
+ */
259
+ set: function (allowed) {
260
+ if (typeof allowed === 'string')
261
+ allowed = allowed.split(',');
262
+ allowed = allowed
263
+ .map(function (position) { return position.toLowerCase().trim(); })
264
+ .filter(this.isValidPosition);
265
+ this.allowed.positions = allowed.length
266
+ ? allowed
267
+ : OVERLAY_BASE_DEFAULTS.positionsAllowed;
268
+ },
269
+ enumerable: false,
270
+ configurable: true
271
+ });
272
+ Object.defineProperty(OverlayBase.prototype, "oppositePositionsAllowed", {
273
+ /**
274
+ * @description
275
+ * Sets the allowed opposite positions.
276
+ */
277
+ set: function (position) {
278
+ var _a, _b;
279
+ position = (_a = position !== null && position !== void 0 ? position : this.desiredPosition) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.position;
280
+ if (typeof position === 'string')
281
+ position = position.split('-');
282
+ if (!this.isValidPosition(position[0]))
283
+ position[0] = (_b = this.desiredPosition) !== null && _b !== void 0 ? _b : exports.POSITION.TOP;
284
+ var opposites = {
285
+ top: exports.POSITION.BOTTOM,
286
+ bottom: exports.POSITION.TOP,
287
+ left: exports.POSITION.RIGHT,
288
+ right: exports.POSITION.LEFT,
289
+ };
290
+ this.allowed.positions = [position[0], opposites[position[0]]];
291
+ },
292
+ enumerable: false,
293
+ configurable: true
294
+ });
295
+ /**
296
+ * @description
297
+ * Verifies if the given position is allowed.
298
+ *
299
+ * @param { string } position - A given position (top, bottom, left, right).
300
+ * @returns { boolean }
301
+ */
302
+ OverlayBase.prototype.isPositionAllowed = function (position) {
303
+ return this.allowed.positions.includes(position);
304
+ };
305
+ Object.defineProperty(OverlayBase.prototype, "alignmentsAllowed", {
306
+ /**
307
+ * @description
308
+ * Sets the allowed alignments.
309
+ */
310
+ set: function (allowed) {
311
+ if (allowed === 'edges') {
312
+ this.allowed.alignments = [exports.ALIGNMENT.START, exports.ALIGNMENT.END];
313
+ }
314
+ else if (allowed === 'center' && this.fluidAlignment) {
315
+ this.allowed.alignments = [exports.ALIGNMENT.CENTER];
316
+ }
317
+ else {
318
+ if (typeof allowed === 'string')
319
+ allowed = allowed.split(',');
320
+ allowed = allowed
321
+ .map(function (alignment) { return alignment.toLowerCase().trim(); })
322
+ .filter(this.isValidAlignment);
323
+ this.allowed.alignments = allowed.length
324
+ ? allowed
325
+ : OVERLAY_BASE_DEFAULTS.alignmentsAllowed;
326
+ }
327
+ },
328
+ enumerable: false,
329
+ configurable: true
330
+ });
331
+ /**
332
+ * @description
333
+ * Verifies if the given alignment is allowed.
334
+ *
335
+ * @param { string } alignment - A given alignment (start, center, end).
336
+ * @returns { boolean }
337
+ */
338
+ OverlayBase.prototype.isAlignmentAllowed = function (alignment) {
339
+ return this.allowed.alignments.includes(alignment);
340
+ };
341
+ Object.defineProperty(OverlayBase.prototype, "isAlignmentStartAllowed", {
342
+ get: function () {
343
+ return this.isAlignmentAllowed(exports.ALIGNMENT.START);
344
+ },
345
+ enumerable: false,
346
+ configurable: true
347
+ });
348
+ Object.defineProperty(OverlayBase.prototype, "isAlignmentCenterAllowed", {
349
+ get: function () {
350
+ return this.isAlignmentAllowed(exports.ALIGNMENT.CENTER);
351
+ },
352
+ enumerable: false,
353
+ configurable: true
354
+ });
355
+ Object.defineProperty(OverlayBase.prototype, "isAlignmentEndAllowed", {
356
+ get: function () {
357
+ return this.isAlignmentAllowed(exports.ALIGNMENT.END);
358
+ },
359
+ enumerable: false,
360
+ configurable: true
361
+ });
362
+ Object.defineProperty(OverlayBase.prototype, "isAlignmentCenterOnly", {
363
+ get: function () {
364
+ return this.allowed.alignments.length === 1 && this.allowed.alignments[0] === exports.ALIGNMENT.CENTER;
365
+ },
366
+ enumerable: false,
367
+ configurable: true
368
+ });
369
+ Object.defineProperty(OverlayBase.prototype, "isDesiredAlignmentStart", {
370
+ get: function () {
371
+ return this.desiredAlignment === exports.ALIGNMENT.START;
372
+ },
373
+ enumerable: false,
374
+ configurable: true
375
+ });
376
+ Object.defineProperty(OverlayBase.prototype, "isDesiredAlignmentCenter", {
377
+ get: function () {
378
+ return this.desiredAlignment === exports.ALIGNMENT.CENTER;
379
+ },
380
+ enumerable: false,
381
+ configurable: true
382
+ });
383
+ Object.defineProperty(OverlayBase.prototype, "isDesiredAlignmentEnd", {
384
+ get: function () {
385
+ return this.desiredAlignment === exports.ALIGNMENT.END;
386
+ },
387
+ enumerable: false,
388
+ configurable: true
389
+ });
390
+ Object.defineProperty(OverlayBase.prototype, "boundaryElement", {
391
+ /**
392
+ * @description
393
+ * Sets a custom Boundary element.
394
+ *
395
+ * @default <body>
396
+ */
397
+ get: function () {
398
+ var _a;
399
+ return (_a = this.overlayConfig.boundary) !== null && _a !== void 0 ? _a : document.body;
400
+ },
401
+ set: function (boundaryElement) {
402
+ this.overlayConfig.boundary = boundaryElement instanceof HTMLElement ? boundaryElement : document.body;
403
+ },
404
+ enumerable: false,
405
+ configurable: true
406
+ });
407
+ Object.defineProperty(OverlayBase.prototype, "isBoundaryCustom", {
408
+ /**
409
+ * @description
410
+ * Checks if the Boundary is the `<body>` or not (custom).
411
+ */
412
+ get: function () {
413
+ return this.boundaryElement.tagName !== 'BODY';
414
+ },
415
+ enumerable: false,
416
+ configurable: true
417
+ });
418
+ Object.defineProperty(OverlayBase.prototype, "safeSpace", {
419
+ /**
420
+ * @description
421
+ * Considers an extra (safe) space for the Viewport.
422
+ */
423
+ get: function () {
424
+ var _a;
425
+ return (_a = this.overlayConfig.safeSpace) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.safeSpace;
426
+ },
427
+ set: function (safeSpace) {
428
+ this.overlayConfig.safeSpace = Object.assign(Object.assign({}, OVERLAY_BASE_DEFAULTS.safeSpace), (safeSpace || {}));
429
+ },
430
+ enumerable: false,
431
+ configurable: true
432
+ });
433
+ Object.defineProperty(OverlayBase.prototype, "offsetSize", {
434
+ /**
435
+ * @description
436
+ * Distance between Trigger & Overlay.
437
+ */
438
+ get: function () {
439
+ var _a;
440
+ return (_a = this.overlayConfig.offsetSize) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.offsetSize;
441
+ },
442
+ set: function (offsetSize) {
443
+ var _a;
444
+ this.overlayConfig.offsetSize = (_a = this.getNumericValue(offsetSize)) !== null && _a !== void 0 ? _a : undefined;
445
+ },
446
+ enumerable: false,
447
+ configurable: true
448
+ });
449
+ Object.defineProperty(OverlayBase.prototype, "fluidAlignment", {
450
+ /**
451
+ * @description
452
+ * Overlay alignment is fluid, it doesn't make jumps between Start, Center or End.
453
+ * The Overlay will stick to the edges of the Viewport/Boundary when reaches any of them.
454
+ */
455
+ get: function () {
456
+ return !!this.overlayConfig.fluidAlignment;
457
+ },
458
+ set: function (fluidAlignment) {
459
+ this.overlayConfig.fluidAlignment = fluidAlignment;
460
+ },
461
+ enumerable: false,
462
+ configurable: true
463
+ });
464
+ Object.defineProperty(OverlayBase.prototype, "fluidSize", {
465
+ /**
466
+ * @description
467
+ * Overlay size is fluid, it will adapt its width (for `left`/`right` positions) or
468
+ * height (for `top`/`bottom` positions) to the available free space.
469
+ *
470
+ * Hand in hand with this, would be good to establish `maxSize` values.
471
+ */
472
+ get: function () {
473
+ var _a;
474
+ return (_a = this.overlayConfig.fluidSize) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.fluidSize;
475
+ },
476
+ set: function (fluidSize) {
477
+ this.overlayConfig.fluidSize = fluidSize;
478
+ },
479
+ enumerable: false,
480
+ configurable: true
481
+ });
482
+ Object.defineProperty(OverlayBase.prototype, "isTop", {
483
+ get: function () {
484
+ return this.currentPosition === exports.POSITION.TOP;
485
+ },
486
+ enumerable: false,
487
+ configurable: true
488
+ });
489
+ Object.defineProperty(OverlayBase.prototype, "isBottom", {
490
+ get: function () {
491
+ return this.currentPosition === exports.POSITION.BOTTOM;
492
+ },
493
+ enumerable: false,
494
+ configurable: true
495
+ });
496
+ Object.defineProperty(OverlayBase.prototype, "isLeft", {
497
+ get: function () {
498
+ return this.currentPosition === exports.POSITION.LEFT;
499
+ },
500
+ enumerable: false,
501
+ configurable: true
502
+ });
503
+ Object.defineProperty(OverlayBase.prototype, "isRight", {
504
+ get: function () {
505
+ return this.currentPosition === exports.POSITION.RIGHT;
506
+ },
507
+ enumerable: false,
508
+ configurable: true
509
+ });
510
+ Object.defineProperty(OverlayBase.prototype, "isStart", {
511
+ get: function () {
512
+ return this.currentAlignment === exports.ALIGNMENT.START;
513
+ },
514
+ enumerable: false,
515
+ configurable: true
516
+ });
517
+ Object.defineProperty(OverlayBase.prototype, "isCenter", {
518
+ get: function () {
519
+ return this.currentAlignment === exports.ALIGNMENT.CENTER;
520
+ },
521
+ enumerable: false,
522
+ configurable: true
523
+ });
524
+ Object.defineProperty(OverlayBase.prototype, "isEnd", {
525
+ get: function () {
526
+ return this.currentAlignment === exports.ALIGNMENT.END;
527
+ },
528
+ enumerable: false,
529
+ configurable: true
530
+ });
531
+ Object.defineProperty(OverlayBase.prototype, "isTopBottom", {
532
+ get: function () {
533
+ return this.isTop || this.isBottom;
534
+ },
535
+ enumerable: false,
536
+ configurable: true
537
+ });
538
+ Object.defineProperty(OverlayBase.prototype, "triggerOverlayDistance", {
539
+ /**
540
+ * @description
541
+ * Distance between Trigger & Overlay.
542
+ */
543
+ get: function () {
544
+ return this.offsetSize;
545
+ },
546
+ enumerable: false,
547
+ configurable: true
548
+ });
549
+ Object.defineProperty(OverlayBase.prototype, "triggerOverlayDifferenceWidth", {
550
+ /**
551
+ * @description
552
+ * Real Width difference between Trigger & Overlay.
553
+ *
554
+ * Positive value means the Overlay is wider than the Trigger.
555
+ */
556
+ get: function () {
557
+ return this.overlayRect.width - this.triggerRect.width;
558
+ },
559
+ enumerable: false,
560
+ configurable: true
561
+ });
562
+ Object.defineProperty(OverlayBase.prototype, "triggerOverlayDifferenceHeight", {
563
+ /**
564
+ * @description
565
+ * Real Height difference between Trigger & Overlay.
566
+ *
567
+ * Positive value means the Overlay is higher than the Trigger.
568
+ */
569
+ get: function () {
570
+ return this.overlayRect.height - this.triggerRect.height;
571
+ },
572
+ enumerable: false,
573
+ configurable: true
574
+ });
575
+ Object.defineProperty(OverlayBase.prototype, "triggerOverlayOriginalDifferenceWidth", {
576
+ /**
577
+ * @description
578
+ * Original Width difference between Trigger & Overlay.
579
+ *
580
+ * Positive value means the Overlay is wider than the Trigger.
581
+ */
582
+ get: function () {
583
+ return this.overlayOriginalRect.width - this.triggerRect.width;
584
+ },
585
+ enumerable: false,
586
+ configurable: true
587
+ });
588
+ Object.defineProperty(OverlayBase.prototype, "triggerOverlayOriginalDifferenceHeight", {
589
+ /**
590
+ * @description
591
+ * Original Height difference between Trigger & Overlay.
592
+ *
593
+ * Positive value means the Overlay is higher than the Trigger.
594
+ */
595
+ get: function () {
596
+ return this.overlayOriginalRect.height - this.triggerRect.height;
597
+ },
598
+ enumerable: false,
599
+ configurable: true
600
+ });
601
+ /**
602
+ * @description
603
+ * Distance between Boundary & Viewport for the given Position.
604
+ *
605
+ * @param { OverlayBasePosition } position - A given position (top, bottom, left, right).
606
+ * @returns { number } The number of pixels between both elements.
607
+ */
608
+ OverlayBase.prototype.boundaryViewportDistance = function (position) {
609
+ var boundarySide = this.boundaryData[position];
610
+ if (position === exports.POSITION.TOP || position === exports.POSITION.LEFT)
611
+ return boundarySide;
612
+ if (position === exports.POSITION.BOTTOM)
613
+ return this.viewportSize.height - boundarySide;
614
+ return this.viewportSize.width - boundarySide; // right
615
+ };
616
+ /**
617
+ * @description
618
+ * Distance between Trigger & Boundary for the given Position.
619
+ * This will take into consideration a given custom Boundary and/or Safe Space.
620
+ *
621
+ * @param { OverlayBasePosition } position - A given position (top, bottom, left, right).
622
+ * @returns { number } The number of pixels between both elements.
623
+ */
624
+ OverlayBase.prototype.triggerBoundaryDistance = function (position) {
625
+ var safeSpace = this.isBoundaryCustom
626
+ ? Math.min(this.boundaryViewportDistance(position) - Number(this.safeSpace[position]), 0) * -1
627
+ : Number(this.safeSpace[position]);
628
+ var triggerPos = this.triggerRect[position];
629
+ var boundaryPos = this.boundaryData[position];
630
+ var distance = position === exports.POSITION.TOP || position === exports.POSITION.LEFT
631
+ ? triggerPos - boundaryPos
632
+ : boundaryPos - triggerPos;
633
+ return distance - safeSpace;
634
+ };
635
+ /**
636
+ * @description
637
+ * Verifies if there is enough vertical/horizontal available space for the Overlay to fit.
638
+ */
639
+ OverlayBase.prototype.enoughAlignmentSpace = function (position) {
640
+ var isTopBottom = position === exports.POSITION.TOP || position === exports.POSITION.BOTTOM;
641
+ return isTopBottom ? this.overlayFitsHorizontally : this.overlayFitsVertically;
642
+ };
643
+ Object.defineProperty(OverlayBase.prototype, "overlayFitsHorizontally", {
644
+ /**
645
+ * @description
646
+ * Verifies if there is enough horizontal available space (horizontal scrolling)
647
+ * for the Overlay to fit.
648
+ */
649
+ get: function () {
650
+ var triggerOverlayDifferenceWidth = this.triggerOverlayOriginalDifferenceWidth;
651
+ var distanceLeft = this.triggerBoundaryDistance(exports.POSITION.LEFT);
652
+ var distanceRight = this.triggerBoundaryDistance(exports.POSITION.RIGHT);
653
+ if (triggerOverlayDifferenceWidth >= 0) {
654
+ return (distanceLeft >= 0 && distanceRight >= 0) || this.allowedOpposite;
655
+ }
656
+ var overlayTriggerDiff = triggerOverlayDifferenceWidth * -1;
657
+ var overlayTriggerDiffHalf = overlayTriggerDiff / 2;
658
+ var canBeStart = distanceLeft > 0 && distanceRight + overlayTriggerDiff > 0;
659
+ var canBeCenter = distanceLeft + overlayTriggerDiffHalf > 0 && distanceRight + overlayTriggerDiffHalf > 0;
660
+ var canBeEnd = distanceLeft + overlayTriggerDiff > 0 && distanceRight > 0;
661
+ var fitsHorizontally = (this.isAlignmentStartAllowed && canBeStart) ||
662
+ (this.isAlignmentCenterAllowed && canBeCenter) ||
663
+ (this.isAlignmentEndAllowed && canBeEnd);
664
+ return fitsHorizontally || this.allowedOpposite;
665
+ },
666
+ enumerable: false,
667
+ configurable: true
668
+ });
669
+ Object.defineProperty(OverlayBase.prototype, "overlayFitsVertically", {
670
+ /**
671
+ * @description
672
+ * Verifies if there is enough vertical available space (vertical scrolling)
673
+ * for the Overlay to fit.
674
+ */
675
+ get: function () {
676
+ var triggerOverlayDifferenceHeight = this.triggerOverlayOriginalDifferenceHeight;
677
+ var distanceTop = this.triggerBoundaryDistance(exports.POSITION.TOP);
678
+ var distanceBottom = this.triggerBoundaryDistance(exports.POSITION.BOTTOM);
679
+ if (triggerOverlayDifferenceHeight >= 0) {
680
+ return (distanceTop >= 0 && distanceBottom >= 0) || this.allowedOpposite;
681
+ }
682
+ var overlayTriggerDiff = triggerOverlayDifferenceHeight * -1;
683
+ var overlayTriggerDiffHalf = overlayTriggerDiff / 2;
684
+ var canBeStart = distanceTop > 0 && distanceBottom + overlayTriggerDiff > 0;
685
+ var canBeCenter = distanceTop + overlayTriggerDiffHalf > 0 && distanceBottom + overlayTriggerDiffHalf > 0;
686
+ var canBeEnd = distanceTop + overlayTriggerDiff > 0 && distanceBottom > 0;
687
+ var fitsVertically = (this.isAlignmentStartAllowed && canBeStart) ||
688
+ (this.isAlignmentCenterAllowed && canBeCenter) ||
689
+ (this.isAlignmentEndAllowed && canBeEnd);
690
+ return fitsVertically || this.allowedOpposite;
691
+ },
692
+ enumerable: false,
693
+ configurable: true
694
+ });
695
+ /**
696
+ * @description
697
+ * Verifies if there is enough free space at the given position for the Overlay to fit.
698
+ *
699
+ * @param { OverlayBasePosition } position - A given position (top, bottom, left, right).
700
+ * @returns { boolean }
701
+ */
702
+ OverlayBase.prototype.enoughBoundarySpace = function (position) {
703
+ var enoughSpace = this.triggerBoundaryDistance(position);
704
+ if (position === exports.POSITION.TOP || position === exports.POSITION.BOTTOM) {
705
+ enoughSpace -= this.overlayOriginalRect.height + this.triggerOverlayDistance;
706
+ }
707
+ else {
708
+ enoughSpace -= this.overlayOriginalRect.width + this.triggerOverlayDistance;
709
+ }
710
+ return enoughSpace - 2 >= 0;
711
+ };
712
+ /**
713
+ * @description
714
+ * Returns if the given Position is allowed and has enough space for the Overlay to fit.
715
+ */
716
+ OverlayBase.prototype.canPositionAt = function (position) {
717
+ var canPositionAt = this.isPositionAllowed(position) &&
718
+ this.enoughBoundarySpace(position) &&
719
+ this.enoughAlignmentSpace(position);
720
+ return canPositionAt ? position : undefined;
721
+ };
722
+ Object.defineProperty(OverlayBase.prototype, "getAlignmentVertically", {
723
+ /**
724
+ * @description
725
+ * Calculates and returns the vertical alignment (for `left`/`right` positions).
726
+ */
727
+ get: function () {
728
+ var overlayTriggerDiff = this.triggerOverlayOriginalDifferenceHeight;
729
+ var overlayTriggerDiffHalf = overlayTriggerDiff / 2;
730
+ if (this.fluidAlignment && overlayTriggerDiff > 0)
731
+ return this.desiredAlignment;
732
+ var distanceTop = this.triggerBoundaryDistance(exports.POSITION.TOP);
733
+ var distanceBottom = this.triggerBoundaryDistance(exports.POSITION.BOTTOM);
734
+ var canBeStart;
735
+ var canBeCentered;
736
+ var canBeEnd;
737
+ if (overlayTriggerDiff > 0) {
738
+ // Overlay is higher than Trigger
739
+ var topSpaceCentered = distanceTop - overlayTriggerDiffHalf > 0 ? distanceTop : 0;
740
+ var bottomSpaceCentered = distanceBottom - overlayTriggerDiffHalf > 0 ? distanceBottom : 0;
741
+ canBeStart = overlayTriggerDiff <= bottomSpaceCentered;
742
+ canBeCentered = overlayTriggerDiffHalf <= topSpaceCentered && overlayTriggerDiffHalf <= bottomSpaceCentered;
743
+ canBeEnd = overlayTriggerDiff <= topSpaceCentered;
744
+ }
745
+ else {
746
+ // Overlay is shorter than Trigger
747
+ overlayTriggerDiff = overlayTriggerDiff * -1;
748
+ overlayTriggerDiffHalf = overlayTriggerDiffHalf * -1;
749
+ canBeStart = distanceTop > 0 && distanceBottom + overlayTriggerDiff > 0;
750
+ canBeCentered = distanceTop + overlayTriggerDiffHalf > 0 && distanceBottom + overlayTriggerDiffHalf > 0;
751
+ canBeEnd = distanceTop + overlayTriggerDiff > 0 && distanceBottom > 0;
752
+ }
753
+ return this.getFinalAlignment(distanceTop, canBeCentered, canBeStart, canBeEnd);
754
+ },
755
+ enumerable: false,
756
+ configurable: true
757
+ });
758
+ Object.defineProperty(OverlayBase.prototype, "getAlignmentHorizontally", {
759
+ /**
760
+ * @description
761
+ * Calculates and return the horizontal alignment (for `top`/`bottom` positions).
762
+ */
763
+ get: function () {
764
+ var overlayTriggerDiff = this.triggerOverlayOriginalDifferenceWidth;
765
+ var overlayTriggerDiffHalf = overlayTriggerDiff / 2;
766
+ if (this.fluidAlignment && overlayTriggerDiff > 0)
767
+ return this.desiredAlignment;
768
+ var distanceLeft = this.triggerBoundaryDistance(exports.POSITION.LEFT);
769
+ var distanceRight = this.triggerBoundaryDistance(exports.POSITION.RIGHT);
770
+ var canBeStart;
771
+ var canBeCentered;
772
+ var canBeEnd;
773
+ if (overlayTriggerDiff > 0) {
774
+ // Overlay is wider than Trigger
775
+ var leftSpaceCentered = distanceLeft - overlayTriggerDiffHalf > 0 ? distanceLeft : 0;
776
+ var rightSpaceCentered = distanceRight - overlayTriggerDiffHalf > 0 ? distanceRight : 0;
777
+ canBeStart = overlayTriggerDiff <= rightSpaceCentered;
778
+ canBeCentered = overlayTriggerDiffHalf <= leftSpaceCentered && overlayTriggerDiffHalf <= rightSpaceCentered;
779
+ canBeEnd = overlayTriggerDiff <= leftSpaceCentered;
780
+ }
781
+ else {
782
+ // Overlay is narrower than Trigger
783
+ overlayTriggerDiff = overlayTriggerDiff * -1;
784
+ overlayTriggerDiffHalf = overlayTriggerDiffHalf * -1;
785
+ canBeStart = distanceLeft > 0 && distanceRight + overlayTriggerDiff > 0;
786
+ canBeCentered = distanceLeft + overlayTriggerDiffHalf > 0 && distanceRight + overlayTriggerDiffHalf > 0;
787
+ canBeEnd = distanceLeft + overlayTriggerDiff > 0 && distanceRight > 0;
788
+ }
789
+ return this.getFinalAlignment(distanceLeft, canBeCentered, canBeStart, canBeEnd);
790
+ },
791
+ enumerable: false,
792
+ configurable: true
793
+ });
794
+ /**
795
+ * @description
796
+ * Calculates the right alignment based on the
797
+ *
798
+ * @param { number } distance - The main distance (`top` for vertical alignment, `left` for horizontal alignment).
799
+ * @param { boolean } canBeCentered - If the Overlay can be aligned to the center.
800
+ * @param { boolean } canBeStart - If the Overlay can be aligned to the start.
801
+ * @param { boolean } canBeEnd - If the Overlay can be aligned to the end.
802
+ * @returns { OverlayBaseAlignment } The alignment.
803
+ */
804
+ OverlayBase.prototype.getFinalAlignment = function (distance, canBeCentered, canBeStart, canBeEnd) {
805
+ var isAlignmentStartAllowed = this.isAlignmentStartAllowed;
806
+ var isAlignmentCenterAllowed = this.isAlignmentCenterAllowed;
807
+ var isAlignmentEndAllowed = this.isAlignmentEndAllowed;
808
+ var isDesiredAllowedAlignmentStart = isAlignmentStartAllowed && this.isDesiredAlignmentStart;
809
+ var isDesiredAllowedAlignmentCenter = isAlignmentCenterAllowed && this.isDesiredAlignmentCenter;
810
+ var isDesiredAllowedAlignmentEnd = isAlignmentEndAllowed && this.isDesiredAlignmentEnd;
811
+ // Check for desired alignment
812
+ if (isDesiredAllowedAlignmentCenter && canBeCentered)
813
+ return exports.ALIGNMENT.CENTER;
814
+ if (isDesiredAllowedAlignmentStart && canBeStart)
815
+ return exports.ALIGNMENT.START;
816
+ if (isDesiredAllowedAlignmentEnd && canBeEnd)
817
+ return exports.ALIGNMENT.END;
818
+ // Check for allowed alignment
819
+ if (isAlignmentCenterAllowed && canBeCentered)
820
+ return exports.ALIGNMENT.CENTER;
821
+ if (isAlignmentStartAllowed && canBeStart)
822
+ return exports.ALIGNMENT.START;
823
+ if (isAlignmentEndAllowed && canBeEnd)
824
+ return exports.ALIGNMENT.END;
825
+ // Check for which edge has more free space
826
+ if (!isAlignmentCenterAllowed && isAlignmentStartAllowed && isAlignmentEndAllowed) {
827
+ return distance > 0 ? exports.ALIGNMENT.START : exports.ALIGNMENT.END;
828
+ }
829
+ // Check the defaults
830
+ if (isAlignmentStartAllowed && !isAlignmentEndAllowed && !isAlignmentCenterAllowed)
831
+ return exports.ALIGNMENT.START;
832
+ if (isAlignmentEndAllowed && !isAlignmentStartAllowed && !isAlignmentCenterAllowed)
833
+ return exports.ALIGNMENT.END;
834
+ return exports.ALIGNMENT.CENTER;
835
+ };
836
+ Object.defineProperty(OverlayBase.prototype, "getMaxSize", {
837
+ /**
838
+ * @description
839
+ * Calculates maximum size (`width` or `height`) in case the overlay does not fit in the screen.
840
+ */
841
+ get: function () {
842
+ var maxSize = { width: null, height: null };
843
+ if (this.fluidSize) {
844
+ var size = this.triggerBoundaryDistance(this.currentPosition) - this.triggerOverlayDistance;
845
+ if (this.isTopBottom) {
846
+ maxSize.height = Math.min(this.maxSize.height || Infinity, size);
847
+ }
848
+ else {
849
+ maxSize.width = Math.min(this.maxSize.width || Infinity, size);
850
+ }
851
+ }
852
+ return maxSize;
853
+ },
854
+ enumerable: false,
855
+ configurable: true
856
+ });
857
+ Object.defineProperty(OverlayBase.prototype, "getCalculatedPosition", {
858
+ /**
859
+ * @description
860
+ * Returns the final Position, Alignment, Render and MaxSize.
861
+ */
862
+ get: function () {
863
+ this.getElementsSizeInfo();
864
+ var isPositionFixed = this.positionStrategy === exports.POSITION_STRATEGY.FIXED;
865
+ var position = this.getPosition;
866
+ this.currentPosition = position;
867
+ var alignment = this.getAlignment;
868
+ this.currentAlignment = alignment;
869
+ var render = Object.assign(Object.assign({}, (isPositionFixed ? this.getFixedY : this.getAbsoluteY)), (isPositionFixed ? this.getFixedX : this.getAbsoluteX));
870
+ var maxSize = this.getMaxSize;
871
+ return { position: position, alignment: alignment, render: render, maxSize: maxSize };
872
+ },
873
+ enumerable: false,
874
+ configurable: true
875
+ });
876
+ Object.defineProperty(OverlayBase.prototype, "getFixedY", {
877
+ /**
878
+ * @description
879
+ * Returns the Overlay's `top` or `bottom` render Position/Alignment for the Strategy FIXED.
880
+ */
881
+ get: function () {
882
+ var posY = { top: null, bottom: null };
883
+ if (this.isTop) {
884
+ posY.bottom = this.viewportSize.height - this.triggerRect.top + this.triggerOverlayDistance;
885
+ }
886
+ else if (this.isBottom) {
887
+ posY.top = this.triggerRect.bottom + this.triggerOverlayDistance;
888
+ }
889
+ else {
890
+ var triggerOverlayDifferenceHeight = this.triggerOverlayDifferenceHeight;
891
+ var triggerOverlayDifferenceHalf = triggerOverlayDifferenceHeight / 2;
892
+ // Fluid Alignment only works for Overlays that are higher than the Trigger
893
+ if (this.fluidAlignment && triggerOverlayDifferenceHeight > 0) {
894
+ var distanceTop = this.triggerBoundaryDistance(exports.POSITION.TOP);
895
+ var distanceBottom = this.triggerBoundaryDistance(exports.POSITION.BOTTOM);
896
+ var overlayTop = void 0;
897
+ var posTop = void 0;
898
+ var posBottom = void 0;
899
+ if (this.isAlignmentCenterOnly || (this.isAlignmentCenterAllowed && this.isCenter)) {
900
+ overlayTop = distanceTop - triggerOverlayDifferenceHalf;
901
+ posTop = this.triggerRect.top - triggerOverlayDifferenceHalf;
902
+ posBottom = distanceBottom - triggerOverlayDifferenceHalf;
903
+ }
904
+ else if (this.isStart) {
905
+ overlayTop = distanceTop;
906
+ posTop = this.triggerRect.top;
907
+ posBottom = distanceBottom - triggerOverlayDifferenceHeight;
908
+ }
909
+ else if (this.isEnd) {
910
+ overlayTop = distanceTop - triggerOverlayDifferenceHeight;
911
+ posTop = this.triggerRect.top - triggerOverlayDifferenceHeight;
912
+ posBottom = distanceBottom;
913
+ }
914
+ this.overlayOutsideCheckY(overlayTop, posBottom);
915
+ if (posBottom > 0) {
916
+ posY.top = Math.max(posTop, this.boundaryViewportDistance(exports.POSITION.TOP), Number(this.safeSpace.top));
917
+ }
918
+ else {
919
+ posY.bottom = Math.max(posBottom, this.boundaryViewportDistance(exports.POSITION.BOTTOM), Number(this.safeSpace.bottom));
920
+ }
921
+ }
922
+ else {
923
+ if (this.isStart) {
924
+ posY.top = this.triggerRect.top;
925
+ }
926
+ else if (this.isEnd) {
927
+ posY.bottom = this.viewportSize.height - this.triggerRect.bottom;
928
+ }
929
+ else {
930
+ posY.top = this.triggerRect.top - triggerOverlayDifferenceHalf;
931
+ }
932
+ }
933
+ }
934
+ return posY;
935
+ },
936
+ enumerable: false,
937
+ configurable: true
938
+ });
939
+ Object.defineProperty(OverlayBase.prototype, "getFixedX", {
940
+ /**
941
+ * @description
942
+ * Returns the Overlay's `left` or `right` render Position/Alignment for the Strategy FIXED.
943
+ */
944
+ get: function () {
945
+ var posX = { left: null, right: null };
946
+ if (this.isLeft) {
947
+ posX.right = this.viewportSize.width - this.triggerRect.left + this.triggerOverlayDistance;
948
+ }
949
+ else if (this.isRight) {
950
+ posX.left = this.triggerRect.right + this.triggerOverlayDistance;
951
+ }
952
+ else {
953
+ var triggerOverlayDifferenceWidth = this.triggerOverlayDifferenceWidth;
954
+ var triggerOverlayDifferenceHalf = triggerOverlayDifferenceWidth / 2;
955
+ // Fluid Alignment only works for Overlays that are wider than the Trigger
956
+ if (this.fluidAlignment && triggerOverlayDifferenceWidth > 0) {
957
+ var distanceLeft = this.triggerBoundaryDistance(exports.POSITION.LEFT);
958
+ var distanceRight = this.triggerBoundaryDistance(exports.POSITION.RIGHT);
959
+ var overlayLeft = void 0;
960
+ var posLeft = void 0;
961
+ var posRight = void 0;
962
+ if (this.isAlignmentCenterOnly || (this.isAlignmentCenterAllowed && this.isCenter)) {
963
+ overlayLeft = distanceLeft - triggerOverlayDifferenceHalf;
964
+ posLeft = this.triggerRect.left - triggerOverlayDifferenceHalf;
965
+ posRight = distanceRight - triggerOverlayDifferenceHalf;
966
+ }
967
+ else if (this.isStart) {
968
+ overlayLeft = distanceLeft;
969
+ posLeft = this.triggerRect.left;
970
+ posRight = distanceRight - triggerOverlayDifferenceWidth;
971
+ }
972
+ else if (this.isEnd) {
973
+ overlayLeft = distanceLeft - triggerOverlayDifferenceWidth;
974
+ posLeft = this.triggerRect.left - triggerOverlayDifferenceWidth;
975
+ posRight = distanceRight;
976
+ }
977
+ this.overlayOutsideCheckX(overlayLeft, posRight);
978
+ if (posRight > 0) {
979
+ posX.left = Math.max(posLeft, this.boundaryViewportDistance(exports.POSITION.LEFT), Number(this.safeSpace.left));
980
+ }
981
+ else {
982
+ posX.right = Math.max(posRight, this.boundaryViewportDistance(exports.POSITION.RIGHT), Number(this.safeSpace.right));
983
+ }
984
+ }
985
+ else {
986
+ if (this.isStart) {
987
+ posX.left = this.triggerRect.left;
988
+ }
989
+ else if (this.isEnd) {
990
+ posX.right = this.viewportSize.width - this.triggerRect.right;
991
+ }
992
+ else {
993
+ posX.left = this.triggerRect.left - triggerOverlayDifferenceHalf;
994
+ }
995
+ }
996
+ }
997
+ return posX;
998
+ },
999
+ enumerable: false,
1000
+ configurable: true
1001
+ });
1002
+ /**
1003
+ * @description
1004
+ * Returns the absolute offset distance for the given position.
1005
+ *
1006
+ * @param { 'left' | 'top' } position - A given position (left, top).
1007
+ * @returns { number } The number of pixels between the chosen side and the Boundary.
1008
+ */
1009
+ OverlayBase.prototype.getAbsoluteOffset = function (position) {
1010
+ var currentEl = this.triggerElement;
1011
+ var offset = 0;
1012
+ do {
1013
+ offset += position === 'top' ? currentEl.offsetTop : currentEl.offsetLeft;
1014
+ currentEl = currentEl.offsetParent;
1015
+ } while (this.boundaryElement.contains(currentEl === null || currentEl === void 0 ? void 0 : currentEl.offsetParent));
1016
+ return offset;
1017
+ };
1018
+ /**
1019
+ * @description
1020
+ * Returns the scroll distance for the given position.
1021
+ *
1022
+ * @param { 'left' | 'top' } position - A given position (left, top).
1023
+ * @returns { number } The number of pixels scrolled on the chosen side for the Boundary.
1024
+ */
1025
+ OverlayBase.prototype.getAbsoluteScroll = function (position) {
1026
+ var scrollElement = !this.isBoundaryCustom ? document.documentElement : this.boundaryElement;
1027
+ return position === 'top' ? scrollElement.scrollTop : scrollElement.scrollLeft;
1028
+ };
1029
+ Object.defineProperty(OverlayBase.prototype, "getAbsoluteY", {
1030
+ /**
1031
+ * @description
1032
+ * Returns the Overlay's `top` or `bottom` render Position/Alignment for the Strategy ABSOLUTE.
1033
+ */
1034
+ get: function () {
1035
+ var posY = { top: null, bottom: null };
1036
+ var offsetPosition = this.getAbsoluteOffset('top');
1037
+ if (this.isTop) {
1038
+ posY.bottom = this.boundaryData.height - offsetPosition + this.triggerOverlayDistance;
1039
+ }
1040
+ else if (this.isBottom) {
1041
+ posY.top = offsetPosition + this.triggerRect.height + this.triggerOverlayDistance;
1042
+ }
1043
+ else {
1044
+ var triggerOverlayDifferenceHeight = this.triggerOverlayDifferenceHeight;
1045
+ var triggerOverlayDifferenceHalf = triggerOverlayDifferenceHeight / 2;
1046
+ // Fluid Alignment only works for Overlays that are higher than the Trigger
1047
+ if (this.fluidAlignment && triggerOverlayDifferenceHeight > 0) {
1048
+ var scrollTop = this.getAbsoluteScroll('top');
1049
+ var distanceTop = this.triggerBoundaryDistance(exports.POSITION.TOP);
1050
+ var distanceBottom = this.triggerBoundaryDistance(exports.POSITION.BOTTOM);
1051
+ var boundaryTop = this.isBoundaryCustom ? this.boundaryRect.top : 0;
1052
+ var boundaryBottom = this.isBoundaryCustom
1053
+ ? this.viewportSize.height - this.boundaryRect.bottom + this.boundaryScrollSize.horizontal
1054
+ : 0;
1055
+ var posTop = void 0;
1056
+ var posBottom = void 0;
1057
+ if (this.isAlignmentCenterOnly || (this.isAlignmentCenterAllowed && this.isCenter)) {
1058
+ posTop = distanceTop - triggerOverlayDifferenceHalf;
1059
+ posBottom = distanceBottom - triggerOverlayDifferenceHalf;
1060
+ }
1061
+ else if (this.isStart) {
1062
+ posTop = distanceTop;
1063
+ posBottom = distanceBottom - triggerOverlayDifferenceHeight;
1064
+ }
1065
+ else if (this.isEnd) {
1066
+ posTop = distanceTop - triggerOverlayDifferenceHeight;
1067
+ posBottom = distanceBottom;
1068
+ }
1069
+ this.overlayOutsideCheckY(posTop, posBottom);
1070
+ if (posBottom > 0) {
1071
+ posY.top =
1072
+ Math.max(posTop + scrollTop, scrollTop) - Math.min(boundaryTop - Number(this.safeSpace.top), 0);
1073
+ }
1074
+ else {
1075
+ posY.bottom = scrollTop * -1 - Math.min(boundaryBottom - Number(this.safeSpace.bottom), 0);
1076
+ }
1077
+ }
1078
+ else {
1079
+ if (this.isStart) {
1080
+ posY.top = offsetPosition;
1081
+ }
1082
+ else if (this.isEnd) {
1083
+ posY.top = offsetPosition - triggerOverlayDifferenceHeight;
1084
+ }
1085
+ else {
1086
+ posY.top = offsetPosition - triggerOverlayDifferenceHalf;
1087
+ }
1088
+ }
1089
+ }
1090
+ return posY;
1091
+ },
1092
+ enumerable: false,
1093
+ configurable: true
1094
+ });
1095
+ Object.defineProperty(OverlayBase.prototype, "getAbsoluteX", {
1096
+ /**
1097
+ * @description
1098
+ * Returns the Overlay's `left` or `right` render Position/Alignment for the Strategy ABSOLUTE.
1099
+ */
1100
+ get: function () {
1101
+ var posX = { left: null, right: null };
1102
+ var offsetPosition = this.getAbsoluteOffset('left');
1103
+ if (this.isLeft) {
1104
+ posX.right = this.boundaryData.width - offsetPosition + this.triggerOverlayDistance;
1105
+ }
1106
+ else if (this.isRight) {
1107
+ posX.left = offsetPosition + this.triggerRect.width + this.triggerOverlayDistance;
1108
+ }
1109
+ else {
1110
+ var triggerOverlayDifferenceWidth = this.triggerOverlayDifferenceWidth;
1111
+ var triggerOverlayDifferenceHalf = triggerOverlayDifferenceWidth / 2;
1112
+ // Fluid Alignment only works for Overlays that are wider than the Trigger
1113
+ if (this.fluidAlignment && triggerOverlayDifferenceWidth > 0) {
1114
+ var scrollLeft = this.getAbsoluteScroll('left');
1115
+ var distanceLeft = this.triggerBoundaryDistance(exports.POSITION.LEFT);
1116
+ var distanceRight = this.triggerBoundaryDistance(exports.POSITION.RIGHT);
1117
+ var boundaryLeft = this.isBoundaryCustom ? this.boundaryRect.left : 0;
1118
+ var boundaryRight = this.isBoundaryCustom
1119
+ ? this.viewportSize.width - this.boundaryRect.right + this.boundaryScrollSize.vertical
1120
+ : 0;
1121
+ var posLeft = void 0;
1122
+ var posRight = void 0;
1123
+ if (this.isAlignmentCenterOnly || (this.isAlignmentCenterAllowed && this.isCenter)) {
1124
+ posLeft = distanceLeft - triggerOverlayDifferenceHalf;
1125
+ posRight = distanceRight - triggerOverlayDifferenceHalf;
1126
+ }
1127
+ else if (this.isStart) {
1128
+ posLeft = distanceLeft;
1129
+ posRight = distanceRight - triggerOverlayDifferenceWidth;
1130
+ }
1131
+ else if (this.isEnd) {
1132
+ posLeft = distanceLeft - triggerOverlayDifferenceWidth;
1133
+ posRight = distanceRight;
1134
+ }
1135
+ this.overlayOutsideCheckX(posLeft, posRight);
1136
+ if (posRight > 0) {
1137
+ posX.left =
1138
+ Math.max(posLeft + scrollLeft, scrollLeft) -
1139
+ Math.min(boundaryLeft - Number(this.safeSpace.left), 0);
1140
+ }
1141
+ else {
1142
+ posX.right = scrollLeft * -1 - Math.min(boundaryRight - Number(this.safeSpace.right), 0);
1143
+ }
1144
+ }
1145
+ else {
1146
+ if (this.isStart) {
1147
+ posX.left = offsetPosition;
1148
+ }
1149
+ else if (this.isEnd) {
1150
+ posX.left = offsetPosition - triggerOverlayDifferenceWidth;
1151
+ }
1152
+ else {
1153
+ posX.left = offsetPosition - triggerOverlayDifferenceHalf;
1154
+ }
1155
+ }
1156
+ }
1157
+ return posX;
1158
+ },
1159
+ enumerable: false,
1160
+ configurable: true
1161
+ });
1162
+ Object.defineProperty(OverlayBase.prototype, "getAutoPosition", {
1163
+ /**
1164
+ * @description
1165
+ * If the Trigger is (at least partially) outside of the Boundary on one or both of its axes
1166
+ * and the viewport size is not big enough to fit the overlay,
1167
+ * it'll choose the side with more available space.
1168
+ */
1169
+ get: function () {
1170
+ var _g;
1171
+ var viewport = this.viewportSizeSafe;
1172
+ var squareAreas = (_g = {},
1173
+ _g[exports.POSITION.TOP] = this.triggerBoundaryDistance(exports.POSITION.TOP) * viewport.width,
1174
+ _g[exports.POSITION.BOTTOM] = this.triggerBoundaryDistance(exports.POSITION.BOTTOM) * viewport.width,
1175
+ _g[exports.POSITION.LEFT] = this.triggerBoundaryDistance(exports.POSITION.LEFT) * viewport.height,
1176
+ _g[exports.POSITION.RIGHT] = this.triggerBoundaryDistance(exports.POSITION.RIGHT) * viewport.height,
1177
+ _g);
1178
+ var maxVisibleArea = -Infinity;
1179
+ var availablePosition;
1180
+ for (var theArea in squareAreas) {
1181
+ var area = theArea;
1182
+ var squareArea = squareAreas[area];
1183
+ if (this.isPositionAllowed(area) && squareArea > maxVisibleArea) {
1184
+ maxVisibleArea = squareArea;
1185
+ availablePosition = area;
1186
+ }
1187
+ }
1188
+ return availablePosition;
1189
+ },
1190
+ enumerable: false,
1191
+ configurable: true
1192
+ });
1193
+ Object.defineProperty(OverlayBase.prototype, "getPosition", {
1194
+ /**
1195
+ * @description
1196
+ * Returns the final position.
1197
+ */
1198
+ get: function () {
1199
+ var position = undefined;
1200
+ var order;
1201
+ if (this.desiredPosition === exports.POSITION.TOP) {
1202
+ order = [exports.POSITION.TOP, exports.POSITION.BOTTOM, exports.POSITION.LEFT, exports.POSITION.RIGHT];
1203
+ }
1204
+ else if (this.desiredPosition === exports.POSITION.BOTTOM) {
1205
+ order = [exports.POSITION.BOTTOM, exports.POSITION.TOP, exports.POSITION.LEFT, exports.POSITION.RIGHT];
1206
+ }
1207
+ else if (this.desiredPosition === exports.POSITION.LEFT) {
1208
+ order = [exports.POSITION.LEFT, exports.POSITION.RIGHT, exports.POSITION.TOP, exports.POSITION.BOTTOM];
1209
+ }
1210
+ else if (this.desiredPosition === exports.POSITION.RIGHT) {
1211
+ order = [exports.POSITION.RIGHT, exports.POSITION.LEFT, exports.POSITION.TOP, exports.POSITION.BOTTOM];
1212
+ }
1213
+ for (var pos = 0; pos < order.length; pos++) {
1214
+ position = this.canPositionAt(order[pos]);
1215
+ if (position)
1216
+ break;
1217
+ }
1218
+ // If no position found, check for best option based on free space
1219
+ return position || this.getAutoPosition;
1220
+ },
1221
+ enumerable: false,
1222
+ configurable: true
1223
+ });
1224
+ Object.defineProperty(OverlayBase.prototype, "getAlignment", {
1225
+ /**
1226
+ * @description
1227
+ * Returns the final alignment.
1228
+ */
1229
+ get: function () {
1230
+ if (this.isTopBottom)
1231
+ return this.getAlignmentHorizontally;
1232
+ return this.getAlignmentVertically;
1233
+ },
1234
+ enumerable: false,
1235
+ configurable: true
1236
+ });
1237
+ Object.defineProperty(OverlayBase.prototype, "overlayListeners$", {
1238
+ /**
1239
+ * @description
1240
+ * Base listeners for Page Scroll, Page Resize, Boundary Scroll & Update on demand.
1241
+ */
1242
+ get: function () {
1243
+ return rxjs.from(this.listeners).pipe(operators.mergeAll());
1244
+ },
1245
+ enumerable: false,
1246
+ configurable: true
1247
+ });
1248
+ /**
1249
+ * @description
1250
+ * Update on demand to return recalculated position/alignment data.
1251
+ */
1252
+ OverlayBase.prototype.recalculate = function () {
1253
+ this.forceUpdate$.next();
1254
+ };
1255
+ /**
1256
+ * @description
1257
+ * Update Overlay ClientRect data on demand in case its content changes.
1258
+ *
1259
+ * This will force recalculations.
1260
+ */
1261
+ OverlayBase.prototype.updateOverlaySize = function () {
1262
+ this.getOverlayOriginalClientRect(true);
1263
+ this.recalculate();
1264
+ };
1265
+ /**
1266
+ * @description
1267
+ * Sets / updates the basic config.
1268
+ */
1269
+ OverlayBase.prototype.setBaseConfig = function (customConfig) {
1270
+ var _a, _b, _c;
1271
+ if (!customConfig)
1272
+ return;
1273
+ if ('trigger' in customConfig) {
1274
+ if (customConfig.trigger instanceof HTMLElement) {
1275
+ this.triggerElement = customConfig.trigger;
1276
+ }
1277
+ else {
1278
+ this.virtualTriggerRect = customConfig.trigger;
1279
+ }
1280
+ }
1281
+ if ('fluidAlignment' in customConfig)
1282
+ this.fluidAlignment = (_a = this.getBooleanValue(customConfig.fluidAlignment)) !== null && _a !== void 0 ? _a : OVERLAY_BASE_DEFAULTS.fluidAlignment;
1283
+ if ('fluidSize' in customConfig)
1284
+ this.fluidSize = (_b = this.getBooleanValue(customConfig.fluidSize)) !== null && _b !== void 0 ? _b : OVERLAY_BASE_DEFAULTS.fluidSize;
1285
+ if ('alignmentsAllowed' in customConfig)
1286
+ this.alignmentsAllowed = customConfig.alignmentsAllowed;
1287
+ if ('positionsAllowed' in customConfig) {
1288
+ var positionsAllowed = customConfig.positionsAllowed;
1289
+ this.allowedOpposite =
1290
+ typeof positionsAllowed === 'string' && positionsAllowed.toLowerCase().trim() === 'opposite';
1291
+ if (!this.allowedOpposite)
1292
+ this.positionsAllowed = positionsAllowed;
1293
+ }
1294
+ // First input will not have desired position nor alignment.
1295
+ var noDefaultPositionOrAlignment = !this.desiredPosition && !this.desiredAlignment;
1296
+ if (noDefaultPositionOrAlignment || 'position' in customConfig) {
1297
+ if (this.allowedOpposite)
1298
+ this.oppositePositionsAllowed = customConfig.position;
1299
+ this.overlayPosition = customConfig.position;
1300
+ }
1301
+ else {
1302
+ if (this.allowedOpposite) {
1303
+ this.oppositePositionsAllowed = undefined;
1304
+ }
1305
+ else {
1306
+ this.overlayPosition = undefined;
1307
+ }
1308
+ }
1309
+ if ('positionStrategy' in customConfig)
1310
+ this.positionStrategy = customConfig.positionStrategy;
1311
+ if ('boundary' in customConfig)
1312
+ this.boundaryElement = customConfig.boundary;
1313
+ if ('safeSpace' in customConfig)
1314
+ this.safeSpace = customConfig.safeSpace;
1315
+ if ('offsetSize' in customConfig)
1316
+ this.offsetSize = customConfig.offsetSize;
1317
+ if ('allowScrollListener' in customConfig)
1318
+ this.allowScrollListener =
1319
+ (_c = this.getBooleanValue(customConfig.allowScrollListener)) !== null && _c !== void 0 ? _c : OVERLAY_BASE_DEFAULTS.allowScrollListener;
1320
+ };
1321
+ /**
1322
+ * @description
1323
+ * Assigns the provided overlay element and starts listening to the scroll & resize to calculate and return the best position for it.
1324
+ *
1325
+ * @param { HTMLElement } overlayElement - The `overlay` HTML element to base all calculation on.
1326
+ * @param { number } debounceTimeMs - Delay between emissions.
1327
+ * @returns { Observable<OverlayBaseCalculatedPosition> } An `observable` with
1328
+ * - the `position` (top, bottom, left, right),
1329
+ * - the `alignment` (start, center, end),
1330
+ * - the position to `render` (top, bottom, left, right) based on the chosen `position strategy` and
1331
+ * - the `max size` (if "`fluidSize`" is active) that'll provide max width/height so the overlay is always visible on screen.
1332
+ */
1333
+ OverlayBase.prototype.attachOverlay = function (overlayElement, debounceTimeMs) {
1334
+ var _this = this;
1335
+ if (debounceTimeMs === void 0) { debounceTimeMs = 10; }
1336
+ if (!this.isAttached) {
1337
+ this.overlayElement = overlayElement;
1338
+ if (this.isBoundaryCustom) {
1339
+ this.boundaryElement.addEventListener('scroll', this.boundaryScrollFn);
1340
+ }
1341
+ this.forceUpdate$ = new rxjs.BehaviorSubject(undefined);
1342
+ this.isDetached$ = new rxjs.Subject();
1343
+ this.isAttached = true;
1344
+ if (this.allowScrollListener && this.triggerElement) {
1345
+ window.addEventListener('scroll', this.scrollFn);
1346
+ this.listeners.push(this.scroll$);
1347
+ }
1348
+ window.addEventListener('resize', this.resizeFn);
1349
+ this.listeners.push(this.resize$, this.boundaryScroll$, this.forceUpdate$);
1350
+ }
1351
+ return this.overlayListeners$.pipe(operators.debounceTime(debounceTimeMs), operators.map(function () { return _this.getCalculatedPosition; }));
1352
+ };
1353
+ /**
1354
+ * @description
1355
+ * Detaches the Overlay and removes the scroll listener for custom Boundary.
1356
+ */
1357
+ OverlayBase.prototype.detachOverlay = function () {
1358
+ if (!this.isAttached)
1359
+ return;
1360
+ this.isAttached = false;
1361
+ this.isDetached$.next();
1362
+ this.isDetached$.complete();
1363
+ this.forceUpdate$.complete();
1364
+ window.removeEventListener('scroll', this.scrollFn);
1365
+ window.removeEventListener('resize', this.resizeFn);
1366
+ this.listeners.length = 0;
1367
+ if (this.isBoundaryCustom) {
1368
+ this.boundaryElement.removeEventListener('scroll', this.boundaryScrollFn);
1369
+ }
1370
+ };
1371
+ /**
1372
+ * @description
1373
+ * Gets all the necessary ClientRect, Boundary and Viewport data.
1374
+ */
1375
+ OverlayBase.prototype.getElementsSizeInfo = function () {
1376
+ this.getTriggerClientRect();
1377
+ this.getOverlayClientRect();
1378
+ this.getBoundaryClientRect();
1379
+ this.getBoundaryScrollSize();
1380
+ this.getBoundaryCalculatedRect();
1381
+ this.getViewportSizeSafe();
1382
+ };
1383
+ OverlayBase.prototype.getTriggerClientRect = function () {
1384
+ var _a;
1385
+ this.triggerRect = this.virtualTriggerRect || ((_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect());
1386
+ if (!this.triggerRect)
1387
+ throw new Error(ERROR_NO_TRIGGER_PROVIDED());
1388
+ };
1389
+ OverlayBase.prototype.getOverlayClientRect = function () {
1390
+ this.overlayRect = this.overlayElement.getBoundingClientRect();
1391
+ this.getOverlayOriginalClientRect();
1392
+ };
1393
+ OverlayBase.prototype.getOverlayOriginalClientRect = function (forceUpdate) {
1394
+ if (!this.overlayOriginalRect || forceUpdate) {
1395
+ this.overlayOriginalRect = this.overlayElement.getBoundingClientRect();
1396
+ }
1397
+ };
1398
+ OverlayBase.prototype.getBoundaryClientRect = function () {
1399
+ var _a;
1400
+ this.boundaryRect = (_a = this.boundaryElement) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
1401
+ };
1402
+ OverlayBase.prototype.getBoundaryCalculatedRect = function () {
1403
+ var viewportSize = this.viewportSize;
1404
+ var top = 0;
1405
+ var bottom = viewportSize.height;
1406
+ var left = 0;
1407
+ var right = viewportSize.width;
1408
+ var width = viewportSize.width;
1409
+ var height = viewportSize.height;
1410
+ if (this.isBoundaryCustom) {
1411
+ var boundaryBottom = this.boundaryRect.bottom - this.boundaryScrollSize.horizontal;
1412
+ var boundaryRight = this.boundaryRect.right - this.boundaryScrollSize.vertical;
1413
+ height = boundaryBottom - this.boundaryRect.top;
1414
+ width = boundaryRight - this.boundaryRect.left;
1415
+ top = this.boundaryRect.top;
1416
+ left = this.boundaryRect.left;
1417
+ bottom = boundaryBottom;
1418
+ right = boundaryRight;
1419
+ }
1420
+ this.boundaryData = { top: top, bottom: bottom, left: left, right: right, width: width, height: height };
1421
+ };
1422
+ OverlayBase.prototype.getBoundaryScrollSize = function () {
1423
+ var vertical = this.isBoundaryCustom
1424
+ ? this.boundaryElement.offsetWidth - this.boundaryElement.clientWidth
1425
+ : 0;
1426
+ var horizontal = this.isBoundaryCustom
1427
+ ? this.boundaryElement.offsetHeight - this.boundaryElement.clientHeight
1428
+ : 0;
1429
+ this.boundaryScrollSize = { vertical: vertical, horizontal: horizontal };
1430
+ };
1431
+ OverlayBase.prototype.getViewportSizeSafe = function () {
1432
+ var viewportSize = this.viewportSize;
1433
+ this.viewportSafe = {
1434
+ width: viewportSize.width -
1435
+ Math.max(this.boundaryViewportDistance(exports.POSITION.LEFT), Number(this.safeSpace.left)) -
1436
+ Math.max(this.boundaryViewportDistance(exports.POSITION.RIGHT), Number(this.safeSpace.right)),
1437
+ height: viewportSize.height -
1438
+ Math.max(this.boundaryViewportDistance(exports.POSITION.TOP), Number(this.safeSpace.top)) -
1439
+ Math.max(this.boundaryViewportDistance(exports.POSITION.BOTTOM), Number(this.safeSpace.bottom)),
1440
+ };
1441
+ };
1442
+ OverlayBase.prototype.getNumericValue = function (value) {
1443
+ var isNumeric = function (val) {
1444
+ var _a;
1445
+ return ((_a = String(val)) === null || _a === void 0 ? void 0 : _a.trim().length) > 0 && !isNaN(Number(val !== null && val !== void 0 ? val : '!'));
1446
+ };
1447
+ var numericValue = parseFloat(String(value !== null && value !== void 0 ? value : ''));
1448
+ if (!isNumeric(value) || isNaN(numericValue))
1449
+ return null;
1450
+ return numericValue;
1451
+ };
1452
+ OverlayBase.prototype.getBooleanValue = function (value) {
1453
+ var isBoolean = function (val) {
1454
+ var valueStr = String(val).trim();
1455
+ return ['true', 'false'].indexOf(valueStr) !== -1;
1456
+ };
1457
+ try {
1458
+ return isBoolean(value) ? JSON.parse(String(value)) : null;
1459
+ }
1460
+ catch (_a) {
1461
+ return null;
1462
+ }
1463
+ };
1464
+ return OverlayBase;
1465
+ }());
1466
+
1467
+ /**
1468
+ * Generated bundle index. Do not edit.
1469
+ */
1470
+
1471
+ exports.OVERLAY_BASE_DEFAULTS = OVERLAY_BASE_DEFAULTS;
1472
+ exports.OverlayBase = OverlayBase;
1473
+
1474
+ Object.defineProperty(exports, '__esModule', { value: true });
1475
+
1476
+ }));
1477
+ //# sourceMappingURL=a11y-ngx-overlay-base.umd.js.map