@ngbase/adk 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/a11y/accessibility-group.d.ts +2 -5
  2. package/accordion/accordion-item.d.ts +7 -1
  3. package/accordion/public-api.d.ts +1 -1
  4. package/autocomplete/autocomplete-input.d.ts +2 -4
  5. package/autocomplete/autocomplete.d.ts +13 -4
  6. package/avatar/avatar.d.ts +1 -1
  7. package/breadcrumb/breadcrumb.d.ts +2 -3
  8. package/breadcrumb/public-api.d.ts +1 -1
  9. package/carousel/carousel.d.ts +3 -3
  10. package/checkbox/checkbox.d.ts +11 -3
  11. package/checkbox/public-api.d.ts +1 -1
  12. package/chip/chip.d.ts +2 -2
  13. package/datepicker/calendar.d.ts +3 -3
  14. package/datepicker/datepicker-trigger.d.ts +22 -5
  15. package/datepicker/datepicker.d.ts +4 -3
  16. package/datepicker/time.d.ts +2 -2
  17. package/dialog/dialog.d.ts +1 -1
  18. package/drag/drag.d.ts +1 -2
  19. package/fesm2022/ngbase-adk-a11y.mjs +29 -26
  20. package/fesm2022/ngbase-adk-a11y.mjs.map +1 -1
  21. package/fesm2022/ngbase-adk-accordion.mjs +16 -3
  22. package/fesm2022/ngbase-adk-accordion.mjs.map +1 -1
  23. package/fesm2022/ngbase-adk-autocomplete.mjs +23 -52
  24. package/fesm2022/ngbase-adk-autocomplete.mjs.map +1 -1
  25. package/fesm2022/ngbase-adk-avatar.mjs +2 -2
  26. package/fesm2022/ngbase-adk-avatar.mjs.map +1 -1
  27. package/fesm2022/ngbase-adk-breadcrumb.mjs +2 -2
  28. package/fesm2022/ngbase-adk-breadcrumb.mjs.map +1 -1
  29. package/fesm2022/ngbase-adk-carousel.mjs +7 -7
  30. package/fesm2022/ngbase-adk-carousel.mjs.map +1 -1
  31. package/fesm2022/ngbase-adk-checkbox.mjs +8 -6
  32. package/fesm2022/ngbase-adk-checkbox.mjs.map +1 -1
  33. package/fesm2022/ngbase-adk-chip.mjs +4 -2
  34. package/fesm2022/ngbase-adk-chip.mjs.map +1 -1
  35. package/fesm2022/ngbase-adk-datepicker.mjs +187 -350
  36. package/fesm2022/ngbase-adk-datepicker.mjs.map +1 -1
  37. package/fesm2022/ngbase-adk-dialog.mjs +14 -15
  38. package/fesm2022/ngbase-adk-dialog.mjs.map +1 -1
  39. package/fesm2022/ngbase-adk-drag.mjs +1 -2
  40. package/fesm2022/ngbase-adk-drag.mjs.map +1 -1
  41. package/fesm2022/ngbase-adk-form-field.mjs +2 -156
  42. package/fesm2022/ngbase-adk-form-field.mjs.map +1 -1
  43. package/fesm2022/ngbase-adk-list.mjs +2 -2
  44. package/fesm2022/ngbase-adk-list.mjs.map +1 -1
  45. package/fesm2022/ngbase-adk-mask.mjs +5 -3
  46. package/fesm2022/ngbase-adk-mask.mjs.map +1 -1
  47. package/fesm2022/ngbase-adk-menu.mjs +34 -34
  48. package/fesm2022/ngbase-adk-menu.mjs.map +1 -1
  49. package/fesm2022/ngbase-adk-otp.mjs +164 -0
  50. package/fesm2022/ngbase-adk-otp.mjs.map +1 -0
  51. package/fesm2022/ngbase-adk-pagination.mjs +10 -67
  52. package/fesm2022/ngbase-adk-pagination.mjs.map +1 -1
  53. package/fesm2022/ngbase-adk-popover.mjs +434 -556
  54. package/fesm2022/ngbase-adk-popover.mjs.map +1 -1
  55. package/fesm2022/ngbase-adk-portal.mjs +5 -10
  56. package/fesm2022/ngbase-adk-portal.mjs.map +1 -1
  57. package/fesm2022/ngbase-adk-radio.mjs +8 -19
  58. package/fesm2022/ngbase-adk-radio.mjs.map +1 -1
  59. package/fesm2022/ngbase-adk-resizable.mjs +10 -43
  60. package/fesm2022/ngbase-adk-resizable.mjs.map +1 -1
  61. package/fesm2022/ngbase-adk-select.mjs +87 -185
  62. package/fesm2022/ngbase-adk-select.mjs.map +1 -1
  63. package/fesm2022/ngbase-adk-sheet.mjs +95 -0
  64. package/fesm2022/ngbase-adk-sheet.mjs.map +1 -0
  65. package/fesm2022/ngbase-adk-sidenav.mjs +2 -2
  66. package/fesm2022/ngbase-adk-sidenav.mjs.map +1 -1
  67. package/fesm2022/ngbase-adk-slider.mjs +12 -23
  68. package/fesm2022/ngbase-adk-slider.mjs.map +1 -1
  69. package/fesm2022/ngbase-adk-sonner.mjs +13 -63
  70. package/fesm2022/ngbase-adk-sonner.mjs.map +1 -1
  71. package/fesm2022/ngbase-adk-stepper.mjs +16 -114
  72. package/fesm2022/ngbase-adk-stepper.mjs.map +1 -1
  73. package/fesm2022/ngbase-adk-switch.mjs +2 -2
  74. package/fesm2022/ngbase-adk-switch.mjs.map +1 -1
  75. package/fesm2022/ngbase-adk-table.mjs +17 -35
  76. package/fesm2022/ngbase-adk-table.mjs.map +1 -1
  77. package/fesm2022/ngbase-adk-tabs.mjs +14 -94
  78. package/fesm2022/ngbase-adk-tabs.mjs.map +1 -1
  79. package/fesm2022/ngbase-adk-test.mjs +11 -1
  80. package/fesm2022/ngbase-adk-test.mjs.map +1 -1
  81. package/fesm2022/ngbase-adk-tooltip.mjs +49 -39
  82. package/fesm2022/ngbase-adk-tooltip.mjs.map +1 -1
  83. package/fesm2022/ngbase-adk-tour.mjs +3 -3
  84. package/fesm2022/ngbase-adk-tour.mjs.map +1 -1
  85. package/fesm2022/ngbase-adk-tree.mjs +11 -43
  86. package/fesm2022/ngbase-adk-tree.mjs.map +1 -1
  87. package/fesm2022/ngbase-adk-utils.mjs +12 -9
  88. package/fesm2022/ngbase-adk-utils.mjs.map +1 -1
  89. package/form-field/public-api.d.ts +0 -1
  90. package/mask/mask.d.ts +1 -2
  91. package/menu/menu-trigger.d.ts +3 -3
  92. package/menu/menu.d.ts +13 -7
  93. package/otp/index.d.ts +5 -0
  94. package/{form-field → otp}/otp.d.ts +1 -1
  95. package/otp/public-api.d.ts +1 -0
  96. package/package.json +27 -19
  97. package/pagination/pagination.d.ts +7 -3
  98. package/popover/base-popover.service.d.ts +1 -1
  99. package/popover/popover-arrow.ng.d.ts +34 -0
  100. package/popover/popover.d.ts +17 -7
  101. package/popover/popover.service.d.ts +5 -4
  102. package/popover/public-api.d.ts +1 -0
  103. package/popover/utils.d.ts +32 -48
  104. package/portal/dialog-ref.d.ts +0 -1
  105. package/portal/portal-base.service.d.ts +3 -3
  106. package/portal/portal-close.directive.d.ts +3 -2
  107. package/radio/radio.d.ts +5 -1
  108. package/resizable/resizable-group.d.ts +2 -2
  109. package/resizable/resizable.d.ts +2 -2
  110. package/select/option-group.d.ts +3 -3
  111. package/select/option.d.ts +1 -1
  112. package/select/select-base.d.ts +8 -6
  113. package/select/select.d.ts +6 -3
  114. package/sheet/index.d.ts +5 -0
  115. package/sheet/public-api.d.ts +2 -0
  116. package/sheet/sheet.d.ts +26 -0
  117. package/sheet/sheet.service.d.ts +13 -0
  118. package/sidenav/public-api.d.ts +1 -1
  119. package/sidenav/sidenav.d.ts +1 -1
  120. package/slider/public-api.d.ts +1 -1
  121. package/slider/slider.d.ts +6 -5
  122. package/sonner/sonner.d.ts +2 -1
  123. package/stepper/animation.d.ts +1 -1
  124. package/stepper/step.d.ts +1 -1
  125. package/stepper/stepper.d.ts +2 -2
  126. package/switch/switch.d.ts +1 -1
  127. package/table/body-row.d.ts +3 -3
  128. package/table/head-row.d.ts +3 -3
  129. package/table/table.d.ts +3 -3
  130. package/tabs/tab-group.d.ts +4 -4
  131. package/tabs/tab.d.ts +2 -2
  132. package/test/utils.d.ts +19 -3
  133. package/tooltip/public-api.d.ts +1 -1
  134. package/tooltip/tooltip.d.ts +5 -1
  135. package/tooltip/tooltip.directive.d.ts +1 -1
  136. package/tooltip/tooltip.service.d.ts +4 -2
  137. package/tour/tour.service.d.ts +3 -4
  138. package/tree/public-api.d.ts +2 -2
  139. package/tree/tree-node.d.ts +2 -2
  140. package/tree/tree.d.ts +2 -2
  141. package/utils/utils.d.ts +5 -4
  142. package/schematics/collection.json +0 -15
  143. package/schematics/components/files/accordion/accordion.ts.template +0 -55
  144. package/schematics/components/files/accordion/index.ts.template +0 -5
  145. package/schematics/components/files/alert/alert.ts.template +0 -62
  146. package/schematics/components/files/alert/index.ts.template +0 -1
  147. package/schematics/components/files/autocomplete/autocomplete.ts.template +0 -48
  148. package/schematics/components/files/autocomplete/index.ts.template +0 -5
  149. package/schematics/components/files/avatar/avatar.ts.template +0 -31
  150. package/schematics/components/files/avatar/index.ts.template +0 -1
  151. package/schematics/components/files/badge/badge.ts.template +0 -11
  152. package/schematics/components/files/badge/index.ts.template +0 -1
  153. package/schematics/components/files/breadcrumb/breadcrumb.ts.template +0 -49
  154. package/schematics/components/files/breadcrumb/index.ts.template +0 -1
  155. package/schematics/components/files/button/button.ts.template +0 -29
  156. package/schematics/components/files/button/index.ts.template +0 -5
  157. package/schematics/components/files/card/card.ts.template +0 -11
  158. package/schematics/components/files/card/index.ts.template +0 -5
  159. package/schematics/components/files/carousel/carousel.ts.template +0 -44
  160. package/schematics/components/files/carousel/index.ts.template +0 -1
  161. package/schematics/components/files/checkbox/checkbox.ts.template +0 -46
  162. package/schematics/components/files/checkbox/focus-style.directive.ts.template +0 -12
  163. package/schematics/components/files/checkbox/index.ts.template +0 -6
  164. package/schematics/components/files/chip/chip.ts.template +0 -36
  165. package/schematics/components/files/chip/index.ts.template +0 -1
  166. package/schematics/components/files/color-picker/color-picker.ts.template +0 -104
  167. package/schematics/components/files/color-picker/index.ts.template +0 -5
  168. package/schematics/components/files/command/command.ts.template +0 -82
  169. package/schematics/components/files/command/index.ts.template +0 -1
  170. package/schematics/components/files/datepicker/calendar.ts.template +0 -117
  171. package/schematics/components/files/datepicker/datepicker-trigger.ts.template +0 -27
  172. package/schematics/components/files/datepicker/datepicker.ts.template +0 -28
  173. package/schematics/components/files/datepicker/index.ts.template +0 -3
  174. package/schematics/components/files/datepicker/time.ts.template +0 -46
  175. package/schematics/components/files/dialog/dialog.ts.template +0 -89
  176. package/schematics/components/files/dialog/index.ts.template +0 -5
  177. package/schematics/components/files/drawer/drawer.ts.template +0 -104
  178. package/schematics/components/files/drawer/index.ts.template +0 -5
  179. package/schematics/components/files/form-field/index.ts.template +0 -7
  180. package/schematics/components/files/form-field/input-style.directive.ts.template +0 -11
  181. package/schematics/components/files/form-field/input.ts.template +0 -100
  182. package/schematics/components/files/form-field/otp.ts.template +0 -37
  183. package/schematics/components/files/hover-card/hover-card.ts.template +0 -13
  184. package/schematics/components/files/hover-card/index.ts.template +0 -5
  185. package/schematics/components/files/icon/icon.ts.template +0 -16
  186. package/schematics/components/files/icon/index.ts.template +0 -1
  187. package/schematics/components/files/inline-edit/index.ts.template +0 -1
  188. package/schematics/components/files/inline-edit/inline-edit.ts.template +0 -24
  189. package/schematics/components/files/keys/index.ts.template +0 -5
  190. package/schematics/components/files/keys/key.ts.template +0 -35
  191. package/schematics/components/files/list/index.ts.template +0 -5
  192. package/schematics/components/files/list/list.ts.template +0 -28
  193. package/schematics/components/files/mask/index.ts.template +0 -1
  194. package/schematics/components/files/mask/mask.ts.template +0 -8
  195. package/schematics/components/files/menu/context-menu.ts.template +0 -14
  196. package/schematics/components/files/menu/index.ts.template +0 -8
  197. package/schematics/components/files/menu/mention.ts.template +0 -14
  198. package/schematics/components/files/menu/menu.ts.template +0 -37
  199. package/schematics/components/files/menu/navigation-menu.ts.template +0 -8
  200. package/schematics/components/files/pagination/index.ts.template +0 -1
  201. package/schematics/components/files/pagination/pagination.ts.template +0 -71
  202. package/schematics/components/files/picasa/index.ts.template +0 -1
  203. package/schematics/components/files/picasa/picasa-base.component.ts.template +0 -80
  204. package/schematics/components/files/picasa/picasa.component.ts.template +0 -57
  205. package/schematics/components/files/picasa/picasa.directive.ts.template +0 -41
  206. package/schematics/components/files/picasa/picase.service.ts.template +0 -24
  207. package/schematics/components/files/popover/index.ts.template +0 -1
  208. package/schematics/components/files/popover/popover.ts.template +0 -87
  209. package/schematics/components/files/progress/index.ts.template +0 -5
  210. package/schematics/components/files/progress/progress.ts.template +0 -14
  211. package/schematics/components/files/radio/index.ts.template +0 -5
  212. package/schematics/components/files/radio/radio.ts.template +0 -40
  213. package/schematics/components/files/resizable/index.ts.template +0 -5
  214. package/schematics/components/files/resizable/resizable.ts.template +0 -56
  215. package/schematics/components/files/scroll-area/index.ts.template +0 -1
  216. package/schematics/components/files/scroll-area/scroll-area.ts.template +0 -40
  217. package/schematics/components/files/select/index.ts.template +0 -8
  218. package/schematics/components/files/select/list-selection.ts.template +0 -15
  219. package/schematics/components/files/select/option.ts.template +0 -34
  220. package/schematics/components/files/select/select-input.ts.template +0 -21
  221. package/schematics/components/files/select/select.ts.template +0 -96
  222. package/schematics/components/files/selectable/index.ts.template +0 -1
  223. package/schematics/components/files/selectable/selectable.ts.template +0 -34
  224. package/schematics/components/files/separator/index.ts.template +0 -5
  225. package/schematics/components/files/separator/separator.ts.template +0 -19
  226. package/schematics/components/files/sheet/index.ts.template +0 -5
  227. package/schematics/components/files/sheet/sheet.ts.template +0 -134
  228. package/schematics/components/files/sidenav/index.ts.template +0 -1
  229. package/schematics/components/files/sidenav/sidenav.ts.template +0 -48
  230. package/schematics/components/files/skeleton/index.ts.template +0 -1
  231. package/schematics/components/files/skeleton/skeleton.ts.template +0 -15
  232. package/schematics/components/files/slider/index.ts.template +0 -5
  233. package/schematics/components/files/slider/slider.ts.template +0 -42
  234. package/schematics/components/files/sonner/index.ts.template +0 -5
  235. package/schematics/components/files/sonner/sonner.ts.template +0 -58
  236. package/schematics/components/files/spinner/index.ts.template +0 -1
  237. package/schematics/components/files/spinner/spinner.ts.template +0 -79
  238. package/schematics/components/files/stepper/index.ts.template +0 -1
  239. package/schematics/components/files/stepper/stepper.ts.template +0 -88
  240. package/schematics/components/files/switch/index.ts.template +0 -5
  241. package/schematics/components/files/switch/switch.ts.template +0 -29
  242. package/schematics/components/files/table/body-cell.ts.template +0 -19
  243. package/schematics/components/files/table/body-row.ts.template +0 -21
  244. package/schematics/components/files/table/column.ts.template +0 -8
  245. package/schematics/components/files/table/head-cell.ts.template +0 -19
  246. package/schematics/components/files/table/head-row.ts.template +0 -27
  247. package/schematics/components/files/table/index.ts.template +0 -26
  248. package/schematics/components/files/table/table.ts.template +0 -20
  249. package/schematics/components/files/tabs/index.ts.template +0 -5
  250. package/schematics/components/files/tabs/tab.ts.template +0 -89
  251. package/schematics/components/files/theme/index.ts.template +0 -2
  252. package/schematics/components/files/theme/theme-button.component.ts.template +0 -26
  253. package/schematics/components/files/theme/theme.component.ts.template +0 -165
  254. package/schematics/components/files/theme/theme.service.ts.template +0 -44
  255. package/schematics/components/files/toggle/index.ts.template +0 -5
  256. package/schematics/components/files/toggle/toggle.ts.template +0 -13
  257. package/schematics/components/files/toggle-group/index.ts.template +0 -5
  258. package/schematics/components/files/toggle-group/toggle-group.ts.template +0 -25
  259. package/schematics/components/files/tooltip/index.ts.template +0 -5
  260. package/schematics/components/files/tooltip/tooltip.ts.template +0 -40
  261. package/schematics/components/files/tour/index.ts.template +0 -3
  262. package/schematics/components/files/tour/tour-step.ts.template +0 -8
  263. package/schematics/components/files/tour/tour.service.ts.template +0 -7
  264. package/schematics/components/files/tour/tour.ts.template +0 -8
  265. package/schematics/components/files/tree/index.ts.template +0 -1
  266. package/schematics/components/files/tree/tree.ts.template +0 -66
  267. package/schematics/components/index.d.ts +0 -3
  268. package/schematics/components/index.js +0 -17
  269. package/schematics/components/index.js.map +0 -1
  270. package/schematics/components/index.ts +0 -29
  271. package/schematics/components/schema.d.ts +0 -6
  272. package/schematics/components/schema.js +0 -3
  273. package/schematics/components/schema.js.map +0 -1
  274. package/schematics/components/schema.json +0 -137
  275. package/schematics/components/schema.ts +0 -6
