@ngbase/adk 0.1.1 → 0.1.2
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.
- package/accordion/accordion-item.d.ts +4 -0
- package/accordion/public-api.d.ts +1 -1
- package/autocomplete/autocomplete.d.ts +2 -2
- package/avatar/avatar.d.ts +1 -1
- package/breadcrumb/breadcrumb.d.ts +2 -3
- package/breadcrumb/public-api.d.ts +1 -1
- package/carousel/carousel.d.ts +1 -1
- package/chip/chip.d.ts +2 -2
- package/datepicker/calendar.d.ts +3 -3
- package/datepicker/datepicker.d.ts +2 -2
- package/datepicker/time.d.ts +2 -2
- package/dialog/dialog.d.ts +1 -1
- package/fesm2022/ngbase-adk-accordion.mjs +4 -1
- package/fesm2022/ngbase-adk-accordion.mjs.map +1 -1
- package/fesm2022/ngbase-adk-autocomplete.mjs +7 -36
- package/fesm2022/ngbase-adk-autocomplete.mjs.map +1 -1
- package/fesm2022/ngbase-adk-avatar.mjs +2 -2
- package/fesm2022/ngbase-adk-avatar.mjs.map +1 -1
- package/fesm2022/ngbase-adk-breadcrumb.mjs +2 -2
- package/fesm2022/ngbase-adk-breadcrumb.mjs.map +1 -1
- package/fesm2022/ngbase-adk-carousel.mjs +2 -2
- package/fesm2022/ngbase-adk-carousel.mjs.map +1 -1
- package/fesm2022/ngbase-adk-chip.mjs +4 -2
- package/fesm2022/ngbase-adk-chip.mjs.map +1 -1
- package/fesm2022/ngbase-adk-datepicker.mjs +114 -328
- package/fesm2022/ngbase-adk-datepicker.mjs.map +1 -1
- package/fesm2022/ngbase-adk-dialog.mjs +12 -13
- package/fesm2022/ngbase-adk-dialog.mjs.map +1 -1
- package/fesm2022/ngbase-adk-form-field.mjs +2 -156
- package/fesm2022/ngbase-adk-form-field.mjs.map +1 -1
- package/fesm2022/ngbase-adk-menu.mjs +15 -30
- package/fesm2022/ngbase-adk-menu.mjs.map +1 -1
- package/fesm2022/ngbase-adk-otp.mjs +164 -0
- package/fesm2022/ngbase-adk-otp.mjs.map +1 -0
- package/fesm2022/ngbase-adk-pagination.mjs +8 -65
- package/fesm2022/ngbase-adk-pagination.mjs.map +1 -1
- package/fesm2022/ngbase-adk-popover.mjs +423 -548
- package/fesm2022/ngbase-adk-popover.mjs.map +1 -1
- package/fesm2022/ngbase-adk-portal.mjs +0 -1
- package/fesm2022/ngbase-adk-portal.mjs.map +1 -1
- package/fesm2022/ngbase-adk-radio.mjs +2 -16
- package/fesm2022/ngbase-adk-radio.mjs.map +1 -1
- package/fesm2022/ngbase-adk-resizable.mjs +10 -43
- package/fesm2022/ngbase-adk-resizable.mjs.map +1 -1
- package/fesm2022/ngbase-adk-select.mjs +67 -173
- package/fesm2022/ngbase-adk-select.mjs.map +1 -1
- package/fesm2022/ngbase-adk-sheet.mjs +95 -0
- package/fesm2022/ngbase-adk-sheet.mjs.map +1 -0
- package/fesm2022/ngbase-adk-sidenav.mjs +2 -2
- package/fesm2022/ngbase-adk-sidenav.mjs.map +1 -1
- package/fesm2022/ngbase-adk-slider.mjs +9 -23
- package/fesm2022/ngbase-adk-slider.mjs.map +1 -1
- package/fesm2022/ngbase-adk-sonner.mjs +13 -63
- package/fesm2022/ngbase-adk-sonner.mjs.map +1 -1
- package/fesm2022/ngbase-adk-stepper.mjs +16 -114
- package/fesm2022/ngbase-adk-stepper.mjs.map +1 -1
- package/fesm2022/ngbase-adk-switch.mjs +2 -2
- package/fesm2022/ngbase-adk-switch.mjs.map +1 -1
- package/fesm2022/ngbase-adk-table.mjs +10 -30
- package/fesm2022/ngbase-adk-table.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tabs.mjs +14 -94
- package/fesm2022/ngbase-adk-tabs.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tooltip.mjs +49 -39
- package/fesm2022/ngbase-adk-tooltip.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tour.mjs +1 -1
- package/fesm2022/ngbase-adk-tour.mjs.map +1 -1
- package/fesm2022/ngbase-adk-tree.mjs +11 -43
- package/fesm2022/ngbase-adk-tree.mjs.map +1 -1
- package/form-field/public-api.d.ts +0 -1
- package/menu/menu-trigger.d.ts +2 -2
- package/menu/menu.d.ts +6 -6
- package/otp/index.d.ts +5 -0
- package/{form-field → otp}/otp.d.ts +1 -1
- package/otp/public-api.d.ts +1 -0
- package/package.json +25 -17
- package/pagination/pagination.d.ts +5 -1
- package/popover/popover-arrow.ng.d.ts +34 -0
- package/popover/popover.d.ts +12 -3
- package/popover/popover.service.d.ts +5 -4
- package/popover/public-api.d.ts +1 -0
- package/popover/utils.d.ts +32 -48
- package/portal/dialog-ref.d.ts +0 -1
- package/resizable/resizable-group.d.ts +2 -2
- package/resizable/resizable.d.ts +2 -2
- package/schematics/components/files/accordion/accordion.ts.template +6 -8
- package/schematics/components/files/autocomplete/autocomplete.ts.template +2 -6
- package/schematics/components/files/avatar/avatar.ts.template +2 -2
- package/schematics/components/files/breadcrumb/breadcrumb.ts.template +5 -5
- package/schematics/components/files/carousel/carousel.ts.template +2 -2
- package/schematics/components/files/chip/chip.ts.template +2 -2
- package/schematics/components/files/datepicker/calendar.ts.template +6 -6
- package/schematics/components/files/datepicker/datepicker.ts.template +33 -3
- package/schematics/components/files/datepicker/index.ts.template +0 -1
- package/schematics/components/files/datepicker/time.ts.template +12 -4
- package/schematics/components/files/dialog/dialog.ts.template +8 -8
- package/schematics/components/files/form-field/{input.ts.template → form-field.ts.template} +13 -2
- package/schematics/components/files/form-field/index.ts.template +1 -2
- package/schematics/components/files/form-field/input-style.directive.ts.template +1 -1
- package/schematics/components/files/menu/menu.ts.template +3 -3
- package/schematics/components/files/otp/index.ts.template +5 -0
- package/schematics/components/files/{form-field → otp}/otp.ts.template +3 -3
- package/schematics/components/files/pagination/pagination.ts.template +2 -2
- package/schematics/components/files/popover/popover.ts.template +7 -30
- package/schematics/components/files/radio/radio.ts.template +3 -8
- package/schematics/components/files/resizable/resizable.ts.template +7 -7
- package/schematics/components/files/select/option.ts.template +1 -0
- package/schematics/components/files/select/select.ts.template +8 -8
- package/schematics/components/files/sheet/sheet.ts.template +11 -76
- package/schematics/components/files/sidenav/sidenav.ts.template +3 -3
- package/schematics/components/files/slider/slider.ts.template +3 -10
- package/schematics/components/files/sonner/sonner.ts.template +3 -2
- package/schematics/components/files/stepper/stepper.ts.template +4 -4
- package/schematics/components/files/switch/switch.ts.template +1 -1
- package/schematics/components/files/tabs/tab.ts.template +11 -8
- package/schematics/components/files/theme/theme.service.ts.template +0 -11
- package/schematics/components/files/tooltip/tooltip.ts.template +8 -3
- package/schematics/components/files/tour/index.ts.template +0 -2
- package/schematics/components/files/tour/tour.ts.template +13 -2
- package/schematics/components/files/tree/tree.ts.template +3 -3
- package/schematics/components/schema.json +8 -0
- package/select/option-group.d.ts +3 -3
- package/select/select.d.ts +2 -2
- package/sheet/index.d.ts +5 -0
- package/sheet/public-api.d.ts +2 -0
- package/sheet/sheet.d.ts +26 -0
- package/sheet/sheet.service.d.ts +13 -0
- package/sidenav/public-api.d.ts +1 -1
- package/sidenav/sidenav.d.ts +1 -1
- package/slider/public-api.d.ts +1 -1
- package/slider/slider.d.ts +5 -5
- package/sonner/sonner.d.ts +2 -1
- package/stepper/animation.d.ts +1 -1
- package/stepper/step.d.ts +1 -1
- package/stepper/stepper.d.ts +2 -2
- package/switch/switch.d.ts +1 -1
- package/table/body-row.d.ts +3 -3
- package/table/head-row.d.ts +3 -3
- package/table/table.d.ts +1 -1
- package/tabs/tab-group.d.ts +4 -4
- package/tabs/tab.d.ts +2 -2
- package/tooltip/public-api.d.ts +1 -1
- package/tooltip/tooltip.d.ts +5 -1
- package/tooltip/tooltip.directive.d.ts +1 -1
- package/tooltip/tooltip.service.d.ts +4 -2
- package/tour/tour.service.d.ts +3 -4
- package/tree/public-api.d.ts +2 -2
- package/tree/tree-node.d.ts +2 -2
- package/tree/tree.d.ts +2 -2
- package/schematics/components/files/datepicker/datepicker-trigger.ts.template +0 -27
- package/schematics/components/files/theme/theme.component.ts.template +0 -165
- package/schematics/components/files/tour/tour-step.ts.template +0 -8
- package/schematics/components/files/tour/tour.service.ts.template +0 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { InjectionToken, signal, inject, input, ElementRef, computed, Component, linkedSignal, Directive, viewChild, ViewContainerRef, effect } from '@angular/core';
|
|
3
3
|
import * as i2 from '@ngbase/adk/portal';
|
|
4
4
|
import { basePortal, BaseDialog, NgbPortalClose, DialogOptions } from '@ngbase/adk/portal';
|
|
5
5
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
@@ -30,16 +30,7 @@ function basePopoverPortal(component) {
|
|
|
30
30
|
return { open, closeAll };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
top: 'bottom',
|
|
35
|
-
bottom: 'top',
|
|
36
|
-
left: 'right',
|
|
37
|
-
right: 'left',
|
|
38
|
-
tl: 'bl',
|
|
39
|
-
tr: 'br',
|
|
40
|
-
bl: 'tl',
|
|
41
|
-
br: 'tr',
|
|
42
|
-
};
|
|
33
|
+
// Main position enum with all supported positions
|
|
43
34
|
var Position;
|
|
44
35
|
(function (Position) {
|
|
45
36
|
Position["Top"] = "top";
|
|
@@ -50,30 +41,171 @@ var Position;
|
|
|
50
41
|
Position["TopRight"] = "tr";
|
|
51
42
|
Position["BottomLeft"] = "bl";
|
|
52
43
|
Position["BottomRight"] = "br";
|
|
44
|
+
Position["RightStart"] = "rs";
|
|
45
|
+
Position["RightEnd"] = "re";
|
|
46
|
+
Position["LeftStart"] = "ls";
|
|
47
|
+
Position["LeftEnd"] = "le";
|
|
53
48
|
})(Position || (Position = {}));
|
|
49
|
+
// Position metadata definitions
|
|
50
|
+
const POSITION_META = {
|
|
51
|
+
[Position.Top]: {
|
|
52
|
+
main: 'vertical',
|
|
53
|
+
placement: 'before',
|
|
54
|
+
align: 'center',
|
|
55
|
+
oppositePosition: Position.Bottom,
|
|
56
|
+
fallbacks: [Position.Bottom],
|
|
57
|
+
getCoords: (target, element, offset) => ({
|
|
58
|
+
top: target.top - element.height - offset,
|
|
59
|
+
left: target.left + (target.width - element.width) / 2,
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
[Position.Bottom]: {
|
|
63
|
+
main: 'vertical',
|
|
64
|
+
placement: 'after',
|
|
65
|
+
align: 'center',
|
|
66
|
+
oppositePosition: Position.Top,
|
|
67
|
+
fallbacks: [Position.Top, Position.Right, Position.Left],
|
|
68
|
+
getCoords: (target, element, offset) => ({
|
|
69
|
+
top: target.top + target.height + offset,
|
|
70
|
+
left: target.left + (target.width - element.width) / 2,
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
[Position.Left]: {
|
|
74
|
+
main: 'horizontal',
|
|
75
|
+
placement: 'before',
|
|
76
|
+
align: 'center',
|
|
77
|
+
oppositePosition: Position.Right,
|
|
78
|
+
fallbacks: [Position.Right, Position.Top, Position.Bottom],
|
|
79
|
+
getCoords: (target, element, offset) => ({
|
|
80
|
+
top: target.top + (target.height - element.height) / 2,
|
|
81
|
+
left: target.left - element.width - offset,
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
[Position.Right]: {
|
|
85
|
+
main: 'horizontal',
|
|
86
|
+
placement: 'after',
|
|
87
|
+
align: 'center',
|
|
88
|
+
oppositePosition: Position.Left,
|
|
89
|
+
fallbacks: [Position.Left, Position.Top, Position.Bottom],
|
|
90
|
+
getCoords: (target, element, offset) => ({
|
|
91
|
+
top: target.top + (target.height - element.height) / 2,
|
|
92
|
+
left: target.left + target.width + offset,
|
|
93
|
+
}),
|
|
94
|
+
},
|
|
95
|
+
[Position.TopLeft]: {
|
|
96
|
+
main: 'vertical',
|
|
97
|
+
placement: 'before',
|
|
98
|
+
align: 'start',
|
|
99
|
+
oppositePosition: Position.BottomLeft,
|
|
100
|
+
fallbacks: [Position.BottomLeft, Position.TopRight, Position.BottomRight],
|
|
101
|
+
getCoords: (target, element, offset) => ({
|
|
102
|
+
top: target.top - element.height - offset,
|
|
103
|
+
left: target.left,
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
[Position.TopRight]: {
|
|
107
|
+
main: 'vertical',
|
|
108
|
+
placement: 'before',
|
|
109
|
+
align: 'end',
|
|
110
|
+
oppositePosition: Position.BottomRight,
|
|
111
|
+
fallbacks: [Position.BottomRight, Position.TopLeft, Position.BottomLeft],
|
|
112
|
+
getCoords: (target, element, offset) => ({
|
|
113
|
+
top: target.top - element.height - offset,
|
|
114
|
+
left: target.left + target.width - element.width,
|
|
115
|
+
}),
|
|
116
|
+
},
|
|
117
|
+
[Position.BottomLeft]: {
|
|
118
|
+
main: 'vertical',
|
|
119
|
+
placement: 'after',
|
|
120
|
+
align: 'start',
|
|
121
|
+
oppositePosition: Position.BottomRight,
|
|
122
|
+
fallbacks: [Position.BottomRight, Position.TopLeft, Position.TopRight],
|
|
123
|
+
getCoords: (target, element, offset) => ({
|
|
124
|
+
top: target.top + target.height + offset,
|
|
125
|
+
left: target.left,
|
|
126
|
+
}),
|
|
127
|
+
},
|
|
128
|
+
[Position.BottomRight]: {
|
|
129
|
+
main: 'vertical',
|
|
130
|
+
placement: 'after',
|
|
131
|
+
align: 'end',
|
|
132
|
+
oppositePosition: Position.BottomLeft,
|
|
133
|
+
fallbacks: [Position.BottomLeft, Position.TopRight, Position.TopLeft],
|
|
134
|
+
getCoords: (target, element, offset) => ({
|
|
135
|
+
top: target.top + target.height + offset,
|
|
136
|
+
left: target.left + target.width - element.width,
|
|
137
|
+
}),
|
|
138
|
+
},
|
|
139
|
+
[Position.RightStart]: {
|
|
140
|
+
main: 'horizontal',
|
|
141
|
+
placement: 'after',
|
|
142
|
+
align: 'start',
|
|
143
|
+
oppositePosition: Position.RightEnd,
|
|
144
|
+
fallbacks: [Position.RightEnd, Position.LeftStart, Position.LeftEnd],
|
|
145
|
+
getCoords: (target, element, offset) => ({
|
|
146
|
+
top: target.top,
|
|
147
|
+
left: target.left + target.width + offset,
|
|
148
|
+
}),
|
|
149
|
+
},
|
|
150
|
+
[Position.RightEnd]: {
|
|
151
|
+
main: 'horizontal',
|
|
152
|
+
placement: 'after',
|
|
153
|
+
align: 'end',
|
|
154
|
+
oppositePosition: Position.LeftEnd,
|
|
155
|
+
fallbacks: [Position.LeftEnd, Position.RightStart, Position.LeftStart],
|
|
156
|
+
getCoords: (target, element, offset) => ({
|
|
157
|
+
top: target.top + target.height - element.height,
|
|
158
|
+
left: target.left + target.width + offset,
|
|
159
|
+
}),
|
|
160
|
+
},
|
|
161
|
+
[Position.LeftStart]: {
|
|
162
|
+
main: 'horizontal',
|
|
163
|
+
placement: 'before',
|
|
164
|
+
align: 'start',
|
|
165
|
+
oppositePosition: Position.LeftEnd,
|
|
166
|
+
fallbacks: [Position.LeftEnd, Position.RightStart, Position.RightEnd],
|
|
167
|
+
getCoords: (target, element, offset) => ({
|
|
168
|
+
top: target.top,
|
|
169
|
+
left: target.left - element.width - offset,
|
|
170
|
+
}),
|
|
171
|
+
},
|
|
172
|
+
[Position.LeftEnd]: {
|
|
173
|
+
main: 'horizontal',
|
|
174
|
+
placement: 'before',
|
|
175
|
+
align: 'end',
|
|
176
|
+
oppositePosition: Position.RightEnd,
|
|
177
|
+
fallbacks: [Position.RightEnd, Position.LeftStart, Position.RightStart],
|
|
178
|
+
getCoords: (target, element, offset) => ({
|
|
179
|
+
top: target.top + target.height - element.height,
|
|
180
|
+
left: target.left - element.width - offset,
|
|
181
|
+
}),
|
|
182
|
+
},
|
|
183
|
+
};
|
|
54
184
|
class PopoverPositioner {
|
|
55
|
-
constructor(config, windowDimensions, scrollWidth) {
|
|
185
|
+
constructor(config, windowDimensions, scrollWidth = 0) {
|
|
56
186
|
this.config = config;
|
|
57
187
|
this.windowDimensions = windowDimensions;
|
|
58
188
|
this.scrollWidth = scrollWidth;
|
|
59
189
|
this.offset = this.config.offset || 5;
|
|
190
|
+
this.sideOffset = this.config.sideOffset || 0;
|
|
60
191
|
}
|
|
61
192
|
calculatePosition() {
|
|
62
193
|
const targetRect = this.getTargetRect();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const initialPosition = this.
|
|
66
|
-
|
|
67
|
-
|
|
194
|
+
this.elementRect = this.getElementRect();
|
|
195
|
+
// Get initial position or use bottom as default
|
|
196
|
+
const initialPosition = this.config.position || Position.Bottom;
|
|
197
|
+
// Find best position
|
|
198
|
+
const bestPosition = this.findBestPosition(initialPosition, targetRect);
|
|
199
|
+
// Generate and finalize coordinates
|
|
200
|
+
const coords = POSITION_META[bestPosition].getCoords(targetRect, this.elementRect, this.offset);
|
|
201
|
+
return this.finalizePosition(coords, bestPosition, targetRect);
|
|
68
202
|
}
|
|
69
203
|
getTargetRect() {
|
|
70
204
|
if (this.config.client) {
|
|
71
205
|
const { x, y, w, h } = this.config.client;
|
|
72
206
|
return { top: y, left: x, width: w, height: h };
|
|
73
207
|
}
|
|
74
|
-
|
|
75
|
-
// return { top, left, width, height: Math.min(height, this.windowDimensions.height - top) };
|
|
76
|
-
return { top, left, width, height };
|
|
208
|
+
return this.config.target.getBoundingClientRect();
|
|
77
209
|
}
|
|
78
210
|
getElementRect() {
|
|
79
211
|
const el = this.config.el;
|
|
@@ -84,433 +216,289 @@ class PopoverPositioner {
|
|
|
84
216
|
height: el.clientHeight,
|
|
85
217
|
};
|
|
86
218
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return { ...coords, position };
|
|
92
|
-
}
|
|
93
|
-
getCoordinatesForPosition(position, targetRect, elRect, offset) {
|
|
94
|
-
switch (position) {
|
|
95
|
-
case Position.Top:
|
|
96
|
-
return {
|
|
97
|
-
top: targetRect.top - elRect.height - offset,
|
|
98
|
-
left: targetRect.left + (targetRect.width - elRect.width) / 2,
|
|
99
|
-
};
|
|
100
|
-
case Position.Bottom:
|
|
101
|
-
return {
|
|
102
|
-
top: targetRect.top + targetRect.height + offset,
|
|
103
|
-
left: targetRect.left + (targetRect.width - elRect.width) / 2,
|
|
104
|
-
};
|
|
105
|
-
case Position.Left:
|
|
106
|
-
return { top: targetRect.top, left: targetRect.left - elRect.width - offset };
|
|
107
|
-
case Position.Right:
|
|
108
|
-
return { top: targetRect.top, left: targetRect.left + targetRect.width + offset };
|
|
109
|
-
case Position.TopLeft:
|
|
110
|
-
return { top: targetRect.top - elRect.height - offset, left: targetRect.left };
|
|
111
|
-
case Position.TopRight:
|
|
112
|
-
return {
|
|
113
|
-
top: targetRect.top - elRect.height - offset,
|
|
114
|
-
left: targetRect.left - (elRect.width - targetRect.width),
|
|
115
|
-
};
|
|
116
|
-
case Position.BottomLeft:
|
|
117
|
-
return { top: targetRect.top + targetRect.height + offset, left: targetRect.left };
|
|
118
|
-
case Position.BottomRight:
|
|
119
|
-
return {
|
|
120
|
-
top: targetRect.top + targetRect.height + offset,
|
|
121
|
-
left: targetRect.left - (elRect.width - targetRect.width),
|
|
122
|
-
};
|
|
219
|
+
findBestPosition(initialPosition, targetRect) {
|
|
220
|
+
// If the initial position works, use it
|
|
221
|
+
if (!this.positionOverflows(initialPosition, targetRect)) {
|
|
222
|
+
return initialPosition;
|
|
123
223
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
224
|
+
// Get available space in each direction
|
|
225
|
+
const space = this.getAvailableSpace(targetRect);
|
|
226
|
+
// Special handling for simple cases (e.g., choosing between top and bottom based on space)
|
|
227
|
+
const meta = POSITION_META[initialPosition];
|
|
228
|
+
// 1. Try the opposite position on the same axis (e.g., bottom for top)
|
|
229
|
+
const opposite = meta.oppositePosition;
|
|
230
|
+
if (!this.positionOverflows(opposite, targetRect)) {
|
|
231
|
+
return opposite;
|
|
131
232
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const leftSpace = position.left;
|
|
139
|
-
const rightSpace = this.windowDimensions.width - position.left;
|
|
140
|
-
// Calculate overflow amounts (negative means no overflow)
|
|
141
|
-
const topOverflow = -(targetRect.top - elRect.height);
|
|
142
|
-
const bottomOverflow = targetRect.top + targetRect.height + elRect.height - this.windowDimensions.height;
|
|
143
|
-
// const leftOverflow = -(position.left - (elRect.width - targetRect.width));
|
|
144
|
-
const leftOverflow = -(targetRect.left + targetRect.width - elRect.width);
|
|
145
|
-
const leftSideOverflow = -(targetRect.left - elRect.width);
|
|
146
|
-
const rightOverflow = targetRect.left + elRect.width - this.windowDimensions.width;
|
|
147
|
-
const rightSideOverflow = -(targetRect.left + targetRect.width - elRect.width);
|
|
148
|
-
const isTop = topOverflow > 0;
|
|
149
|
-
const isBottom = bottomOverflow > 0;
|
|
150
|
-
const isLeft = leftOverflow > 0;
|
|
151
|
-
const isRight = rightOverflow > 0;
|
|
152
|
-
const isLeftSide = leftSideOverflow > 0;
|
|
153
|
-
const isRightSide = rightSideOverflow > 0;
|
|
154
|
-
let preferredHorizontal;
|
|
155
|
-
let preferredVertical;
|
|
156
|
-
// If both left and right overflow, determine which side has more space
|
|
157
|
-
if (isLeft || isRight) {
|
|
158
|
-
preferredHorizontal = leftOverflow > rightOverflow ? 'right' : 'left';
|
|
233
|
+
// 2. For vertical positions, prefer the side with more space
|
|
234
|
+
if (meta.main === 'vertical') {
|
|
235
|
+
const preferredVertical = space.top > space.bottom ? Position.Top : Position.Bottom;
|
|
236
|
+
if (!this.positionOverflows(preferredVertical, targetRect)) {
|
|
237
|
+
return preferredVertical;
|
|
238
|
+
}
|
|
159
239
|
}
|
|
160
|
-
|
|
161
|
-
|
|
240
|
+
// 3. For horizontal positions, prefer the side with more space
|
|
241
|
+
if (meta.main === 'horizontal') {
|
|
242
|
+
const preferredHorizontal = space.left > space.right ? Position.Left : Position.Right;
|
|
243
|
+
if (!this.positionOverflows(preferredHorizontal, targetRect)) {
|
|
244
|
+
return preferredHorizontal;
|
|
245
|
+
}
|
|
162
246
|
}
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
|
|
247
|
+
// 4. Try fallbacks in order
|
|
248
|
+
for (const fallback of meta.fallbacks) {
|
|
249
|
+
if (!this.positionOverflows(fallback, targetRect)) {
|
|
250
|
+
return fallback;
|
|
251
|
+
}
|
|
166
252
|
}
|
|
253
|
+
// 5. If all positions have issues, find the one with the best fit
|
|
254
|
+
return this.getPositionWithLeastOverflow(initialPosition, targetRect);
|
|
255
|
+
}
|
|
256
|
+
getAvailableSpace(targetRect) {
|
|
167
257
|
return {
|
|
168
|
-
top:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
leftSide: isLeftSide,
|
|
173
|
-
rightSide: isRightSide,
|
|
174
|
-
any: isTop || isBottom || isLeft || isRight || isLeftSide || isRightSide,
|
|
175
|
-
preferredHorizontal,
|
|
176
|
-
preferredVertical,
|
|
177
|
-
overflowAmount: {
|
|
178
|
-
top: topOverflow,
|
|
179
|
-
bottom: bottomOverflow,
|
|
180
|
-
left: leftOverflow,
|
|
181
|
-
right: rightOverflow,
|
|
182
|
-
leftSide: leftSideOverflow,
|
|
183
|
-
rightSide: rightSideOverflow,
|
|
184
|
-
},
|
|
258
|
+
top: targetRect.top,
|
|
259
|
+
right: this.windowDimensions.width - (targetRect.left + targetRect.width),
|
|
260
|
+
bottom: this.windowDimensions.height - (targetRect.top + targetRect.height),
|
|
261
|
+
left: targetRect.left,
|
|
185
262
|
};
|
|
186
263
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// } else if (position.includes('bl') && overflow.preferredVertical === 'bottom') {
|
|
225
|
-
// return overflow.right && overflow.preferredHorizontal !== 'right'
|
|
226
|
-
// ? Position.BottomRight
|
|
227
|
-
// : Position.BottomLeft;
|
|
228
|
-
// }
|
|
229
|
-
// }
|
|
230
|
-
// if (overflow.left) {
|
|
231
|
-
// if (position === Position.Left) {
|
|
232
|
-
// return Position.Right;
|
|
233
|
-
// }
|
|
234
|
-
// if (overflow.preferredHorizontal === 'left' || !overflow.right) {
|
|
235
|
-
// return overflow.bottom ? Position.TopLeft : Position.BottomLeft;
|
|
236
|
-
// }
|
|
237
|
-
// if (overflow.preferredHorizontal === 'right') {
|
|
238
|
-
// return overflow.bottom ? Position.TopRight : Position.BottomRight;
|
|
239
|
-
// }
|
|
240
|
-
// }
|
|
241
|
-
// if (overflow.right) {
|
|
242
|
-
// if (position.includes('right')) {
|
|
243
|
-
// return !overflow.left
|
|
244
|
-
// ? Position.Left
|
|
245
|
-
// : overflow.bottom && !overflow.left
|
|
246
|
-
// ? (positionSwap[position] as Position)
|
|
247
|
-
// : overflow.left && overflow.bottom
|
|
248
|
-
// ? Position.Top
|
|
249
|
-
// : Position.BottomRight;
|
|
250
|
-
// } else if (position.includes('bl')) {
|
|
251
|
-
// return overflow.bottom ? Position.TopRight : Position.BottomRight;
|
|
252
|
-
// }
|
|
253
|
-
// }
|
|
254
|
-
// return position;
|
|
255
|
-
if (!overflow.any) {
|
|
256
|
-
return position;
|
|
257
|
-
}
|
|
258
|
-
// Simple mapping for opposite positions
|
|
259
|
-
const opposites = {
|
|
260
|
-
[Position.Top]: Position.Bottom,
|
|
261
|
-
[Position.Bottom]: Position.Top,
|
|
262
|
-
[Position.Left]: Position.Right,
|
|
263
|
-
[Position.Right]: Position.Left,
|
|
264
|
-
[Position.TopLeft]: Position.BottomRight,
|
|
265
|
-
[Position.TopRight]: Position.BottomLeft,
|
|
266
|
-
[Position.BottomLeft]: Position.TopRight,
|
|
267
|
-
[Position.BottomRight]: Position.TopLeft,
|
|
268
|
-
};
|
|
269
|
-
// For cardinal positions (Top, Bottom, Left, Right)
|
|
270
|
-
if ([Position.Top, Position.Bottom].includes(position)) {
|
|
271
|
-
return overflow.preferredVertical || opposites[position];
|
|
272
|
-
}
|
|
273
|
-
if ([Position.Left, Position.Right].includes(position)) {
|
|
274
|
-
return overflow.preferredHorizontal || opposites[position];
|
|
275
|
-
}
|
|
276
|
-
// For corner positions
|
|
277
|
-
const isTop = position.includes('t');
|
|
278
|
-
const isLeft = position.includes('l');
|
|
279
|
-
const vertical = overflow.preferredVertical === 'top' ? 't' : 'b';
|
|
280
|
-
const horizontal = overflow.preferredHorizontal === 'left' ? 'r' : 'l';
|
|
281
|
-
// If current position overflows, use the preferred directions
|
|
282
|
-
if ((isTop && overflow.top) ||
|
|
283
|
-
(!isTop && overflow.bottom) ||
|
|
284
|
-
(isLeft && overflow.left) ||
|
|
285
|
-
(!isLeft && overflow.right) ||
|
|
286
|
-
(horizontal === 'r' && overflow.right) ||
|
|
287
|
-
(horizontal === 'l' && overflow.left)) {
|
|
288
|
-
switch (vertical + horizontal) {
|
|
289
|
-
case 'tl':
|
|
290
|
-
return Position.TopLeft;
|
|
291
|
-
case 'tr':
|
|
292
|
-
return Position.TopRight;
|
|
293
|
-
case 'bl':
|
|
294
|
-
return Position.BottomLeft;
|
|
295
|
-
case 'br':
|
|
296
|
-
return Position.BottomRight;
|
|
297
|
-
default:
|
|
298
|
-
return opposites[position];
|
|
264
|
+
positionOverflows(position, targetRect) {
|
|
265
|
+
const meta = POSITION_META[position];
|
|
266
|
+
const element = this.elementRect;
|
|
267
|
+
const coords = meta.getCoords(targetRect, element, this.offset);
|
|
268
|
+
const { width: windowWidth, height: windowHeight } = this.windowDimensions;
|
|
269
|
+
// Check boundaries
|
|
270
|
+
return (coords.left < 0 ||
|
|
271
|
+
coords.left + element.width > windowWidth ||
|
|
272
|
+
coords.top < 0 ||
|
|
273
|
+
coords.top + element.height > windowHeight);
|
|
274
|
+
}
|
|
275
|
+
getOverflowAmount(position, targetRect) {
|
|
276
|
+
const meta = POSITION_META[position];
|
|
277
|
+
const element = this.elementRect;
|
|
278
|
+
const coords = meta.getCoords(targetRect, element, this.offset);
|
|
279
|
+
const { width: windowWidth, height: windowHeight } = this.windowDimensions;
|
|
280
|
+
let amount = 0;
|
|
281
|
+
// Calculate overflow for each edge
|
|
282
|
+
if (coords.left < 0)
|
|
283
|
+
amount += Math.abs(coords.left);
|
|
284
|
+
if (coords.left + element.width > windowWidth)
|
|
285
|
+
amount += coords.left + element.width - windowWidth;
|
|
286
|
+
if (coords.top < 0)
|
|
287
|
+
amount += Math.abs(coords.top);
|
|
288
|
+
if (coords.top + element.height > windowHeight)
|
|
289
|
+
amount += coords.top + element.height - windowHeight;
|
|
290
|
+
return amount;
|
|
291
|
+
}
|
|
292
|
+
getPositionWithLeastOverflow(initialPosition, targetRect) {
|
|
293
|
+
const positionsToCheck = [initialPosition, ...POSITION_META[initialPosition].fallbacks];
|
|
294
|
+
let bestPosition = initialPosition;
|
|
295
|
+
let leastOverflow = this.getOverflowAmount(initialPosition, targetRect);
|
|
296
|
+
for (const position of positionsToCheck) {
|
|
297
|
+
const overflow = this.getOverflowAmount(position, targetRect);
|
|
298
|
+
if (overflow < leastOverflow) {
|
|
299
|
+
leastOverflow = overflow;
|
|
300
|
+
bestPosition = position;
|
|
299
301
|
}
|
|
300
302
|
}
|
|
301
|
-
return
|
|
303
|
+
return bestPosition;
|
|
302
304
|
}
|
|
303
|
-
finalizePosition(position,
|
|
304
|
-
const { top, left } =
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
//
|
|
309
|
-
// this has to be done only if the position is top or bottom
|
|
310
|
-
let right;
|
|
311
|
-
right =
|
|
312
|
-
left + elRect.width > this.windowDimensions.width
|
|
313
|
-
? 0
|
|
314
|
-
: position.position.endsWith('r')
|
|
315
|
-
? this.windowDimensions.width - (left + elRect.width) - this.scrollWidth
|
|
316
|
-
: undefined;
|
|
317
|
-
let overallOffset = this.getOverallOffset(position);
|
|
305
|
+
finalizePosition(coords, position, targetRect) {
|
|
306
|
+
const { top, left } = coords;
|
|
307
|
+
const element = this.elementRect;
|
|
308
|
+
const { width: windowWidth, height: windowHeight } = this.windowDimensions;
|
|
309
|
+
const meta = POSITION_META[position];
|
|
310
|
+
// Calculate max dimensions
|
|
318
311
|
let maxHeight;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
312
|
+
let maxWidth;
|
|
313
|
+
// Set maxHeight if needed
|
|
314
|
+
if (top - this.sideOffset < 0) {
|
|
315
|
+
maxHeight = element.height + top - this.sideOffset;
|
|
322
316
|
}
|
|
323
|
-
else if (
|
|
324
|
-
|
|
325
|
-
maxHeight = this.elRect.height - this.overflow.overflowAmount.bottom - overallOffset.vertical;
|
|
317
|
+
else if (top + element.height + this.sideOffset > windowHeight) {
|
|
318
|
+
maxHeight = element.height - (top + element.height + this.sideOffset - windowHeight);
|
|
326
319
|
}
|
|
327
|
-
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
maxWidth = this.elRect.width - this.overflow.overflowAmount.right - overallOffset.horizontal;
|
|
320
|
+
// Set maxWidth if needed
|
|
321
|
+
if (left + element.width + this.sideOffset > windowWidth) {
|
|
322
|
+
maxWidth = windowWidth - left - this.sideOffset;
|
|
331
323
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
324
|
+
// Add sideOffset to maxHeight and maxWidth because the sideOffset is used for the maxHeight and maxWidth
|
|
325
|
+
const h = maxHeight ? maxHeight + this.sideOffset : element.height;
|
|
326
|
+
const w = maxWidth ? maxWidth + this.sideOffset : element.width;
|
|
327
|
+
// Calculate adjusted coordinates
|
|
328
|
+
let adjustedTop = Math.max(0, Math.min(top, windowHeight - h));
|
|
329
|
+
let adjustedLeft = Math.max(0, Math.min(left, windowWidth - w));
|
|
330
|
+
// Calculate bottom and right (for RTL support)
|
|
331
|
+
let bottom;
|
|
332
|
+
let right;
|
|
333
|
+
// Set bottom if appropriate
|
|
334
|
+
if (meta.main === 'vertical' && meta.placement === 'before') {
|
|
335
|
+
bottom = windowHeight - (adjustedTop + h);
|
|
336
|
+
adjustedTop = undefined;
|
|
337
|
+
}
|
|
338
|
+
// Set right if appropriate
|
|
339
|
+
if (adjustedLeft + w > windowWidth) {
|
|
340
|
+
adjustedLeft = 0;
|
|
341
|
+
right = 0;
|
|
342
|
+
}
|
|
343
|
+
else if (meta.align === 'end' ||
|
|
344
|
+
(meta.main === 'horizontal' && meta.placement === 'before')) {
|
|
345
|
+
right = windowWidth - (adjustedLeft + w) - this.scrollWidth;
|
|
335
346
|
}
|
|
336
347
|
return {
|
|
337
|
-
|
|
338
|
-
|
|
348
|
+
top: adjustedTop,
|
|
349
|
+
left: right !== undefined ? undefined : adjustedLeft,
|
|
339
350
|
bottom,
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
maxWidth,
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
getOverallOffset(position) {
|
|
348
|
-
const overallOffset = this.config.sideOffset ?? 0;
|
|
349
|
-
const isHorizontal = position.position === 'left' || position.position === 'right';
|
|
350
|
-
return {
|
|
351
|
-
horizontal: overallOffset + (isHorizontal ? this.offset : 0),
|
|
352
|
-
vertical: overallOffset + (isHorizontal ? 0 : this.offset),
|
|
351
|
+
right,
|
|
352
|
+
position,
|
|
353
|
+
maxHeight: maxHeight && maxHeight > 0 ? maxHeight : undefined,
|
|
354
|
+
maxWidth: maxWidth && maxWidth > 0 ? maxWidth : undefined,
|
|
353
355
|
};
|
|
354
356
|
}
|
|
355
357
|
}
|
|
356
358
|
// Main function to use the class
|
|
357
|
-
function tooltipPosition(config, windowDimensions = {
|
|
358
|
-
width: window.innerWidth,
|
|
359
|
-
height: window.innerHeight,
|
|
360
|
-
}, scrollWidth = window.innerWidth - document.documentElement.clientWidth) {
|
|
359
|
+
function tooltipPosition(config, windowDimensions = { width: window.innerWidth, height: window.innerHeight }, scrollWidth = window.innerWidth - document.documentElement.clientWidth) {
|
|
361
360
|
const positioner = new PopoverPositioner(config, windowDimensions, scrollWidth);
|
|
362
361
|
return positioner.calculatePosition();
|
|
363
362
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
// : bottomOverflow && !leftOverflow
|
|
504
|
-
// ? positionSwap[position]
|
|
505
|
-
// : leftOverflow && bottomOverflow
|
|
506
|
-
// ? 'top'
|
|
507
|
-
// : 'br';
|
|
508
|
-
// } else if (position.includes('bl')) {
|
|
509
|
-
// position = bottomOverflow ? 'tr' : 'br';
|
|
510
|
-
// }
|
|
511
|
-
// }
|
|
512
|
-
// return position;
|
|
513
|
-
// }
|
|
363
|
+
|
|
364
|
+
class PopoverArrowTracker {
|
|
365
|
+
constructor() {
|
|
366
|
+
this.top = 0;
|
|
367
|
+
this.left = 0;
|
|
368
|
+
this.right = 0;
|
|
369
|
+
this.bottom = 0;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const POPOVER_ARROW_TRACKER = new InjectionToken('popoverArrowTracker');
|
|
373
|
+
function providePopoverArrowTracker() {
|
|
374
|
+
return {
|
|
375
|
+
provide: POPOVER_ARROW_TRACKER,
|
|
376
|
+
useFactory: () => ({ values: signal(new PopoverArrowTracker()) }),
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
class NgbPopoverArrow {
|
|
380
|
+
constructor() {
|
|
381
|
+
this.arrowTracker = inject(POPOVER_ARROW_TRACKER);
|
|
382
|
+
this.anchor = input(false);
|
|
383
|
+
this.el = inject((ElementRef));
|
|
384
|
+
this.styles = computed(() => {
|
|
385
|
+
const { target, position } = this.arrowTracker.values();
|
|
386
|
+
if (target && position) {
|
|
387
|
+
return this.updateAnchorPosition(position, target, this.el.nativeElement);
|
|
388
|
+
}
|
|
389
|
+
return {};
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
updateAnchorPosition(position, target, el) {
|
|
393
|
+
const { height, width, top } = el.getBoundingClientRect();
|
|
394
|
+
const { height: tHeight, width: tWidth, top: tTop } = target.getBoundingClientRect();
|
|
395
|
+
let deg = '0deg';
|
|
396
|
+
let anchorTop = '50%';
|
|
397
|
+
let anchorLeft = '50%';
|
|
398
|
+
const anchorWidth = 8;
|
|
399
|
+
const thHeight = tHeight / 2 - anchorWidth / 2;
|
|
400
|
+
const thWidth = tWidth / 2;
|
|
401
|
+
switch (position) {
|
|
402
|
+
case 'top':
|
|
403
|
+
case 'tl':
|
|
404
|
+
case 'tr':
|
|
405
|
+
anchorTop = '100%';
|
|
406
|
+
break;
|
|
407
|
+
case 'left':
|
|
408
|
+
deg = '270deg';
|
|
409
|
+
anchorLeft = `calc(100% + ${anchorWidth / 2}px)`;
|
|
410
|
+
anchorTop =
|
|
411
|
+
tHeight > height
|
|
412
|
+
? `calc(50% - ${anchorWidth / 2}px)`
|
|
413
|
+
: `calc(${thHeight + (tTop - top)}px)`;
|
|
414
|
+
break;
|
|
415
|
+
case 'right':
|
|
416
|
+
deg = '90deg';
|
|
417
|
+
anchorLeft = `-${anchorWidth / 2}px`;
|
|
418
|
+
anchorTop =
|
|
419
|
+
tHeight > height
|
|
420
|
+
? `calc(50% - ${anchorWidth / 2}px)`
|
|
421
|
+
: `calc(${thHeight + (tTop - top)}px)`;
|
|
422
|
+
break;
|
|
423
|
+
case 'bottom':
|
|
424
|
+
case 'bl':
|
|
425
|
+
case 'br':
|
|
426
|
+
deg = '180deg';
|
|
427
|
+
anchorTop = '-0.5rem';
|
|
428
|
+
anchorLeft = thWidth > width ? '50%' : `calc(100% - ${thWidth}px)`;
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
return { '--action-angle': deg, '--action-left': anchorLeft, '--action-top': anchorTop };
|
|
432
|
+
}
|
|
433
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverArrow, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
434
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: NgbPopoverArrow, isStandalone: true, selector: "[ngbPopoverArrow]", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style": "styles()" } }, ngImport: i0, template: `
|
|
435
|
+
<ng-content />
|
|
436
|
+
@if (anchor()) {
|
|
437
|
+
<style>
|
|
438
|
+
:host {
|
|
439
|
+
--action-angle: 180deg;
|
|
440
|
+
--action-left: 50%;
|
|
441
|
+
--action-top: -1rem;
|
|
442
|
+
}
|
|
443
|
+
:host::before {
|
|
444
|
+
content: '';
|
|
445
|
+
position: absolute;
|
|
446
|
+
width: 0;
|
|
447
|
+
height: 0;
|
|
448
|
+
border-style: solid;
|
|
449
|
+
border-top: 0.5rem solid;
|
|
450
|
+
@apply border-foreground;
|
|
451
|
+
border-left: 0.45rem solid transparent;
|
|
452
|
+
border-right: 0.45rem solid transparent;
|
|
453
|
+
top: var(--action-top);
|
|
454
|
+
left: var(--action-left);
|
|
455
|
+
transform: translateX(-50%) rotate(var(--action-angle, 180deg));
|
|
456
|
+
/* Add shadow to match the container shadow */
|
|
457
|
+
/* filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));
|
|
458
|
+
z-index: -1; */
|
|
459
|
+
}
|
|
460
|
+
</style>
|
|
461
|
+
}
|
|
462
|
+
`, isInline: true, styles: [":host{--action-angle: 180deg;--action-left: 50%;--action-top: -1rem}:host:before{content:\"\";position:absolute;width:0;height:0;border-style:solid;border-top:.5rem solid;@apply border-foreground;border-left:.45rem solid transparent;border-right:.45rem solid transparent;top:var(--action-top);left:var(--action-left);transform:translate(-50%) rotate(var(--action-angle, 180deg))}\n"] }); }
|
|
463
|
+
}
|
|
464
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverArrow, decorators: [{
|
|
465
|
+
type: Component,
|
|
466
|
+
args: [{
|
|
467
|
+
selector: '[ngbPopoverArrow]',
|
|
468
|
+
template: `
|
|
469
|
+
<ng-content />
|
|
470
|
+
@if (anchor()) {
|
|
471
|
+
<style>
|
|
472
|
+
:host {
|
|
473
|
+
--action-angle: 180deg;
|
|
474
|
+
--action-left: 50%;
|
|
475
|
+
--action-top: -1rem;
|
|
476
|
+
}
|
|
477
|
+
:host::before {
|
|
478
|
+
content: '';
|
|
479
|
+
position: absolute;
|
|
480
|
+
width: 0;
|
|
481
|
+
height: 0;
|
|
482
|
+
border-style: solid;
|
|
483
|
+
border-top: 0.5rem solid;
|
|
484
|
+
@apply border-foreground;
|
|
485
|
+
border-left: 0.45rem solid transparent;
|
|
486
|
+
border-right: 0.45rem solid transparent;
|
|
487
|
+
top: var(--action-top);
|
|
488
|
+
left: var(--action-left);
|
|
489
|
+
transform: translateX(-50%) rotate(var(--action-angle, 180deg));
|
|
490
|
+
/* Add shadow to match the container shadow */
|
|
491
|
+
/* filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));
|
|
492
|
+
z-index: -1; */
|
|
493
|
+
}
|
|
494
|
+
</style>
|
|
495
|
+
}
|
|
496
|
+
`,
|
|
497
|
+
host: {
|
|
498
|
+
'[style]': 'styles()',
|
|
499
|
+
},
|
|
500
|
+
}]
|
|
501
|
+
}] });
|
|
514
502
|
|
|
515
503
|
class NgbPopoverBackdrop {
|
|
516
504
|
constructor() {
|
|
@@ -552,6 +540,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
|
|
|
552
540
|
class NgbPopover extends BaseDialog {
|
|
553
541
|
constructor() {
|
|
554
542
|
super();
|
|
543
|
+
this.arrowTracker = inject(POPOVER_ARROW_TRACKER);
|
|
555
544
|
this.disposals = disposals();
|
|
556
545
|
this.myDialog = viewChild.required('myDialog', { read: ViewContainerRef });
|
|
557
546
|
this.container = viewChild.required(NgbPopoverMain, {
|
|
@@ -668,16 +657,16 @@ class NgbPopover extends BaseDialog {
|
|
|
668
657
|
sideOffset: this.options().sideOffset,
|
|
669
658
|
});
|
|
670
659
|
// change the anchor position
|
|
671
|
-
if (this.options().anchor) {
|
|
672
|
-
|
|
673
|
-
}
|
|
660
|
+
// if (this.options().anchor) {
|
|
661
|
+
// this.updateAnchorPosition(position, el, target);
|
|
662
|
+
// }
|
|
674
663
|
this.lastPosition = position;
|
|
675
664
|
// we need to update the values directly instead of signal to avoid too many CD checks
|
|
676
|
-
if (bottom) {
|
|
665
|
+
if (bottom !== undefined) {
|
|
677
666
|
el.style.bottom = `${bottom}px`;
|
|
678
667
|
el.style.top = '';
|
|
679
668
|
}
|
|
680
|
-
else
|
|
669
|
+
else {
|
|
681
670
|
el.style.top = `${top}px`;
|
|
682
671
|
el.style.bottom = '';
|
|
683
672
|
}
|
|
@@ -695,87 +684,14 @@ class NgbPopover extends BaseDialog {
|
|
|
695
684
|
if (maxWidth) {
|
|
696
685
|
el.style.maxWidth = `${maxWidth}px`;
|
|
697
686
|
}
|
|
698
|
-
|
|
699
|
-
updateAnchorPosition(position, el, target) {
|
|
700
|
-
let deg = '0deg';
|
|
701
|
-
let anchorTop = '50%';
|
|
702
|
-
let anchorLeft = '50%';
|
|
703
|
-
const anchorWidth = 12.8;
|
|
704
|
-
const thHeight = target.offsetHeight / 2;
|
|
705
|
-
const thWidth = target.offsetWidth / 2;
|
|
706
|
-
switch (position) {
|
|
707
|
-
case 'top':
|
|
708
|
-
case 'tl':
|
|
709
|
-
case 'tr':
|
|
710
|
-
anchorTop = '100%';
|
|
711
|
-
break;
|
|
712
|
-
case 'left':
|
|
713
|
-
deg = '270deg';
|
|
714
|
-
anchorLeft = `calc(100% + ${anchorWidth / 2}px)`;
|
|
715
|
-
anchorTop = thHeight > el.clientHeight ? '50%' : `calc(${thHeight}px)`;
|
|
716
|
-
break;
|
|
717
|
-
case 'right':
|
|
718
|
-
deg = '90deg';
|
|
719
|
-
anchorLeft = `-${anchorWidth / 2}px`;
|
|
720
|
-
anchorTop = thHeight > el.clientHeight ? '50%' : `calc(${thHeight}px)`;
|
|
721
|
-
break;
|
|
722
|
-
case 'bottom':
|
|
723
|
-
case 'bl':
|
|
724
|
-
case 'br':
|
|
725
|
-
deg = '180deg';
|
|
726
|
-
anchorTop = '-1rem';
|
|
727
|
-
anchorLeft = thWidth > el.clientWidth ? '50%' : `calc(100% - ${thWidth}px)`;
|
|
728
|
-
break;
|
|
729
|
-
}
|
|
730
|
-
el.style.setProperty('--action-angle', deg);
|
|
731
|
-
el.style.setProperty('--action-left', anchorLeft);
|
|
732
|
-
el.style.setProperty('--action-top', anchorTop);
|
|
733
|
-
// console.log('updateAnchorPosition', position, deg);
|
|
687
|
+
this.arrowTracker.values.set({ top, bottom, left, right, target, position });
|
|
734
688
|
}
|
|
735
689
|
setOptions(options) {
|
|
736
690
|
// console.log('setOptions', options);
|
|
737
691
|
this.options.set(options);
|
|
738
692
|
}
|
|
739
693
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopover, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
740
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
741
|
-
.popover-anchor {
|
|
742
|
-
--action-angle: 180deg;
|
|
743
|
-
--action-left: 50%;
|
|
744
|
-
--action-top: -1rem;
|
|
745
|
-
}
|
|
746
|
-
.popover-anchor::before {
|
|
747
|
-
content: '';
|
|
748
|
-
position: absolute;
|
|
749
|
-
width: 0;
|
|
750
|
-
height: 0;
|
|
751
|
-
border-style: solid;
|
|
752
|
-
border-top: 0.8rem solid;
|
|
753
|
-
@apply border-foreground;
|
|
754
|
-
border-left: 0.5rem solid transparent;
|
|
755
|
-
border-right: 0.5rem solid transparent;
|
|
756
|
-
top: var(--action-top);
|
|
757
|
-
left: var(--action-left);
|
|
758
|
-
transform: translateX(-50%) rotate(var(--action-angle, 180deg));
|
|
759
|
-
}
|
|
760
|
-
</style>
|
|
761
|
-
<div
|
|
762
|
-
ngbPopoverMain
|
|
763
|
-
[@slideInOutAnimation]
|
|
764
|
-
class="{{
|
|
765
|
-
'menu-container pointer-events-auto fixed z-10 flex flex-col rounded-lg border bg-foreground shadow-md ' +
|
|
766
|
-
(options().anchor ? 'popover-anchor ' : 'overflow-auto ')
|
|
767
|
-
}}"
|
|
768
|
-
>
|
|
769
|
-
<div class="flex flex-1 flex-col overflow-auto">
|
|
770
|
-
<ng-container #myDialog />
|
|
771
|
-
</div>
|
|
772
|
-
</div>
|
|
773
|
-
@if (options().backdrop) {
|
|
774
|
-
<div
|
|
775
|
-
ngbPopoverBackdrop
|
|
776
|
-
class="popover-backdrop pointer-events-auto fixed top-0 h-full w-full"
|
|
777
|
-
></div>
|
|
778
|
-
}`, isInline: true, styles: [".popover-anchor{--action-angle: 180deg;--action-left: 50%;--action-top: -1rem}.popover-anchor:before{content:\"\";position:absolute;width:0;height:0;border-style:solid;border-top:.8rem solid;@apply border-foreground;border-left:.5rem solid transparent;border-right:.5rem solid transparent;top:var(--action-top);left:var(--action-left);transform:translate(-50%) rotate(var(--action-angle, 180deg))}\n"], dependencies: [{ kind: "directive", type: NgbPopoverBackdrop, selector: "[ngbPopoverBackdrop]" }, { kind: "directive", type: NgbPopoverMain, selector: "[ngbPopoverMain]" }], animations: [
|
|
694
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", type: NgbPopover, isStandalone: true, selector: "ngb-popover", host: { listeners: { "@parentAnimation.done": "animationDone()" }, properties: { "@parentAnimation": "" } }, viewQueries: [{ propertyName: "myDialog", first: true, predicate: ["myDialog"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "container", first: true, predicate: NgbPopoverMain, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "backdropElement", first: true, predicate: NgbPopoverBackdrop, descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true, animations: [
|
|
779
695
|
createHostAnimation(['@slideInOutAnimation']),
|
|
780
696
|
trigger('slideInOutAnimation', [
|
|
781
697
|
state('1', style({ transform: 'none', opacity: 1 })),
|
|
@@ -783,55 +699,14 @@ class NgbPopover extends BaseDialog {
|
|
|
783
699
|
state('0', style({ transform: 'translateY(-10px) scale(0.95)', opacity: 0 })),
|
|
784
700
|
transition('* => *', animate('100ms ease-out')),
|
|
785
701
|
]),
|
|
786
|
-
]
|
|
702
|
+
] }); }
|
|
787
703
|
}
|
|
788
704
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopover, decorators: [{
|
|
789
705
|
type: Component,
|
|
790
706
|
args: [{
|
|
791
707
|
selector: 'ngb-popover',
|
|
792
|
-
|
|
793
|
-
imports: [NgbPopoverBackdrop, NgbPopoverMain],
|
|
794
|
-
template: ` <style>
|
|
795
|
-
.popover-anchor {
|
|
796
|
-
--action-angle: 180deg;
|
|
797
|
-
--action-left: 50%;
|
|
798
|
-
--action-top: -1rem;
|
|
799
|
-
}
|
|
800
|
-
.popover-anchor::before {
|
|
801
|
-
content: '';
|
|
802
|
-
position: absolute;
|
|
803
|
-
width: 0;
|
|
804
|
-
height: 0;
|
|
805
|
-
border-style: solid;
|
|
806
|
-
border-top: 0.8rem solid;
|
|
807
|
-
@apply border-foreground;
|
|
808
|
-
border-left: 0.5rem solid transparent;
|
|
809
|
-
border-right: 0.5rem solid transparent;
|
|
810
|
-
top: var(--action-top);
|
|
811
|
-
left: var(--action-left);
|
|
812
|
-
transform: translateX(-50%) rotate(var(--action-angle, 180deg));
|
|
813
|
-
}
|
|
814
|
-
</style>
|
|
815
|
-
<div
|
|
816
|
-
ngbPopoverMain
|
|
817
|
-
[@slideInOutAnimation]
|
|
818
|
-
class="{{
|
|
819
|
-
'menu-container pointer-events-auto fixed z-10 flex flex-col rounded-lg border bg-foreground shadow-md ' +
|
|
820
|
-
(options().anchor ? 'popover-anchor ' : 'overflow-auto ')
|
|
821
|
-
}}"
|
|
822
|
-
>
|
|
823
|
-
<div class="flex flex-1 flex-col overflow-auto">
|
|
824
|
-
<ng-container #myDialog />
|
|
825
|
-
</div>
|
|
826
|
-
</div>
|
|
827
|
-
@if (options().backdrop) {
|
|
828
|
-
<div
|
|
829
|
-
ngbPopoverBackdrop
|
|
830
|
-
class="popover-backdrop pointer-events-auto fixed top-0 h-full w-full"
|
|
831
|
-
></div>
|
|
832
|
-
}`,
|
|
708
|
+
template: '',
|
|
833
709
|
host: {
|
|
834
|
-
class: 'fixed top-0 left-0 w-full h-full pointer-events-none z-p flex items-center justify-center',
|
|
835
710
|
'[@parentAnimation]': '',
|
|
836
711
|
'(@parentAnimation.done)': 'animationDone()',
|
|
837
712
|
},
|
|
@@ -886,8 +761,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
|
|
|
886
761
|
hostDirectives: [{ directive: NgbPortalClose, inputs: ['ngbPortalClose: ngbPopoverClose'] }],
|
|
887
762
|
}]
|
|
888
763
|
}] });
|
|
889
|
-
function
|
|
890
|
-
return { provide: NgbPopover, useExisting: popover };
|
|
764
|
+
function aliasPopover(popover) {
|
|
765
|
+
return [{ provide: NgbPopover, useExisting: popover }, providePopoverArrowTracker()];
|
|
891
766
|
}
|
|
892
767
|
|
|
893
768
|
class PopoverOptions extends DialogOptions {
|
|
@@ -949,5 +824,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
|
|
|
949
824
|
* Generated bundle index. Do not edit.
|
|
950
825
|
*/
|
|
951
826
|
|
|
952
|
-
export { NgbPopover, NgbPopoverBackdrop, NgbPopoverClose, NgbPopoverMain, NgbPopoverTrigger, PopoverOptions, basePopoverPortal, ngbPopoverPortal,
|
|
827
|
+
export { NgbPopover, NgbPopoverArrow, NgbPopoverBackdrop, NgbPopoverClose, NgbPopoverMain, NgbPopoverTrigger, POPOVER_ARROW_TRACKER, PopoverArrowTracker, PopoverOptions, aliasPopover, basePopoverPortal, ngbPopoverPortal, providePopoverArrowTracker, registerNgbPopover, tooltipPosition };
|
|
953
828
|
//# sourceMappingURL=ngbase-adk-popover.mjs.map
|