@@ -1,6 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, linkedSignal, Directive, viewChild, ViewContainerRef, ElementRef, signal, effect, Component, ChangeDetectionStrategy, InjectionToken, input } from '@angular/core';
3
- import * as i2 from '@ngbase/adk/portal';
2
+ import { InjectionToken, signal, inject, input, ElementRef, computed, Component, linkedSignal, Directive, viewChild, ViewContainerRef, effect } from '@angular/core';
4
3
  import { basePortal, BaseDialog, NgbPortalClose, DialogOptions } from '@ngbase/adk/portal';
5
4
  import { trigger, state, style, transition, animate } from '@angular/animations';
6
5
  import * as i1 from '@ngbase/adk/a11y';
@@ -30,16 +29,7 @@ function basePopoverPortal(component) {
30
29
  return { open, closeAll };
31
30
  }
32
31
 
33
- const positionSwap = {
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
- };
32
+ // Main position enum with all supported positions
43
33
  var Position;
44
34
  (function (Position) {
45
35
  Position["Top"] = "top";
@@ -50,30 +40,171 @@ var Position;
50
40
  Position["TopRight"] = "tr";
51
41
  Position["BottomLeft"] = "bl";
52
42
  Position["BottomRight"] = "br";
43
+ Position["RightStart"] = "rs";
44
+ Position["RightEnd"] = "re";
45
+ Position["LeftStart"] = "ls";
46
+ Position["LeftEnd"] = "le";
53
47
  })(Position || (Position = {}));
48
+ // Position metadata definitions
49
+ const POSITION_META = {
50
+ [Position.Top]: {
51
+ main: 'vertical',
52
+ placement: 'before',
53
+ align: 'center',
54
+ oppositePosition: Position.Bottom,
55
+ fallbacks: [Position.Bottom],
56
+ getCoords: (target, element, offset) => ({
57
+ top: target.top - element.height - offset,
58
+ left: target.left + (target.width - element.width) / 2,
59
+ }),
60
+ },
61
+ [Position.Bottom]: {
62
+ main: 'vertical',
63
+ placement: 'after',
64
+ align: 'center',
65
+ oppositePosition: Position.Top,
66
+ fallbacks: [Position.Top, Position.Right, Position.Left],
67
+ getCoords: (target, element, offset) => ({
68
+ top: target.top + target.height + offset,
69
+ left: target.left + (target.width - element.width) / 2,
70
+ }),
71
+ },
72
+ [Position.Left]: {
73
+ main: 'horizontal',
74
+ placement: 'before',
75
+ align: 'center',
76
+ oppositePosition: Position.Right,
77
+ fallbacks: [Position.Right, Position.Top, Position.Bottom],
78
+ getCoords: (target, element, offset) => ({
79
+ top: target.top + (target.height - element.height) / 2,
80
+ left: target.left - element.width - offset,
81
+ }),
82
+ },
83
+ [Position.Right]: {
84
+ main: 'horizontal',
85
+ placement: 'after',
86
+ align: 'center',
87
+ oppositePosition: Position.Left,
88
+ fallbacks: [Position.Left, Position.Top, Position.Bottom],
89
+ getCoords: (target, element, offset) => ({
90
+ top: target.top + (target.height - element.height) / 2,
91
+ left: target.left + target.width + offset,
92
+ }),
93
+ },
94
+ [Position.TopLeft]: {
95
+ main: 'vertical',
96
+ placement: 'before',
97
+ align: 'start',
98
+ oppositePosition: Position.BottomLeft,
99
+ fallbacks: [Position.BottomLeft, Position.TopRight, Position.BottomRight],
100
+ getCoords: (target, element, offset) => ({
101
+ top: target.top - element.height - offset,
102
+ left: target.left,
103
+ }),
104
+ },
105
+ [Position.TopRight]: {
106
+ main: 'vertical',
107
+ placement: 'before',
108
+ align: 'end',
109
+ oppositePosition: Position.BottomRight,
110
+ fallbacks: [Position.BottomRight, Position.TopLeft, Position.BottomLeft],
111
+ getCoords: (target, element, offset) => ({
112
+ top: target.top - element.height - offset,
113
+ left: target.left + target.width - element.width,
114
+ }),
115
+ },
116
+ [Position.BottomLeft]: {
117
+ main: 'vertical',
118
+ placement: 'after',
119
+ align: 'start',
120
+ oppositePosition: Position.BottomRight,
121
+ fallbacks: [Position.BottomRight, Position.TopLeft, Position.TopRight],
122
+ getCoords: (target, element, offset) => ({
123
+ top: target.top + target.height + offset,
124
+ left: target.left,
125
+ }),
126
+ },
127
+ [Position.BottomRight]: {
128
+ main: 'vertical',
129
+ placement: 'after',
130
+ align: 'end',
131
+ oppositePosition: Position.BottomLeft,
132
+ fallbacks: [Position.BottomLeft, Position.TopRight, Position.TopLeft],
133
+ getCoords: (target, element, offset) => ({
134
+ top: target.top + target.height + offset,
135
+ left: target.left + target.width - element.width,
136
+ }),
137
+ },
138
+ [Position.RightStart]: {
139
+ main: 'horizontal',
140
+ placement: 'after',
141
+ align: 'start',
142
+ oppositePosition: Position.RightEnd,
143
+ fallbacks: [Position.RightEnd, Position.LeftStart, Position.LeftEnd],
144
+ getCoords: (target, element, offset) => ({
145
+ top: target.top,
146
+ left: target.left + target.width + offset,
147
+ }),
148
+ },
149
+ [Position.RightEnd]: {
150
+ main: 'horizontal',
151
+ placement: 'after',
152
+ align: 'end',
153
+ oppositePosition: Position.LeftEnd,
154
+ fallbacks: [Position.LeftEnd, Position.RightStart, Position.LeftStart],
155
+ getCoords: (target, element, offset) => ({
156
+ top: target.top + target.height - element.height,
157
+ left: target.left + target.width + offset,
158
+ }),
159
+ },
160
+ [Position.LeftStart]: {
161
+ main: 'horizontal',
162
+ placement: 'before',
163
+ align: 'start',
164
+ oppositePosition: Position.LeftEnd,
165
+ fallbacks: [Position.LeftEnd, Position.RightStart, Position.RightEnd],
166
+ getCoords: (target, element, offset) => ({
167
+ top: target.top,
168
+ left: target.left - element.width - offset,
169
+ }),
170
+ },
171
+ [Position.LeftEnd]: {
172
+ main: 'horizontal',
173
+ placement: 'before',
174
+ align: 'end',
175
+ oppositePosition: Position.RightEnd,
176
+ fallbacks: [Position.RightEnd, Position.LeftStart, Position.RightStart],
177
+ getCoords: (target, element, offset) => ({
178
+ top: target.top + target.height - element.height,
179
+ left: target.left - element.width - offset,
180
+ }),
181
+ },
182
+ };
54
183
  class PopoverPositioner {
55
- constructor(config, windowDimensions, scrollWidth) {
184
+ constructor(config, windowDimensions, scrollWidth = 0) {
56
185
  this.config = config;
57
186
  this.windowDimensions = windowDimensions;
58
187
  this.scrollWidth = scrollWidth;
59
188
  this.offset = this.config.offset || 5;
189
+ this.sideOffset = this.config.sideOffset || 0;
60
190
  }
61
191
  calculatePosition() {
62
192
  const targetRect = this.getTargetRect();
63
- const elRect = this.getElementRect();
64
- this.elRect = elRect;
65
- const initialPosition = this.getInitialPosition(targetRect, elRect, this.config.position || Position.Bottom);
66
- const adjustedPosition = this.adjustForOverflow(initialPosition, targetRect, elRect);
67
- return this.finalizePosition(adjustedPosition, elRect);
193
+ this.elementRect = this.getElementRect();
194
+ // Get initial position or use bottom as default
195
+ const initialPosition = this.config.position || Position.Bottom;
196
+ // Find best position
197
+ const bestPosition = this.findBestPosition(initialPosition, targetRect);
198
+ // Generate and finalize coordinates
199
+ const coords = POSITION_META[bestPosition].getCoords(targetRect, this.elementRect, this.offset);
200
+ return this.finalizePosition(coords, bestPosition, targetRect);
68
201
  }
69
202
  getTargetRect() {
70
203
  if (this.config.client) {
71
204
  const { x, y, w, h } = this.config.client;
72
205
  return { top: y, left: x, width: w, height: h };
73
206
  }
74
- const { top, left, width, height } = this.config.target.getBoundingClientRect();
75
- // return { top, left, width, height: Math.min(height, this.windowDimensions.height - top) };
76
- return { top, left, width, height };
207
+ return this.config.target.getBoundingClientRect();
77
208
  }
78
209
  getElementRect() {
79
210
  const el = this.config.el;
@@ -84,433 +215,289 @@ class PopoverPositioner {
84
215
  height: el.clientHeight,
85
216
  };
86
217
  }
87
- getInitialPosition(targetRect, elRect, position) {
88
- const coords = this.getCoordinatesForPosition(position, targetRect, elRect, this.offset);
89
- // coords.left = Math.max(0, coords.left);
90
- // coords.top = Math.max(0, coords.top);
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
- };
218
+ findBestPosition(initialPosition, targetRect) {
219
+ // If the initial position works, use it
220
+ if (!this.positionOverflows(initialPosition, targetRect)) {
221
+ return initialPosition;
123
222
  }
124
- }
125
- adjustForOverflow(position, targetRect, elRect) {
126
- const overflow = this.checkOverflow(position, elRect, targetRect);
127
- this.overflow = overflow;
128
- if (overflow.any) {
129
- const newPosition = this.getAlternativePosition(position.position, overflow);
130
- return this.getInitialPosition(targetRect, elRect, newPosition);
223
+ // Get available space in each direction
224
+ const space = this.getAvailableSpace(targetRect);
225
+ // Special handling for simple cases (e.g., choosing between top and bottom based on space)
226
+ const meta = POSITION_META[initialPosition];
227
+ // 1. Try the opposite position on the same axis (e.g., bottom for top)
228
+ const opposite = meta.oppositePosition;
229
+ if (!this.positionOverflows(opposite, targetRect)) {
230
+ return opposite;
131
231
  }
132
- return position;
133
- }
134
- checkOverflow(position, elRect, targetRect) {
135
- // Calculate available space on all sides
136
- const topSpace = position.top;
137
- const bottomSpace = this.windowDimensions.height - position.top;
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';
232
+ // 2. Try fallbacks in order
233
+ for (const fallback of meta.fallbacks) {
234
+ if (!this.positionOverflows(fallback, targetRect)) {
235
+ return fallback;
236
+ }
159
237
  }
160
- else if (isLeftSide || isRightSide) {
161
- preferredHorizontal = leftSideOverflow > rightSideOverflow ? 'right' : 'left';
238
+ // 3. For vertical positions, prefer the side with more space
239
+ if (meta.main === 'vertical') {
240
+ const preferredVertical = space.top > space.bottom ? Position.Top : Position.Bottom;
241
+ if (!this.positionOverflows(preferredVertical, targetRect)) {
242
+ return preferredVertical;
243
+ }
162
244
  }
163
- // If both top and bottom overflow, determine which side has more space
164
- if (isTop || isBottom) {
165
- preferredVertical = topOverflow > bottomOverflow ? 'bottom' : 'top';
245
+ // 4. For horizontal positions, prefer the side with more space
246
+ if (meta.main === 'horizontal') {
247
+ const preferredHorizontal = space.left > space.right ? Position.Left : Position.Right;
248
+ if (!this.positionOverflows(preferredHorizontal, targetRect)) {
249
+ return preferredHorizontal;
250
+ }
166
251
  }
252
+ // 5. If all positions have issues, find the one with the best fit
253
+ return this.getPositionWithLeastOverflow(initialPosition, targetRect);
254
+ }
255
+ getAvailableSpace(targetRect) {
167
256
  return {
168
- top: isTop,
169
- bottom: isBottom,
170
- left: isLeft,
171
- right: isRight,
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
- },
257
+ top: targetRect.top,
258
+ right: this.windowDimensions.width - (targetRect.left + targetRect.width),
259
+ bottom: this.windowDimensions.height - (targetRect.top + targetRect.height),
260
+ left: targetRect.left,
185
261
  };
186
262
  }
187
- getAlternativePosition(position, overflow) {
188
- // if (overflow.top) {
189
- // if (position === Position.Top) {
190
- // return Position.Bottom;
191
- // }
192
- // }
193
- // if (
194
- // (overflow.preferredVertical === 'top' || !overflow.bottom) &&
195
- // (overflow.preferredHorizontal === 'left' || !overflow.right)
196
- // ) {
197
- // return Position.BottomRight;
198
- // }
199
- // if (
200
- // (overflow.preferredVertical === 'top' || !overflow.bottom) &&
201
- // (overflow.preferredHorizontal === 'right' || !overflow.left)
202
- // ) {
203
- // return Position.BottomLeft;
204
- // }
205
- // if (
206
- // (overflow.preferredVertical === 'bottom' || !overflow.top) &&
207
- // (overflow.preferredHorizontal === 'left' || !overflow.right)
208
- // ) {
209
- // return Position.TopRight;
210
- // }
211
- // if (
212
- // (overflow.preferredVertical === 'bottom' || !overflow.top) &&
213
- // (overflow.preferredHorizontal === 'right' || !overflow.left)
214
- // ) {
215
- // return Position.TopLeft;
216
- // }
217
- // if (overflow.bottom) {
218
- // if (position.includes('bottom')) {
219
- // return positionSwap[position] as Position;
220
- // } else if (position.includes('bl') && overflow.preferredVertical === 'top') {
221
- // return overflow.right && overflow.preferredHorizontal !== 'right'
222
- // ? Position.TopRight
223
- // : Position.TopLeft;
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];
263
+ positionOverflows(position, targetRect) {
264
+ const meta = POSITION_META[position];
265
+ const element = this.elementRect;
266
+ const coords = meta.getCoords(targetRect, element, this.offset);
267
+ const { width: windowWidth, height: windowHeight } = this.windowDimensions;
268
+ // Check boundaries and consider sideOffset
269
+ return (coords.left < 0 ||
270
+ coords.left + element.width + this.sideOffset > windowWidth ||
271
+ coords.top < 0 ||
272
+ coords.top + element.height + this.sideOffset > windowHeight);
273
+ }
274
+ getOverflowAmount(position, targetRect) {
275
+ const meta = POSITION_META[position];
276
+ const element = this.elementRect;
277
+ const coords = meta.getCoords(targetRect, element, this.offset);
278
+ const { width: windowWidth, height: windowHeight } = this.windowDimensions;
279
+ let amount = 0;
280
+ // Calculate overflow for each edge
281
+ if (coords.left < 0)
282
+ amount += Math.abs(coords.left);
283
+ if (coords.left + element.width > windowWidth)
284
+ amount += coords.left + element.width - windowWidth;
285
+ if (coords.top < 0)
286
+ amount += Math.abs(coords.top);
287
+ if (coords.top + element.height > windowHeight)
288
+ amount += coords.top + element.height - windowHeight;
289
+ return amount;
290
+ }
291
+ getPositionWithLeastOverflow(initialPosition, targetRect) {
292
+ const positionsToCheck = [initialPosition, ...POSITION_META[initialPosition].fallbacks];
293
+ let bestPosition = initialPosition;
294
+ let leastOverflow = this.getOverflowAmount(initialPosition, targetRect);
295
+ for (const position of positionsToCheck) {
296
+ const overflow = this.getOverflowAmount(position, targetRect);
297
+ if (overflow < leastOverflow) {
298
+ leastOverflow = overflow;
299
+ bestPosition = position;
299
300
  }
300
301
  }
301
- return position;
302
+ return bestPosition;
302
303
  }
303
- finalizePosition(position, elRect) {
304
- const { top, left } = position;
305
- const bottom = position.position.startsWith('t')
306
- ? this.windowDimensions.height - (top + elRect.height)
307
- : undefined;
308
- // this is required if tooltip is going outside of the screen horizontally
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);
304
+ finalizePosition(coords, position, targetRect) {
305
+ const { top, left } = coords;
306
+ const element = this.elementRect;
307
+ const { width: windowWidth, height: windowHeight } = this.windowDimensions;
308
+ const meta = POSITION_META[position];
309
+ // Calculate max dimensions
318
310
  let maxHeight;
319
- if (position.position.startsWith('t') &&
320
- this.overflow.overflowAmount.top > -overallOffset.vertical) {
321
- maxHeight = this.elRect.height - this.overflow.overflowAmount.top - overallOffset.vertical;
311
+ let maxWidth;
312
+ // Set maxHeight if needed
313
+ if (top - this.sideOffset < 0) {
314
+ maxHeight = element.height + top - this.sideOffset;
322
315
  }
323
- else if (position.position.startsWith('b') &&
324
- this.overflow.overflowAmount.bottom > -overallOffset.vertical) {
325
- maxHeight = this.elRect.height - this.overflow.overflowAmount.bottom - overallOffset.vertical;
316
+ else if (top + element.height + this.sideOffset > windowHeight) {
317
+ maxHeight = element.height - (top + element.height + this.sideOffset - windowHeight);
326
318
  }
327
- let maxWidth;
328
- if (position.position.endsWith('l') &&
329
- this.overflow.overflowAmount.right > -overallOffset.horizontal) {
330
- maxWidth = this.elRect.width - this.overflow.overflowAmount.right - overallOffset.horizontal;
319
+ // Set maxWidth if needed
320
+ if (left + element.width + this.sideOffset > windowWidth) {
321
+ maxWidth = windowWidth - left - this.sideOffset;
322
+ }
323
+ // Add sideOffset to maxHeight and maxWidth because the sideOffset is used for the maxHeight and maxWidth
324
+ const h = maxHeight ? maxHeight + this.sideOffset : element.height;
325
+ const w = maxWidth ? maxWidth + this.sideOffset : element.width;
326
+ // Calculate adjusted coordinates
327
+ let adjustedTop = Math.max(0, Math.min(top, windowHeight - h));
328
+ let adjustedLeft = Math.max(0, Math.min(left, windowWidth - w));
329
+ // Calculate bottom and right (for RTL support)
330
+ let bottom;
331
+ let right;
332
+ // Set bottom if appropriate
333
+ if (meta.main === 'vertical' && meta.placement === 'before') {
334
+ bottom = windowHeight - (adjustedTop + h);
335
+ adjustedTop = undefined;
336
+ }
337
+ // Set right if appropriate
338
+ if (adjustedLeft + w > windowWidth) {
339
+ adjustedLeft = 0;
340
+ right = 0;
331
341
  }
332
- else if (position.position.endsWith('r') &&
333
- this.overflow.overflowAmount.left > -overallOffset.horizontal) {
334
- maxWidth = this.elRect.width - this.overflow.overflowAmount.left - overallOffset.horizontal;
342
+ else if (meta.align === 'end' ||
343
+ (meta.main === 'horizontal' && meta.placement === 'before')) {
344
+ right = windowWidth - (adjustedLeft + w) - this.scrollWidth;
335
345
  }
336
346
  return {
337
- // top: Math.max(0, Math.min(top, this.windowDimensions.height - (maxHeight || elRect.height))),
338
- top: Math.max(0, top),
347
+ top: adjustedTop,
348
+ left: right !== undefined ? undefined : adjustedLeft,
339
349
  bottom,
340
- left: right ? 0 : Math.max(overallOffset.horizontal, left),
341
- right: right ? Math.max(overallOffset.horizontal, right) : undefined,
342
- position: position.position,
343
- maxHeight,
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),
350
+ right,
351
+ position,
352
+ maxHeight: maxHeight && maxHeight > 0 ? maxHeight : undefined,
353
+ maxWidth: maxWidth && maxWidth > 0 ? maxWidth : undefined,
353
354
  };
354
355
  }
355
356
  }
356
357
  // 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) {
358
+ function tooltipPosition(config, windowDimensions = { width: window.innerWidth, height: window.innerHeight }, scrollWidth = window.innerWidth - document.documentElement.clientWidth) {
361
359
  const positioner = new PopoverPositioner(config, windowDimensions, scrollWidth);
362
360
  return positioner.calculatePosition();
363
361
  }
364
- // export function tooltipPosition(config: OverlayConfig): {
365
- // top: number;
366
- // left: number;
367
- // bottom?: number;
368
- // right?: number;
369
- // position: DialogPosition;
370
- // } {
371
- // const { target, el, position: priority = 'bottom', offset = 5, client: clientXY = null } = config;
372
- // let position: DialogPosition = priority;
373
- // let { top, left, width, height } = target.getBoundingClientRect();
374
- // if (clientXY) {
375
- // top = clientXY.y;
376
- // left = clientXY.x;
377
- // width = clientXY.w;
378
- // height = clientXY.h;
379
- // }
380
- // const { clientWidth: elWidth, clientHeight: elHeight } = el!;
381
- // // we need to check whether the height of the target element is greater than the height then we need to adjust the height
382
- // if (height > window.innerHeight) {
383
- // height = window.innerHeight - top;
384
- // }
385
- // return tooltipPositionInternal({
386
- // top,
387
- // left,
388
- // width,
389
- // height,
390
- // elWidth,
391
- // elHeight,
392
- // offset,
393
- // priority,
394
- // position,
395
- // windowWidth: window.innerWidth,
396
- // windowHeight: window.innerHeight,
397
- // scrollWidth: window.innerWidth - document.documentElement.clientWidth,
398
- // });
399
- // }
400
- // export function tooltipPositionInternal(data: ConfigObj): {
401
- // top: number;
402
- // bottom?: number;
403
- // left: number;
404
- // right?: number;
405
- // position: DialogPosition;
406
- // } {
407
- // let { elHeight, position, windowHeight, windowWidth, offset, elWidth, scrollWidth } = data;
408
- // position = positionSwapBasedOnOverflow(data);
409
- // let { top: topPos, left: leftPos } = getTooltipCoordinates(position, data);
410
- // if (topPos <= 0) {
411
- // topPos = offset;
412
- // } else if (topPos + elHeight > windowHeight) {
413
- // topPos = windowHeight - elHeight - offset;
414
- // } else if (leftPos < 0) {
415
- // leftPos = 0;
416
- // }
417
- // const bottomPos = position.startsWith('t') ? windowHeight - (topPos + elHeight) : undefined;
418
- // const rightPos =
419
- // leftPos + elWidth > windowWidth
420
- // ? 0
421
- // : position.endsWith('r')
422
- // ? windowWidth - (leftPos + elWidth) - scrollWidth
423
- // : undefined;
424
- // return {
425
- // top: topPos,
426
- // bottom: bottomPos,
427
- // left: rightPos ? 0 : leftPos,
428
- // position,
429
- // right: rightPos,
430
- // };
431
- // }
432
- // function getTooltipCoordinates(
433
- // position: DialogPosition,
434
- // data: ConfigObj,
435
- // ): { top: number; left: number } {
436
- // const { top, left, width, height, elWidth, elHeight, offset } = data;
437
- // switch (position) {
438
- // case 'top':
439
- // return {
440
- // top: top - elHeight - offset,
441
- // left: left + (width - elWidth) / 2,
442
- // };
443
- // case 'bottom':
444
- // return { top: top + height + offset, left: left + (width - elWidth) / 2 };
445
- // case 'left':
446
- // return { top, left: left - elWidth - offset };
447
- // case 'right':
448
- // return { top, left: left + width + offset };
449
- // case 'tl':
450
- // return { top: top - elHeight - offset, left };
451
- // case 'tr':
452
- // return { top: top - elHeight - offset, left: left - (elWidth - width) };
453
- // case 'bl':
454
- // return { top: top + height + offset, left };
455
- // case 'br':
456
- // return { top: top + height + offset, left: left - (elWidth - width) };
457
- // default:
458
- // return {
459
- // top: top - elHeight - offset,
460
- // left: left + (width - elWidth) / 2,
461
- // };
462
- // }
463
- // }
464
- // // function to check the overflow sides for target and element
465
- // export function checkOverflow(data: ConfigObj) {
466
- // const isTop = data.top - data.elHeight < 0;
467
- // const isBottom = data.top + data.height + data.elHeight > data.windowHeight;
468
- // const isLeft = data.left - data.elWidth < 0;
469
- // const isRight = data.left + data.width + data.elWidth > data.windowWidth;
470
- // return { top: isTop, bottom: isBottom, left: isLeft, right: isRight };
471
- // }
472
- // // position swap based on the overflow and priority
473
- // function positionSwapBasedOnOverflow(data: ConfigObj): DialogPosition {
474
- // const {
475
- // bottom: bottomOverflow,
476
- // left: leftOverflow,
477
- // right: rightOverflow,
478
- // top: topOverflow,
479
- // } = checkOverflow(data);
480
- // const { priority } = data;
481
- // let position = priority;
482
- // if (topOverflow) {
483
- // if (position.includes('top')) {
484
- // position = positionSwap[position];
485
- // }
486
- // }
487
- // if (bottomOverflow) {
488
- // if (position.includes('bottom')) {
489
- // position = positionSwap[position];
490
- // } else if (position.includes('bl')) {
491
- // position = rightOverflow ? 'tr' : 'tl';
492
- // }
493
- // }
494
- // if (leftOverflow) {
495
- // if (position.includes('left')) {
496
- // position = positionSwap[position];
497
- // }
498
- // }
499
- // if (rightOverflow) {
500
- // if (position.includes('right')) {
501
- // position = !leftOverflow
502
- // ? 'left'
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
- // }
362
+
363
+ class PopoverArrowTracker {
364
+ constructor() {
365
+ this.top = 0;
366
+ this.left = 0;
367
+ this.right = 0;
368
+ this.bottom = 0;
369
+ }
370
+ }
371
+ const POPOVER_ARROW_TRACKER = new InjectionToken('popoverArrowTracker');
372
+ function providePopoverArrowTracker() {
373
+ return {
374
+ provide: POPOVER_ARROW_TRACKER,
375
+ useFactory: () => ({ values: signal(new PopoverArrowTracker()) }),
376
+ };
377
+ }
378
+ class NgbPopoverArrow {
379
+ constructor() {
380
+ this.arrowTracker = inject(POPOVER_ARROW_TRACKER);
381
+ this.anchor = input(false);
382
+ this.el = inject((ElementRef));
383
+ this.styles = computed(() => {
384
+ const { target, position } = this.arrowTracker.values();
385
+ if (target && position) {
386
+ return this.updateAnchorPosition(position, target, this.el.nativeElement);
387
+ }
388
+ return {};
389
+ });
390
+ }
391
+ updateAnchorPosition(position, target, el) {
392
+ const { height, width, top } = el.getBoundingClientRect();
393
+ const { height: tHeight, width: tWidth, top: tTop } = target.getBoundingClientRect();
394
+ let deg = '0deg';
395
+ let anchorTop = '50%';
396
+ let anchorLeft = '50%';
397
+ const anchorWidth = 8;
398
+ const thHeight = tHeight / 2 - anchorWidth / 2;
399
+ const thWidth = tWidth / 2;
400
+ switch (position) {
401
+ case 'top':
402
+ case 'tl':
403
+ case 'tr':
404
+ anchorTop = '100%';
405
+ break;
406
+ case 'left':
407
+ deg = '270deg';
408
+ anchorLeft = `calc(100% + ${anchorWidth / 2}px)`;
409
+ anchorTop =
410
+ tHeight > height
411
+ ? `calc(50% - ${anchorWidth / 2}px)`
412
+ : `calc(${thHeight + (tTop - top)}px)`;
413
+ break;
414
+ case 'right':
415
+ deg = '90deg';
416
+ anchorLeft = `-${anchorWidth / 2}px`;
417
+ anchorTop =
418
+ tHeight > height
419
+ ? `calc(50% - ${anchorWidth / 2}px)`
420
+ : `calc(${thHeight + (tTop - top)}px)`;
421
+ break;
422
+ case 'bottom':
423
+ case 'bl':
424
+ case 'br':
425
+ deg = '180deg';
426
+ anchorTop = '-0.5rem';
427
+ anchorLeft = thWidth > width ? '50%' : `calc(100% - ${thWidth}px)`;
428
+ break;
429
+ }
430
+ return { '--action-angle': deg, '--action-left': anchorLeft, '--action-top': anchorTop };
431
+ }
432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverArrow, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
433
+ 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: `
434
+ <ng-content />
435
+ @if (anchor()) {
436
+ <style>
437
+ :host {
438
+ --action-angle: 180deg;
439
+ --action-left: 50%;
440
+ --action-top: -1rem;
441
+ }
442
+ :host::before {
443
+ content: '';
444
+ position: absolute;
445
+ width: 0;
446
+ height: 0;
447
+ border-style: solid;
448
+ border-top: 0.5rem solid;
449
+ @apply border-background;
450
+ border-left: 0.45rem solid transparent;
451
+ border-right: 0.45rem solid transparent;
452
+ top: var(--action-top);
453
+ left: var(--action-left);
454
+ transform: translateX(-50%) rotate(var(--action-angle, 180deg));
455
+ /* Add shadow to match the container shadow */
456
+ /* filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));
457
+ z-index: -1; */
458
+ }
459
+ </style>
460
+ }
461
+ `, 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-background;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"] }); }
462
+ }
463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverArrow, decorators: [{
464
+ type: Component,
465
+ args: [{
466
+ selector: '[ngbPopoverArrow]',
467
+ template: `
468
+ <ng-content />
469
+ @if (anchor()) {
470
+ <style>
471
+ :host {
472
+ --action-angle: 180deg;
473
+ --action-left: 50%;
474
+ --action-top: -1rem;
475
+ }
476
+ :host::before {
477
+ content: '';
478
+ position: absolute;
479
+ width: 0;
480
+ height: 0;
481
+ border-style: solid;
482
+ border-top: 0.5rem solid;
483
+ @apply border-background;
484
+ border-left: 0.45rem solid transparent;
485
+ border-right: 0.45rem solid transparent;
486
+ top: var(--action-top);
487
+ left: var(--action-left);
488
+ transform: translateX(-50%) rotate(var(--action-angle, 180deg));
489
+ /* Add shadow to match the container shadow */
490
+ /* filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));
491
+ z-index: -1; */
492
+ }
493
+ </style>
494
+ }
495
+ `,
496
+ host: {
497
+ '[style]': 'styles()',
498
+ },
499
+ }]
500
+ }] });
514
501
 
515
502
  class NgbPopoverBackdrop {
516
503
  constructor() {
@@ -552,6 +539,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
552
539
  class NgbPopover extends BaseDialog {
553
540
  constructor() {
554
541
  super();
542
+ this.arrowTracker = inject(POPOVER_ARROW_TRACKER);
555
543
  this.disposals = disposals();
556
544
  this.myDialog = viewChild.required('myDialog', { read: ViewContainerRef });
557
545
  this.container = viewChild.required(NgbPopoverMain, {
@@ -668,16 +656,16 @@ class NgbPopover extends BaseDialog {
668
656
  sideOffset: this.options().sideOffset,
669
657
  });
670
658
  // change the anchor position
671
- if (this.options().anchor) {
672
- this.updateAnchorPosition(position, el, target);
673
- }
659
+ // if (this.options().anchor) {
660
+ // this.updateAnchorPosition(position, el, target);
661
+ // }
674
662
  this.lastPosition = position;
675
663
  // we need to update the values directly instead of signal to avoid too many CD checks
676
- if (bottom) {
664
+ if (bottom !== undefined) {
677
665
  el.style.bottom = `${bottom}px`;
678
666
  el.style.top = '';
679
667
  }
680
- else if (top) {
668
+ else {
681
669
  el.style.top = `${top}px`;
682
670
  el.style.bottom = '';
683
671
  }
@@ -695,87 +683,14 @@ class NgbPopover extends BaseDialog {
695
683
  if (maxWidth) {
696
684
  el.style.maxWidth = `${maxWidth}px`;
697
685
  }
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);
686
+ this.arrowTracker.values.set({ top, bottom, left, right, target, position });
734
687
  }
735
688
  setOptions(options) {
736
689
  // console.log('setOptions', options);
737
690
  this.options.set(options);
738
691
  }
739
692
  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.0.0", version: "19.0.0", type: NgbPopover, isStandalone: true, selector: "ngb-popover", host: { listeners: { "@parentAnimation.done": "animationDone()" }, properties: { "@parentAnimation": "" }, classAttribute: "fixed top-0 left-0 w-full h-full pointer-events-none z-p flex items-center justify-center" }, 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: ` <style>
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: [
693
+ 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
694
  createHostAnimation(['@slideInOutAnimation']),
780
695
  trigger('slideInOutAnimation', [
781
696
  state('1', style({ transform: 'none', opacity: 1 })),
@@ -783,55 +698,14 @@ class NgbPopover extends BaseDialog {
783
698
  state('0', style({ transform: 'translateY(-10px) scale(0.95)', opacity: 0 })),
784
699
  transition('* => *', animate('100ms ease-out')),
785
700
  ]),
786
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
701
+ ] }); }
787
702
  }
788
703
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopover, decorators: [{
789
704
  type: Component,
790
705
  args: [{
791
706
  selector: 'ngb-popover',
792
- changeDetection: ChangeDetectionStrategy.OnPush,
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
- }`,
707
+ template: '',
833
708
  host: {
834
- class: 'fixed top-0 left-0 w-full h-full pointer-events-none z-p flex items-center justify-center',
835
709
  '[@parentAnimation]': '',
836
710
  '(@parentAnimation.done)': 'animationDone()',
837
711
  },
@@ -875,19 +749,23 @@ function scrollToElement(target) {
875
749
  requestAnimationFrame(checkIfScrollComplete);
876
750
  });
877
751
  }
878
- class NgbPopoverClose {
879
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverClose, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
880
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.0", type: NgbPopoverClose, isStandalone: true, selector: "[ngbPopoverClose]", hostDirectives: [{ directive: i2.NgbPortalClose, inputs: ["ngbPortalClose", "ngbPopoverClose"] }], ngImport: i0 }); }
752
+ class NgbPopoverClose extends NgbPortalClose {
753
+ constructor() {
754
+ super(...arguments);
755
+ this.ngbPopoverClose = input();
756
+ }
757
+ close() {
758
+ super.close(this.ngbPopoverClose());
759
+ }
760
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverClose, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
761
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.0", type: NgbPopoverClose, isStandalone: true, selector: "[ngbPopoverClose]", inputs: { ngbPopoverClose: { classPropertyName: "ngbPopoverClose", publicName: "ngbPopoverClose", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
881
762
  }
882
763
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: NgbPopoverClose, decorators: [{
883
764
  type: Directive,
884
- args: [{
885
- selector: '[ngbPopoverClose]',
886
- hostDirectives: [{ directive: NgbPortalClose, inputs: ['ngbPortalClose: ngbPopoverClose'] }],
887
- }]
765
+ args: [{ selector: '[ngbPopoverClose]' }]
888
766
  }] });
889
- function providePopover(popover) {
890
- return { provide: NgbPopover, useExisting: popover };
767
+ function aliasPopover(popover) {
768
+ return [{ provide: NgbPopover, useExisting: popover }, providePopoverArrowTracker()];
891
769
  }
892
770
 
893
771
  class PopoverOptions extends DialogOptions {
@@ -949,5 +827,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
949
827
  * Generated bundle index. Do not edit.
950
828
  */
951
829
 
952
- export { NgbPopover, NgbPopoverBackdrop, NgbPopoverClose, NgbPopoverMain, NgbPopoverTrigger, PopoverOptions, basePopoverPortal, ngbPopoverPortal, providePopover, registerNgbPopover, tooltipPosition };
830
+ export { NgbPopover, NgbPopoverArrow, NgbPopoverBackdrop, NgbPopoverClose, NgbPopoverMain, NgbPopoverTrigger, POPOVER_ARROW_TRACKER, PopoverArrowTracker, PopoverOptions, aliasPopover, basePopoverPortal, ngbPopoverPortal, providePopoverArrowTracker, registerNgbPopover, tooltipPosition };
953
831
  //# sourceMappingURL=ngbase-adk-popover.mjs.map