@haiilo/catalyst 4.1.2 → 5.0.1

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 (277) hide show
  1. package/README.md +0 -2
  2. package/dist/catalyst/assets/fonts/Lato-Black.woff +0 -0
  3. package/dist/catalyst/assets/fonts/Lato-Black.woff2 +0 -0
  4. package/dist/catalyst/assets/fonts/Lato-BlackItalic.woff +0 -0
  5. package/dist/catalyst/assets/fonts/Lato-BlackItalic.woff2 +0 -0
  6. package/dist/catalyst/assets/fonts/Lato-Bold.woff +0 -0
  7. package/dist/catalyst/assets/fonts/Lato-Bold.woff2 +0 -0
  8. package/dist/catalyst/assets/fonts/Lato-BoldItalic.woff +0 -0
  9. package/dist/catalyst/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  10. package/dist/catalyst/assets/fonts/Lato-Hairline.woff +0 -0
  11. package/dist/catalyst/assets/fonts/Lato-Hairline.woff2 +0 -0
  12. package/dist/catalyst/assets/fonts/Lato-HairlineItalic.woff +0 -0
  13. package/dist/catalyst/assets/fonts/Lato-HairlineItalic.woff2 +0 -0
  14. package/dist/catalyst/assets/fonts/Lato-Heavy.woff +0 -0
  15. package/dist/catalyst/assets/fonts/Lato-Heavy.woff2 +0 -0
  16. package/dist/catalyst/assets/fonts/Lato-HeavyItalic.woff +0 -0
  17. package/dist/catalyst/assets/fonts/Lato-HeavyItalic.woff2 +0 -0
  18. package/dist/catalyst/assets/fonts/Lato-Italic.woff +0 -0
  19. package/dist/catalyst/assets/fonts/Lato-Italic.woff2 +0 -0
  20. package/dist/catalyst/assets/fonts/Lato-Light.woff +0 -0
  21. package/dist/catalyst/assets/fonts/Lato-Light.woff2 +0 -0
  22. package/dist/catalyst/assets/fonts/Lato-LightItalic.woff +0 -0
  23. package/dist/catalyst/assets/fonts/Lato-LightItalic.woff2 +0 -0
  24. package/dist/catalyst/assets/fonts/Lato-Medium.woff +0 -0
  25. package/dist/catalyst/assets/fonts/Lato-Medium.woff2 +0 -0
  26. package/dist/catalyst/assets/fonts/Lato-MediumItalic.woff +0 -0
  27. package/dist/catalyst/assets/fonts/Lato-MediumItalic.woff2 +0 -0
  28. package/dist/catalyst/assets/fonts/Lato-Regular.woff +0 -0
  29. package/dist/catalyst/assets/fonts/Lato-Regular.woff2 +0 -0
  30. package/dist/catalyst/assets/fonts/Lato-Semibold.woff +0 -0
  31. package/dist/catalyst/assets/fonts/Lato-Semibold.woff2 +0 -0
  32. package/dist/catalyst/assets/fonts/Lato-SemiboldItalic.woff +0 -0
  33. package/dist/catalyst/assets/fonts/Lato-SemiboldItalic.woff2 +0 -0
  34. package/dist/catalyst/assets/fonts/Lato-Thin.woff +0 -0
  35. package/dist/catalyst/assets/fonts/Lato-Thin.woff2 +0 -0
  36. package/dist/catalyst/assets/fonts/Lato-ThinItalic.woff +0 -0
  37. package/dist/catalyst/assets/fonts/Lato-ThinItalic.woff2 +0 -0
  38. package/dist/catalyst/catalyst.css +6 -27
  39. package/dist/catalyst/catalyst.esm.js +1 -1
  40. package/dist/catalyst/catalyst.esm.js.map +1 -1
  41. package/dist/catalyst/index.esm.js.map +1 -1
  42. package/dist/catalyst/p-ccfebe33.js.map +1 -1
  43. package/dist/catalyst/p-d1ee6a09.entry.js +10 -0
  44. package/dist/catalyst/p-d1ee6a09.entry.js.map +1 -0
  45. package/dist/catalyst/p-d1fb9d96.js +3 -0
  46. package/dist/catalyst/p-d1fb9d96.js.map +1 -0
  47. package/dist/catalyst/scss/fonts/_fonts-mixins.scss +0 -10
  48. package/dist/cjs/cat-alert_24.cjs.entry.js +933 -1135
  49. package/dist/cjs/cat-alert_24.cjs.entry.js.map +1 -1
  50. package/dist/cjs/catalyst.cjs.js +10 -3
  51. package/dist/cjs/catalyst.cjs.js.map +1 -1
  52. package/dist/cjs/{index-c4542095.js → index-01312a2e.js} +527 -245
  53. package/dist/cjs/index-01312a2e.js.map +1 -0
  54. package/dist/cjs/index.cjs.js.map +1 -1
  55. package/dist/cjs/loader.cjs.js +4 -3
  56. package/dist/cjs/loader.cjs.js.map +1 -1
  57. package/dist/collection/assets/fonts/Lato-Black.woff +0 -0
  58. package/dist/collection/assets/fonts/Lato-Black.woff2 +0 -0
  59. package/dist/collection/assets/fonts/Lato-BlackItalic.woff +0 -0
  60. package/dist/collection/assets/fonts/Lato-BlackItalic.woff2 +0 -0
  61. package/dist/collection/assets/fonts/Lato-Bold.woff +0 -0
  62. package/dist/collection/assets/fonts/Lato-Bold.woff2 +0 -0
  63. package/dist/collection/assets/fonts/Lato-BoldItalic.woff +0 -0
  64. package/dist/collection/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  65. package/dist/collection/assets/fonts/Lato-Hairline.woff +0 -0
  66. package/dist/collection/assets/fonts/Lato-Hairline.woff2 +0 -0
  67. package/dist/collection/assets/fonts/Lato-HairlineItalic.woff +0 -0
  68. package/dist/collection/assets/fonts/Lato-HairlineItalic.woff2 +0 -0
  69. package/dist/collection/assets/fonts/Lato-Heavy.woff +0 -0
  70. package/dist/collection/assets/fonts/Lato-Heavy.woff2 +0 -0
  71. package/dist/collection/assets/fonts/Lato-HeavyItalic.woff +0 -0
  72. package/dist/collection/assets/fonts/Lato-HeavyItalic.woff2 +0 -0
  73. package/dist/collection/assets/fonts/Lato-Italic.woff +0 -0
  74. package/dist/collection/assets/fonts/Lato-Italic.woff2 +0 -0
  75. package/dist/collection/assets/fonts/Lato-Light.woff +0 -0
  76. package/dist/collection/assets/fonts/Lato-Light.woff2 +0 -0
  77. package/dist/collection/assets/fonts/Lato-LightItalic.woff +0 -0
  78. package/dist/collection/assets/fonts/Lato-LightItalic.woff2 +0 -0
  79. package/dist/collection/assets/fonts/Lato-Medium.woff +0 -0
  80. package/dist/collection/assets/fonts/Lato-Medium.woff2 +0 -0
  81. package/dist/collection/assets/fonts/Lato-MediumItalic.woff +0 -0
  82. package/dist/collection/assets/fonts/Lato-MediumItalic.woff2 +0 -0
  83. package/dist/collection/assets/fonts/Lato-Regular.woff +0 -0
  84. package/dist/collection/assets/fonts/Lato-Regular.woff2 +0 -0
  85. package/dist/collection/assets/fonts/Lato-Semibold.woff +0 -0
  86. package/dist/collection/assets/fonts/Lato-Semibold.woff2 +0 -0
  87. package/dist/collection/assets/fonts/Lato-SemiboldItalic.woff +0 -0
  88. package/dist/collection/assets/fonts/Lato-SemiboldItalic.woff2 +0 -0
  89. package/dist/collection/assets/fonts/Lato-Thin.woff +0 -0
  90. package/dist/collection/assets/fonts/Lato-Thin.woff2 +0 -0
  91. package/dist/collection/assets/fonts/Lato-ThinItalic.woff +0 -0
  92. package/dist/collection/assets/fonts/Lato-ThinItalic.woff2 +0 -0
  93. package/dist/collection/collection-manifest.json +2 -2
  94. package/dist/collection/components/cat-alert/cat-alert.js +69 -71
  95. package/dist/collection/components/cat-alert/cat-alert.js.map +1 -1
  96. package/dist/collection/components/cat-avatar/cat-avatar.js +172 -165
  97. package/dist/collection/components/cat-avatar/cat-avatar.js.map +1 -1
  98. package/dist/collection/components/cat-badge/cat-badge.js +102 -111
  99. package/dist/collection/components/cat-badge/cat-badge.js.map +1 -1
  100. package/dist/collection/components/cat-button/cat-button.js +526 -537
  101. package/dist/collection/components/cat-button/cat-button.js.map +1 -1
  102. package/dist/collection/components/cat-card/cat-card.js +12 -8
  103. package/dist/collection/components/cat-checkbox/cat-checkbox.js +336 -350
  104. package/dist/collection/components/cat-checkbox/cat-checkbox.js.map +1 -1
  105. package/dist/collection/components/cat-dropdown/cat-dropdown.js +137 -137
  106. package/dist/collection/components/cat-dropdown/cat-dropdown.js.map +1 -1
  107. package/dist/collection/components/cat-form-group/cat-form-group.js +58 -40
  108. package/dist/collection/components/cat-form-group/cat-form-group.js.map +1 -1
  109. package/dist/collection/components/cat-form-hint/cat-form-hint.js +14 -7
  110. package/dist/collection/components/cat-form-hint/cat-form-hint.js.map +1 -1
  111. package/dist/collection/components/cat-i18n/cat-i18n-registry.js +1 -1
  112. package/dist/collection/components/cat-icon/cat-icon-registry.js +1 -1
  113. package/dist/collection/components/cat-icon/cat-icon.js +85 -79
  114. package/dist/collection/components/cat-icon/cat-icon.js.map +1 -1
  115. package/dist/collection/components/cat-input/cat-input.css +32 -3
  116. package/dist/collection/components/cat-input/cat-input.js +662 -660
  117. package/dist/collection/components/cat-input/cat-input.js.map +1 -1
  118. package/dist/collection/components/cat-input/input-type.js +1 -1
  119. package/dist/collection/components/cat-label/cat-label.js +69 -78
  120. package/dist/collection/components/cat-label/cat-label.js.map +1 -1
  121. package/dist/collection/components/cat-notification/cat-notification.js +1 -1
  122. package/dist/collection/components/cat-notification/cat-notification.js.map +1 -1
  123. package/dist/collection/components/cat-pagination/cat-pagination.js +192 -226
  124. package/dist/collection/components/cat-pagination/cat-pagination.js.map +1 -1
  125. package/dist/collection/components/cat-radio/cat-radio.js +319 -327
  126. package/dist/collection/components/cat-radio/cat-radio.js.map +1 -1
  127. package/dist/collection/components/cat-radio-group/cat-radio-group.js +173 -165
  128. package/dist/collection/components/cat-radio-group/cat-radio-group.js.map +1 -1
  129. package/dist/collection/components/cat-scrollable/cat-scrollable.js +200 -208
  130. package/dist/collection/components/cat-scrollable/cat-scrollable.js.map +1 -1
  131. package/dist/collection/components/cat-select/cat-select.js +556 -593
  132. package/dist/collection/components/cat-select/cat-select.js.map +1 -1
  133. package/dist/collection/components/cat-select-demo/cat-select-demo.js +3 -28
  134. package/dist/collection/components/cat-select-demo/cat-select-demo.js.map +1 -1
  135. package/dist/collection/components/cat-skeleton/cat-skeleton.js +85 -88
  136. package/dist/collection/components/cat-skeleton/cat-skeleton.js.map +1 -1
  137. package/dist/collection/components/cat-spinner/cat-spinner.js +52 -50
  138. package/dist/collection/components/cat-spinner/cat-spinner.js.map +1 -1
  139. package/dist/collection/components/cat-tab/cat-tab.js +169 -168
  140. package/dist/collection/components/cat-tab/cat-tab.js.map +1 -1
  141. package/dist/collection/components/cat-tabs/cat-tabs.js +73 -66
  142. package/dist/collection/components/cat-tabs/cat-tabs.js.map +1 -1
  143. package/dist/collection/components/cat-textarea/cat-textarea.css +32 -1
  144. package/dist/collection/components/cat-textarea/cat-textarea.js +479 -468
  145. package/dist/collection/components/cat-textarea/cat-textarea.js.map +1 -1
  146. package/dist/collection/components/cat-toggle/cat-toggle.js +319 -326
  147. package/dist/collection/components/cat-toggle/cat-toggle.js.map +1 -1
  148. package/dist/collection/components/cat-tooltip/cat-tooltip.css +7 -1
  149. package/dist/collection/components/cat-tooltip/cat-tooltip.js +187 -198
  150. package/dist/collection/components/cat-tooltip/cat-tooltip.js.map +1 -1
  151. package/dist/collection/index.js +1 -1
  152. package/dist/collection/scss/fonts/_fonts-mixins.scss +0 -10
  153. package/dist/collection/utils/breakpoints.js +1 -1
  154. package/dist/collection/utils/breakpoints.js.map +1 -1
  155. package/dist/collection/utils/coerce.js +11 -0
  156. package/dist/collection/utils/coerce.js.map +1 -0
  157. package/dist/collection/utils/first-tabbable.js +1 -1
  158. package/dist/collection/utils/is-touch-screen.js +1 -1
  159. package/dist/collection/utils/load-img.js +1 -1
  160. package/dist/collection/utils/media-matcher.js +1 -1
  161. package/dist/collection/utils/platform.js +4 -4
  162. package/dist/collection/utils/setDefault.js +1 -1
  163. package/dist/components/cat-alert.js +1 -6
  164. package/dist/components/cat-alert.js.map +1 -1
  165. package/dist/components/cat-avatar2.js +6 -9
  166. package/dist/components/cat-avatar2.js.map +1 -1
  167. package/dist/components/cat-badge.js +0 -15
  168. package/dist/components/cat-badge.js.map +1 -1
  169. package/dist/components/cat-button2.js +10 -36
  170. package/dist/components/cat-button2.js.map +1 -1
  171. package/dist/components/cat-checkbox2.js +9 -26
  172. package/dist/components/cat-checkbox2.js.map +1 -1
  173. package/dist/components/cat-dropdown2.js +139 -176
  174. package/dist/components/cat-dropdown2.js.map +1 -1
  175. package/dist/components/cat-form-group.js +4 -9
  176. package/dist/components/cat-form-group.js.map +1 -1
  177. package/dist/components/cat-form-hint.js +13 -6
  178. package/dist/components/cat-form-hint.js.map +1 -1
  179. package/dist/components/cat-icon-registry.js +71 -0
  180. package/dist/components/cat-icon-registry.js.map +1 -0
  181. package/dist/components/cat-icon.js +1 -1
  182. package/dist/components/cat-icon2.js +5 -71
  183. package/dist/components/cat-icon2.js.map +1 -1
  184. package/dist/components/cat-input.js +33 -41
  185. package/dist/components/cat-input.js.map +1 -1
  186. package/dist/components/cat-label.js +1 -6
  187. package/dist/components/cat-label.js.map +1 -1
  188. package/dist/components/cat-pagination.js +0 -30
  189. package/dist/components/cat-pagination.js.map +1 -1
  190. package/dist/components/cat-radio-group.js +3 -6
  191. package/dist/components/cat-radio-group.js.map +1 -1
  192. package/dist/components/cat-radio.js +9 -23
  193. package/dist/components/cat-radio.js.map +1 -1
  194. package/dist/components/cat-scrollable2.js +1 -12
  195. package/dist/components/cat-scrollable2.js.map +1 -1
  196. package/dist/components/cat-select-demo.js +2 -12
  197. package/dist/components/cat-select-demo.js.map +1 -1
  198. package/dist/components/cat-select2.js +41 -50
  199. package/dist/components/cat-select2.js.map +1 -1
  200. package/dist/components/cat-skeleton2.js +1 -10
  201. package/dist/components/cat-skeleton2.js.map +1 -1
  202. package/dist/components/cat-spinner2.js +1 -3
  203. package/dist/components/cat-spinner2.js.map +1 -1
  204. package/dist/components/cat-tab.js +3 -12
  205. package/dist/components/cat-tab.js.map +1 -1
  206. package/dist/components/cat-tabs.js +1 -6
  207. package/dist/components/cat-tabs.js.map +1 -1
  208. package/dist/components/cat-textarea.js +28 -33
  209. package/dist/components/cat-textarea.js.map +1 -1
  210. package/dist/components/cat-toggle.js +9 -23
  211. package/dist/components/cat-toggle.js.map +1 -1
  212. package/dist/components/cat-tooltip.js +14 -34
  213. package/dist/components/cat-tooltip.js.map +1 -1
  214. package/dist/components/first-tabbable.js +51 -113
  215. package/dist/components/first-tabbable.js.map +1 -1
  216. package/dist/components/floating-ui.dom.esm.js +577 -441
  217. package/dist/components/floating-ui.dom.esm.js.map +1 -1
  218. package/dist/components/index.d.ts +9 -27
  219. package/dist/components/index.js +2 -26
  220. package/dist/components/index.js.map +1 -1
  221. package/dist/esm/cat-alert_24.entry.js +934 -1136
  222. package/dist/esm/cat-alert_24.entry.js.map +1 -1
  223. package/dist/esm/catalyst.js +7 -3
  224. package/dist/esm/catalyst.js.map +1 -1
  225. package/dist/esm/{index-524906f7.js → index-fc2f91a4.js} +527 -246
  226. package/dist/esm/index-fc2f91a4.js.map +1 -0
  227. package/dist/esm/index.js.map +1 -1
  228. package/dist/esm/loader.js +4 -3
  229. package/dist/esm/loader.js.map +1 -1
  230. package/dist/esm/polyfills/css-shim.js +1 -1
  231. package/dist/types/components/cat-checkbox/cat-checkbox.d.ts +1 -1
  232. package/dist/types/components/cat-form-group/cat-form-group.d.ts +4 -0
  233. package/dist/types/components/cat-form-hint/cat-form-hint.d.ts +5 -0
  234. package/dist/types/components/cat-input/cat-input.d.ts +6 -1
  235. package/dist/types/components/cat-input/input-type.d.ts +1 -1
  236. package/dist/types/components/cat-radio/cat-radio.d.ts +1 -1
  237. package/dist/types/components/cat-select/cat-select.d.ts +2 -1
  238. package/dist/types/components/cat-textarea/cat-textarea.d.ts +6 -1
  239. package/dist/types/components/cat-toggle/cat-toggle.d.ts +1 -1
  240. package/dist/types/components/cat-tooltip/cat-tooltip.d.ts +3 -0
  241. package/dist/types/components.d.ts +353 -7
  242. package/dist/types/stencil-public-runtime.d.ts +91 -19
  243. package/dist/types/utils/breakpoints.d.ts +1 -1
  244. package/dist/types/utils/coerce.d.ts +3 -0
  245. package/dist/types/utils/first-tabbable.d.ts +2 -2
  246. package/loader/index.d.ts +9 -0
  247. package/loader/package.json +1 -0
  248. package/package.json +19 -19
  249. package/dist/catalyst/assets/fonts/AzeretMono-Regular.woff2 +0 -0
  250. package/dist/catalyst/assets/fonts/DMSans-Bold.woff2 +0 -0
  251. package/dist/catalyst/assets/fonts/DMSans-BoldItalic.woff2 +0 -0
  252. package/dist/catalyst/assets/fonts/DMSans-Italic.woff2 +0 -0
  253. package/dist/catalyst/assets/fonts/DMSans-Medium.woff2 +0 -0
  254. package/dist/catalyst/assets/fonts/DMSans-MediumItalic.woff2 +0 -0
  255. package/dist/catalyst/assets/fonts/DMSans-Regular.woff2 +0 -0
  256. package/dist/catalyst/p-919eea27.js +0 -3
  257. package/dist/catalyst/p-919eea27.js.map +0 -1
  258. package/dist/catalyst/p-cd8f8639.entry.js +0 -10
  259. package/dist/catalyst/p-cd8f8639.entry.js.map +0 -1
  260. package/dist/catalyst/scss/fonts/_fonts.mixins.azeret.scss +0 -14
  261. package/dist/catalyst/scss/fonts/_fonts.mixins.dm.scss +0 -53
  262. package/dist/cjs/index-c4542095.js.map +0 -1
  263. package/dist/collection/assets/fonts/AzeretMono-Regular.woff2 +0 -0
  264. package/dist/collection/assets/fonts/DMSans-Bold.woff2 +0 -0
  265. package/dist/collection/assets/fonts/DMSans-BoldItalic.woff2 +0 -0
  266. package/dist/collection/assets/fonts/DMSans-Italic.woff2 +0 -0
  267. package/dist/collection/assets/fonts/DMSans-Medium.woff2 +0 -0
  268. package/dist/collection/assets/fonts/DMSans-MediumItalic.woff2 +0 -0
  269. package/dist/collection/assets/fonts/DMSans-Regular.woff2 +0 -0
  270. package/dist/collection/components/cat-form-hint/cat-form-hint-utils.js +0 -13
  271. package/dist/collection/components/cat-form-hint/cat-form-hint-utils.js.map +0 -1
  272. package/dist/collection/scss/fonts/_fonts.mixins.azeret.scss +0 -14
  273. package/dist/collection/scss/fonts/_fonts.mixins.dm.scss +0 -53
  274. package/dist/components/cat-form-hint-utils.js +0 -17
  275. package/dist/components/cat-form-hint-utils.js.map +0 -1
  276. package/dist/esm/index-524906f7.js.map +0 -1
  277. package/dist/types/components/cat-form-hint/cat-form-hint-utils.d.ts +0 -4
@@ -1,19 +1,19 @@
1
- function getSide(placement) {
2
- return placement.split('-')[0];
3
- }
4
-
5
1
  function getAlignment(placement) {
6
2
  return placement.split('-')[1];
7
3
  }
8
4
 
9
- function getMainAxisFromPlacement(placement) {
10
- return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
11
- }
12
-
13
5
  function getLengthFromAxis(axis) {
14
6
  return axis === 'y' ? 'height' : 'width';
15
7
  }
16
8
 
9
+ function getSide(placement) {
10
+ return placement.split('-')[0];
11
+ }
12
+
13
+ function getMainAxisFromPlacement(placement) {
14
+ return ['top', 'bottom'].includes(getSide(placement)) ? 'x' : 'y';
15
+ }
16
+
17
17
  function computeCoordsFromPlacement(_ref, placement, rtl) {
18
18
  let {
19
19
  reference,
@@ -27,7 +27,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
27
27
  const side = getSide(placement);
28
28
  const isVertical = mainAxis === 'x';
29
29
  let coords;
30
-
31
30
  switch (side) {
32
31
  case 'top':
33
32
  coords = {
@@ -35,45 +34,38 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
35
34
  y: reference.y - floating.height
36
35
  };
37
36
  break;
38
-
39
37
  case 'bottom':
40
38
  coords = {
41
39
  x: commonX,
42
40
  y: reference.y + reference.height
43
41
  };
44
42
  break;
45
-
46
43
  case 'right':
47
44
  coords = {
48
45
  x: reference.x + reference.width,
49
46
  y: commonY
50
47
  };
51
48
  break;
52
-
53
49
  case 'left':
54
50
  coords = {
55
51
  x: reference.x - floating.width,
56
52
  y: commonY
57
53
  };
58
54
  break;
59
-
60
55
  default:
61
56
  coords = {
62
57
  x: reference.x,
63
58
  y: reference.y
64
59
  };
65
60
  }
66
-
67
61
  switch (getAlignment(placement)) {
68
62
  case 'start':
69
63
  coords[mainAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
70
64
  break;
71
-
72
65
  case 'end':
73
66
  coords[mainAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
74
67
  break;
75
68
  }
76
-
77
69
  return coords;
78
70
  }
79
71
 
@@ -84,7 +76,6 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
84
76
  * This export does not have any `platform` interface logic. You will need to
85
77
  * write one for the platform you are using Floating UI with.
86
78
  */
87
-
88
79
  const computePosition$1 = async (reference, floating, config) => {
89
80
  const {
90
81
  placement = 'bottom',
@@ -92,8 +83,8 @@ const computePosition$1 = async (reference, floating, config) => {
92
83
  middleware = [],
93
84
  platform
94
85
  } = config;
86
+ const validMiddleware = middleware.filter(Boolean);
95
87
  const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
96
-
97
88
  let rects = await platform.getElementRects({
98
89
  reference,
99
90
  floating,
@@ -106,12 +97,11 @@ const computePosition$1 = async (reference, floating, config) => {
106
97
  let statefulPlacement = placement;
107
98
  let middlewareData = {};
108
99
  let resetCount = 0;
109
-
110
- for (let i = 0; i < middleware.length; i++) {
100
+ for (let i = 0; i < validMiddleware.length; i++) {
111
101
  const {
112
102
  name,
113
103
  fn
114
- } = middleware[i];
104
+ } = validMiddleware[i];
115
105
  const {
116
106
  x: nextX,
117
107
  y: nextY,
@@ -133,20 +123,19 @@ const computePosition$1 = async (reference, floating, config) => {
133
123
  });
134
124
  x = nextX != null ? nextX : x;
135
125
  y = nextY != null ? nextY : y;
136
- middlewareData = { ...middlewareData,
137
- [name]: { ...middlewareData[name],
126
+ middlewareData = {
127
+ ...middlewareData,
128
+ [name]: {
129
+ ...middlewareData[name],
138
130
  ...data
139
131
  }
140
132
  };
141
-
142
133
  if (reset && resetCount <= 50) {
143
134
  resetCount++;
144
-
145
135
  if (typeof reset === 'object') {
146
136
  if (reset.placement) {
147
137
  statefulPlacement = reset.placement;
148
138
  }
149
-
150
139
  if (reset.rects) {
151
140
  rects = reset.rects === true ? await platform.getElementRects({
152
141
  reference,
@@ -154,18 +143,15 @@ const computePosition$1 = async (reference, floating, config) => {
154
143
  strategy
155
144
  }) : reset.rects;
156
145
  }
157
-
158
146
  ({
159
147
  x,
160
148
  y
161
149
  } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
162
150
  }
163
-
164
151
  i = -1;
165
152
  continue;
166
153
  }
167
154
  }
168
-
169
155
  return {
170
156
  x,
171
157
  y,
@@ -195,7 +181,8 @@ function getSideObjectFromPadding(padding) {
195
181
  }
196
182
 
197
183
  function rectToClientRect(rect) {
198
- return { ...rect,
184
+ return {
185
+ ...rect,
199
186
  top: rect.y,
200
187
  left: rect.x,
201
188
  right: rect.x + rect.width,
@@ -205,19 +192,17 @@ function rectToClientRect(rect) {
205
192
 
206
193
  /**
207
194
  * Resolves with an object of overflow side offsets that determine how much the
208
- * element is overflowing a given clipping boundary.
195
+ * element is overflowing a given clipping boundary on each side.
209
196
  * - positive = overflowing the boundary by that number of pixels
210
197
  * - negative = how many pixels left before it will overflow
211
198
  * - 0 = lies flush with the boundary
212
199
  * @see https://floating-ui.com/docs/detectOverflow
213
200
  */
214
- async function detectOverflow(middlewareArguments, options) {
201
+ async function detectOverflow(state, options) {
215
202
  var _await$platform$isEle;
216
-
217
203
  if (options === void 0) {
218
204
  options = {};
219
205
  }
220
-
221
206
  const {
222
207
  x,
223
208
  y,
@@ -225,7 +210,7 @@ async function detectOverflow(middlewareArguments, options) {
225
210
  rects,
226
211
  elements,
227
212
  strategy
228
- } = middlewareArguments;
213
+ } = state;
229
214
  const {
230
215
  boundary = 'clippingAncestors',
231
216
  rootBoundary = 'viewport',
@@ -242,58 +227,72 @@ async function detectOverflow(middlewareArguments, options) {
242
227
  rootBoundary,
243
228
  strategy
244
229
  }));
230
+ const rect = elementContext === 'floating' ? {
231
+ ...rects.floating,
232
+ x,
233
+ y
234
+ } : rects.reference;
235
+ const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
236
+ const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
237
+ x: 1,
238
+ y: 1
239
+ } : {
240
+ x: 1,
241
+ y: 1
242
+ };
245
243
  const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
246
- rect: elementContext === 'floating' ? { ...rects.floating,
247
- x,
248
- y
249
- } : rects.reference,
250
- offsetParent: await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)),
244
+ rect,
245
+ offsetParent,
251
246
  strategy
252
- }) : rects[elementContext]);
247
+ }) : rect);
253
248
  return {
254
- top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
255
- bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
256
- left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
257
- right: elementClientRect.right - clippingClientRect.right + paddingObject.right
249
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
250
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
251
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
252
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
258
253
  };
259
254
  }
260
255
 
261
- const hash$1 = {
256
+ const min$1 = Math.min;
257
+ const max$1 = Math.max;
258
+
259
+ function within(min$1$1, value, max$1$1) {
260
+ return max$1(min$1$1, min$1(value, max$1$1));
261
+ }
262
+
263
+ const oppositeSideMap = {
262
264
  left: 'right',
263
265
  right: 'left',
264
266
  bottom: 'top',
265
267
  top: 'bottom'
266
268
  };
267
269
  function getOppositePlacement(placement) {
268
- return placement.replace(/left|right|bottom|top/g, matched => hash$1[matched]);
270
+ return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
269
271
  }
270
272
 
271
273
  function getAlignmentSides(placement, rects, rtl) {
272
274
  if (rtl === void 0) {
273
275
  rtl = false;
274
276
  }
275
-
276
277
  const alignment = getAlignment(placement);
277
278
  const mainAxis = getMainAxisFromPlacement(placement);
278
279
  const length = getLengthFromAxis(mainAxis);
279
280
  let mainAlignmentSide = mainAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
280
-
281
281
  if (rects.reference[length] > rects.floating[length]) {
282
282
  mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
283
283
  }
284
-
285
284
  return {
286
285
  main: mainAlignmentSide,
287
286
  cross: getOppositePlacement(mainAlignmentSide)
288
287
  };
289
288
  }
290
289
 
291
- const hash = {
290
+ const oppositeAlignmentMap = {
292
291
  start: 'end',
293
292
  end: 'start'
294
293
  };
295
294
  function getOppositeAlignmentPlacement(placement) {
296
- return placement.replace(/start|end/g, matched => hash[matched]);
295
+ return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
297
296
  }
298
297
 
299
298
  function getExpandedPlacements(placement) {
@@ -301,23 +300,50 @@ function getExpandedPlacements(placement) {
301
300
  return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
302
301
  }
303
302
 
303
+ function getSideList(side, isStart, rtl) {
304
+ const lr = ['left', 'right'];
305
+ const rl = ['right', 'left'];
306
+ const tb = ['top', 'bottom'];
307
+ const bt = ['bottom', 'top'];
308
+ switch (side) {
309
+ case 'top':
310
+ case 'bottom':
311
+ if (rtl) return isStart ? rl : lr;
312
+ return isStart ? lr : rl;
313
+ case 'left':
314
+ case 'right':
315
+ return isStart ? tb : bt;
316
+ default:
317
+ return [];
318
+ }
319
+ }
320
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
321
+ const alignment = getAlignment(placement);
322
+ let list = getSideList(getSide(placement), direction === 'start', rtl);
323
+ if (alignment) {
324
+ list = list.map(side => side + "-" + alignment);
325
+ if (flipAlignment) {
326
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
327
+ }
328
+ }
329
+ return list;
330
+ }
331
+
304
332
  /**
305
- * Changes the placement of the floating element to one that will fit if the
306
- * initially specified `placement` does not.
333
+ * Optimizes the visibility of the floating element by flipping the `placement`
334
+ * in order to keep it in view when the preferred placement(s) will overflow the
335
+ * clipping boundary. Alternative to `autoPlacement`.
307
336
  * @see https://floating-ui.com/docs/flip
308
337
  */
309
338
  const flip = function (options) {
310
339
  if (options === void 0) {
311
340
  options = {};
312
341
  }
313
-
314
342
  return {
315
343
  name: 'flip',
316
344
  options,
317
-
318
- async fn(middlewareArguments) {
345
+ async fn(state) {
319
346
  var _middlewareData$flip;
320
-
321
347
  const {
322
348
  placement,
323
349
  middlewareData,
@@ -325,48 +351,49 @@ const flip = function (options) {
325
351
  initialPlacement,
326
352
  platform,
327
353
  elements
328
- } = middlewareArguments;
354
+ } = state;
329
355
  const {
330
356
  mainAxis: checkMainAxis = true,
331
357
  crossAxis: checkCrossAxis = true,
332
358
  fallbackPlacements: specifiedFallbackPlacements,
333
359
  fallbackStrategy = 'bestFit',
360
+ fallbackAxisSideDirection = 'none',
334
361
  flipAlignment = true,
335
362
  ...detectOverflowOptions
336
363
  } = options;
337
364
  const side = getSide(placement);
338
- const isBasePlacement = side === initialPlacement;
365
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
366
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
339
367
  const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
368
+ if (!specifiedFallbackPlacements && fallbackAxisSideDirection !== 'none') {
369
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
370
+ }
340
371
  const placements = [initialPlacement, ...fallbackPlacements];
341
- const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
372
+ const overflow = await detectOverflow(state, detectOverflowOptions);
342
373
  const overflows = [];
343
374
  let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
344
-
345
375
  if (checkMainAxis) {
346
376
  overflows.push(overflow[side]);
347
377
  }
348
-
349
378
  if (checkCrossAxis) {
350
379
  const {
351
380
  main,
352
381
  cross
353
- } = getAlignmentSides(placement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));
382
+ } = getAlignmentSides(placement, rects, rtl);
354
383
  overflows.push(overflow[main], overflow[cross]);
355
384
  }
356
-
357
385
  overflowsData = [...overflowsData, {
358
386
  placement,
359
387
  overflows
360
- }]; // One or more sides is overflowing
388
+ }];
361
389
 
390
+ // One or more sides is overflowing.
362
391
  if (!overflows.every(side => side <= 0)) {
363
- var _middlewareData$flip$, _middlewareData$flip2;
364
-
365
- const nextIndex = ((_middlewareData$flip$ = (_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) != null ? _middlewareData$flip$ : 0) + 1;
392
+ var _middlewareData$flip2, _overflowsData$filter;
393
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
366
394
  const nextPlacement = placements[nextIndex];
367
-
368
395
  if (nextPlacement) {
369
- // Try next placement and re-run the lifecycle
396
+ // Try next placement and re-run the lifecycle.
370
397
  return {
371
398
  data: {
372
399
  index: nextIndex,
@@ -378,27 +405,27 @@ const flip = function (options) {
378
405
  };
379
406
  }
380
407
 
381
- let resetPlacement = 'bottom';
382
-
383
- switch (fallbackStrategy) {
384
- case 'bestFit':
385
- {
386
- var _overflowsData$map$so;
387
-
388
- const placement = (_overflowsData$map$so = overflowsData.map(d => [d, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0].placement;
389
-
390
- if (placement) {
391
- resetPlacement = placement;
408
+ // First, find the candidates that fit on the mainAxis side of overflow,
409
+ // then find the placement that fits the best on the main crossAxis side.
410
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
411
+
412
+ // Otherwise fallback.
413
+ if (!resetPlacement) {
414
+ switch (fallbackStrategy) {
415
+ case 'bestFit':
416
+ {
417
+ var _overflowsData$map$so;
418
+ const placement = (_overflowsData$map$so = overflowsData.map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$map$so[0];
419
+ if (placement) {
420
+ resetPlacement = placement;
421
+ }
422
+ break;
392
423
  }
393
-
424
+ case 'initialPlacement':
425
+ resetPlacement = initialPlacement;
394
426
  break;
395
- }
396
-
397
- case 'initialPlacement':
398
- resetPlacement = initialPlacement;
399
- break;
427
+ }
400
428
  }
401
-
402
429
  if (placement !== resetPlacement) {
403
430
  return {
404
431
  reset: {
@@ -407,27 +434,26 @@ const flip = function (options) {
407
434
  };
408
435
  }
409
436
  }
410
-
411
437
  return {};
412
438
  }
413
-
414
439
  };
415
440
  };
416
441
 
417
- async function convertValueToCoords(middlewareArguments, value) {
442
+ async function convertValueToCoords(state, value) {
418
443
  const {
419
444
  placement,
420
445
  platform,
421
446
  elements
422
- } = middlewareArguments;
447
+ } = state;
423
448
  const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
424
449
  const side = getSide(placement);
425
450
  const alignment = getAlignment(placement);
426
451
  const isVertical = getMainAxisFromPlacement(placement) === 'x';
427
452
  const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1;
428
453
  const crossAxisMulti = rtl && isVertical ? -1 : 1;
429
- const rawValue = typeof value === 'function' ? value(middlewareArguments) : value; // eslint-disable-next-line prefer-const
454
+ const rawValue = typeof value === 'function' ? value(state) : value;
430
455
 
456
+ // eslint-disable-next-line prefer-const
431
457
  let {
432
458
  mainAxis,
433
459
  crossAxis,
@@ -442,11 +468,9 @@ async function convertValueToCoords(middlewareArguments, value) {
442
468
  alignmentAxis: null,
443
469
  ...rawValue
444
470
  };
445
-
446
471
  if (alignment && typeof alignmentAxis === 'number') {
447
472
  crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
448
473
  }
449
-
450
474
  return isVertical ? {
451
475
  x: crossAxis * crossAxisMulti,
452
476
  y: mainAxis * mainAxisMulti
@@ -455,67 +479,159 @@ async function convertValueToCoords(middlewareArguments, value) {
455
479
  y: crossAxis * crossAxisMulti
456
480
  };
457
481
  }
482
+
458
483
  /**
459
- * Displaces the floating element from its reference element.
484
+ * Modifies the placement by translating the floating element along the
485
+ * specified axes.
486
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
487
+ * object may be passed.
460
488
  * @see https://floating-ui.com/docs/offset
461
489
  */
462
-
463
490
  const offset = function (value) {
464
491
  if (value === void 0) {
465
492
  value = 0;
466
493
  }
467
-
468
494
  return {
469
495
  name: 'offset',
470
496
  options: value,
471
-
472
- async fn(middlewareArguments) {
497
+ async fn(state) {
473
498
  const {
474
499
  x,
475
500
  y
476
- } = middlewareArguments;
477
- const diffCoords = await convertValueToCoords(middlewareArguments, value);
501
+ } = state;
502
+ const diffCoords = await convertValueToCoords(state, value);
478
503
  return {
479
504
  x: x + diffCoords.x,
480
505
  y: y + diffCoords.y,
481
506
  data: diffCoords
482
507
  };
483
508
  }
484
-
485
509
  };
486
510
  };
487
511
 
488
- function isWindow(value) {
489
- return value && value.document && value.location && value.alert && value.setInterval;
512
+ function getCrossAxis(axis) {
513
+ return axis === 'x' ? 'y' : 'x';
490
514
  }
491
- function getWindow(node) {
492
- if (node == null) {
493
- return window;
494
- }
495
515
 
496
- if (!isWindow(node)) {
497
- const ownerDocument = node.ownerDocument;
498
- return ownerDocument ? ownerDocument.defaultView || window : window;
516
+ /**
517
+ * Optimizes the visibility of the floating element by shifting it in order to
518
+ * keep it in view when it will overflow the clipping boundary.
519
+ * @see https://floating-ui.com/docs/shift
520
+ */
521
+ const shift = function (options) {
522
+ if (options === void 0) {
523
+ options = {};
499
524
  }
525
+ return {
526
+ name: 'shift',
527
+ options,
528
+ async fn(state) {
529
+ const {
530
+ x,
531
+ y,
532
+ placement
533
+ } = state;
534
+ const {
535
+ mainAxis: checkMainAxis = true,
536
+ crossAxis: checkCrossAxis = false,
537
+ limiter = {
538
+ fn: _ref => {
539
+ let {
540
+ x,
541
+ y
542
+ } = _ref;
543
+ return {
544
+ x,
545
+ y
546
+ };
547
+ }
548
+ },
549
+ ...detectOverflowOptions
550
+ } = options;
551
+ const coords = {
552
+ x,
553
+ y
554
+ };
555
+ const overflow = await detectOverflow(state, detectOverflowOptions);
556
+ const mainAxis = getMainAxisFromPlacement(getSide(placement));
557
+ const crossAxis = getCrossAxis(mainAxis);
558
+ let mainAxisCoord = coords[mainAxis];
559
+ let crossAxisCoord = coords[crossAxis];
560
+ if (checkMainAxis) {
561
+ const minSide = mainAxis === 'y' ? 'top' : 'left';
562
+ const maxSide = mainAxis === 'y' ? 'bottom' : 'right';
563
+ const min = mainAxisCoord + overflow[minSide];
564
+ const max = mainAxisCoord - overflow[maxSide];
565
+ mainAxisCoord = within(min, mainAxisCoord, max);
566
+ }
567
+ if (checkCrossAxis) {
568
+ const minSide = crossAxis === 'y' ? 'top' : 'left';
569
+ const maxSide = crossAxis === 'y' ? 'bottom' : 'right';
570
+ const min = crossAxisCoord + overflow[minSide];
571
+ const max = crossAxisCoord - overflow[maxSide];
572
+ crossAxisCoord = within(min, crossAxisCoord, max);
573
+ }
574
+ const limitedCoords = limiter.fn({
575
+ ...state,
576
+ [mainAxis]: mainAxisCoord,
577
+ [crossAxis]: crossAxisCoord
578
+ });
579
+ return {
580
+ ...limitedCoords,
581
+ data: {
582
+ x: limitedCoords.x - x,
583
+ y: limitedCoords.y - y
584
+ }
585
+ };
586
+ }
587
+ };
588
+ };
500
589
 
501
- return node;
590
+ function getWindow(node) {
591
+ var _node$ownerDocument;
592
+ return ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
502
593
  }
503
594
 
504
- function getComputedStyle(element) {
595
+ function getComputedStyle$1(element) {
505
596
  return getWindow(element).getComputedStyle(element);
506
597
  }
507
598
 
599
+ const min = Math.min;
600
+ const max = Math.max;
601
+ const round = Math.round;
602
+
603
+ function getCssDimensions(element) {
604
+ const css = getComputedStyle$1(element);
605
+ let width = parseFloat(css.width);
606
+ let height = parseFloat(css.height);
607
+ const offsetWidth = element.offsetWidth;
608
+ const offsetHeight = element.offsetHeight;
609
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
610
+ if (shouldFallback) {
611
+ width = offsetWidth;
612
+ height = offsetHeight;
613
+ }
614
+ return {
615
+ width,
616
+ height,
617
+ fallback: shouldFallback
618
+ };
619
+ }
620
+
508
621
  function getNodeName(node) {
509
- return isWindow(node) ? '' : node ? (node.nodeName || '').toLowerCase() : '';
622
+ return isNode(node) ? (node.nodeName || '').toLowerCase() : '';
510
623
  }
511
624
 
625
+ let uaString;
512
626
  function getUAString() {
627
+ if (uaString) {
628
+ return uaString;
629
+ }
513
630
  const uaData = navigator.userAgentData;
514
-
515
- if (uaData != null && uaData.brands) {
516
- return uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
631
+ if (uaData && Array.isArray(uaData.brands)) {
632
+ uaString = uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
633
+ return uaString;
517
634
  }
518
-
519
635
  return navigator.userAgent;
520
636
  }
521
637
 
@@ -529,82 +645,142 @@ function isNode(value) {
529
645
  return value instanceof getWindow(value).Node;
530
646
  }
531
647
  function isShadowRoot(node) {
532
- // Browsers without `ShadowRoot` support
648
+ // Browsers without `ShadowRoot` support.
533
649
  if (typeof ShadowRoot === 'undefined') {
534
650
  return false;
535
651
  }
536
-
537
652
  const OwnElement = getWindow(node).ShadowRoot;
538
653
  return node instanceof OwnElement || node instanceof ShadowRoot;
539
654
  }
540
655
  function isOverflowElement(element) {
541
- // Firefox wants us to check `-x` and `-y` variations as well
542
656
  const {
543
657
  overflow,
544
658
  overflowX,
545
659
  overflowY,
546
660
  display
547
- } = getComputedStyle(element);
548
- return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
661
+ } = getComputedStyle$1(element);
662
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
549
663
  }
550
664
  function isTableElement(element) {
551
665
  return ['table', 'td', 'th'].includes(getNodeName(element));
552
666
  }
553
667
  function isContainingBlock(element) {
554
- // TODO: Try and use feature detection here instead
668
+ // TODO: Try to use feature detection here instead.
555
669
  const isFirefox = /firefox/i.test(getUAString());
556
- const css = getComputedStyle(element); // This is non-exhaustive but covers the most common CSS properties that
670
+ const css = getComputedStyle$1(element);
671
+ const backdropFilter = css.backdropFilter || css.WebkitBackdropFilter;
672
+
673
+ // This is non-exhaustive but covers the most common CSS properties that
557
674
  // create a containing block.
558
675
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
559
-
560
- return css.transform !== 'none' || css.perspective !== 'none' || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective'].some(value => css.willChange.includes(value)) || ['paint', 'layout', 'strict', 'content'].some( // TS 4.1 compat
561
- value => {
676
+ return css.transform !== 'none' || css.perspective !== 'none' || (backdropFilter ? backdropFilter !== 'none' : false) || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective'].some(value => css.willChange.includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => {
677
+ // Add type check for old browsers.
562
678
  const contain = css.contain;
563
679
  return contain != null ? contain.includes(value) : false;
564
680
  });
565
681
  }
566
- function isLayoutViewport() {
567
- // Not Safari
568
- return !/^((?!chrome|android).)*safari/i.test(getUAString()); // Feature detection for this fails in various ways
682
+
683
+ /**
684
+ * Determines whether or not `.getBoundingClientRect()` is affected by visual
685
+ * viewport offsets. In Safari, the `x`/`y` offsets are values relative to the
686
+ * visual viewport, while in other engines, they are values relative to the
687
+ * layout viewport.
688
+ */
689
+ function isClientRectVisualViewportBased() {
690
+ // TODO: Try to use feature detection here instead. Feature detection for
691
+ // this can fail in various ways, making the userAgent check the most
692
+ // reliable:
569
693
  // • Always-visible scrollbar or not
570
- // • Width of <html>, etc.
571
- // const vV = win.visualViewport;
572
- // return vV ? Math.abs(win.innerWidth / vV.scale - vV.width) < 0.5 : true;
694
+ // • Width of <html>
695
+
696
+ // Is Safari.
697
+ return /^((?!chrome|android).)*safari/i.test(getUAString());
573
698
  }
574
699
  function isLastTraversableNode(node) {
575
700
  return ['html', 'body', '#document'].includes(getNodeName(node));
576
701
  }
577
702
 
578
- const min = Math.min;
579
- const max = Math.max;
580
- const round = Math.round;
703
+ function unwrapElement(element) {
704
+ return !isElement(element) ? element.contextElement : element;
705
+ }
706
+
707
+ const FALLBACK_SCALE = {
708
+ x: 1,
709
+ y: 1
710
+ };
711
+ function getScale(element) {
712
+ const domElement = unwrapElement(element);
713
+ if (!isHTMLElement(domElement)) {
714
+ return FALLBACK_SCALE;
715
+ }
716
+ const rect = domElement.getBoundingClientRect();
717
+ const {
718
+ width,
719
+ height,
720
+ fallback
721
+ } = getCssDimensions(domElement);
722
+ let x = (fallback ? round(rect.width) : rect.width) / width;
723
+ let y = (fallback ? round(rect.height) : rect.height) / height;
581
724
 
582
- function getBoundingClientRect(element, includeScale, isFixedStrategy) {
583
- var _win$visualViewport$o, _win$visualViewport, _win$visualViewport$o2, _win$visualViewport2;
725
+ // 0, NaN, or Infinity should always fallback to 1.
584
726
 
727
+ if (!x || !Number.isFinite(x)) {
728
+ x = 1;
729
+ }
730
+ if (!y || !Number.isFinite(y)) {
731
+ y = 1;
732
+ }
733
+ return {
734
+ x,
735
+ y
736
+ };
737
+ }
738
+
739
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
740
+ var _win$visualViewport, _win$visualViewport2;
585
741
  if (includeScale === void 0) {
586
742
  includeScale = false;
587
743
  }
588
-
589
744
  if (isFixedStrategy === void 0) {
590
745
  isFixedStrategy = false;
591
746
  }
592
-
593
747
  const clientRect = element.getBoundingClientRect();
594
- let scaleX = 1;
595
- let scaleY = 1;
596
-
597
- if (includeScale && isHTMLElement(element)) {
598
- scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
599
- scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
748
+ const domElement = unwrapElement(element);
749
+ let scale = FALLBACK_SCALE;
750
+ if (includeScale) {
751
+ if (offsetParent) {
752
+ if (isElement(offsetParent)) {
753
+ scale = getScale(offsetParent);
754
+ }
755
+ } else {
756
+ scale = getScale(element);
757
+ }
758
+ }
759
+ const win = domElement ? getWindow(domElement) : window;
760
+ const addVisualOffsets = isClientRectVisualViewportBased() && isFixedStrategy;
761
+ let x = (clientRect.left + (addVisualOffsets ? ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0 : 0)) / scale.x;
762
+ let y = (clientRect.top + (addVisualOffsets ? ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0 : 0)) / scale.y;
763
+ let width = clientRect.width / scale.x;
764
+ let height = clientRect.height / scale.y;
765
+ if (domElement) {
766
+ const win = getWindow(domElement);
767
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
768
+ let currentIFrame = win.frameElement;
769
+ while (currentIFrame && offsetParent && offsetWin !== win) {
770
+ const iframeScale = getScale(currentIFrame);
771
+ const iframeRect = currentIFrame.getBoundingClientRect();
772
+ const css = getComputedStyle(currentIFrame);
773
+ iframeRect.x += (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
774
+ iframeRect.y += (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
775
+ x *= iframeScale.x;
776
+ y *= iframeScale.y;
777
+ width *= iframeScale.x;
778
+ height *= iframeScale.y;
779
+ x += iframeRect.x;
780
+ y += iframeRect.y;
781
+ currentIFrame = getWindow(currentIFrame).frameElement;
782
+ }
600
783
  }
601
-
602
- const win = isElement(element) ? getWindow(element) : window;
603
- const addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
604
- const x = (clientRect.left + (addVisualOffsets ? (_win$visualViewport$o = (_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) != null ? _win$visualViewport$o : 0 : 0)) / scaleX;
605
- const y = (clientRect.top + (addVisualOffsets ? (_win$visualViewport$o2 = (_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) != null ? _win$visualViewport$o2 : 0 : 0)) / scaleY;
606
- const width = clientRect.width / scaleX;
607
- const height = clientRect.height / scaleY;
608
784
  return {
609
785
  width,
610
786
  height,
@@ -628,134 +804,12 @@ function getNodeScroll(element) {
628
804
  scrollTop: element.scrollTop
629
805
  };
630
806
  }
631
-
632
807
  return {
633
808
  scrollLeft: element.pageXOffset,
634
809
  scrollTop: element.pageYOffset
635
810
  };
636
811
  }
637
812
 
638
- function getWindowScrollBarX(element) {
639
- // If <html> has a CSS width greater than the viewport, then this will be
640
- // incorrect for RTL.
641
- return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
642
- }
643
-
644
- function isScaled(element) {
645
- const rect = getBoundingClientRect(element);
646
- return round(rect.width) !== element.offsetWidth || round(rect.height) !== element.offsetHeight;
647
- }
648
-
649
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
650
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
651
- const documentElement = getDocumentElement(offsetParent);
652
- const rect = getBoundingClientRect(element, // @ts-ignore - checked above (TS 4.1 compat)
653
- isOffsetParentAnElement && isScaled(offsetParent), strategy === 'fixed');
654
- let scroll = {
655
- scrollLeft: 0,
656
- scrollTop: 0
657
- };
658
- const offsets = {
659
- x: 0,
660
- y: 0
661
- };
662
-
663
- if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
664
- if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
665
- scroll = getNodeScroll(offsetParent);
666
- }
667
-
668
- if (isHTMLElement(offsetParent)) {
669
- const offsetRect = getBoundingClientRect(offsetParent, true);
670
- offsets.x = offsetRect.x + offsetParent.clientLeft;
671
- offsets.y = offsetRect.y + offsetParent.clientTop;
672
- } else if (documentElement) {
673
- offsets.x = getWindowScrollBarX(documentElement);
674
- }
675
- }
676
-
677
- return {
678
- x: rect.left + scroll.scrollLeft - offsets.x,
679
- y: rect.top + scroll.scrollTop - offsets.y,
680
- width: rect.width,
681
- height: rect.height
682
- };
683
- }
684
-
685
- function getParentNode(node) {
686
- if (getNodeName(node) === 'html') {
687
- return node;
688
- }
689
-
690
- return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
691
- // @ts-ignore
692
- node.assignedSlot || // step into the shadow DOM of the parent of a slotted node
693
- node.parentNode || ( // DOM Element detected
694
- isShadowRoot(node) ? node.host : null) || // ShadowRoot detected
695
- getDocumentElement(node) // fallback
696
-
697
- );
698
- }
699
-
700
- function getTrueOffsetParent(element) {
701
- if (!isHTMLElement(element) || getComputedStyle(element).position === 'fixed') {
702
- return null;
703
- }
704
-
705
- return element.offsetParent;
706
- }
707
-
708
- function getContainingBlock(element) {
709
- let currentNode = getParentNode(element);
710
-
711
- if (isShadowRoot(currentNode)) {
712
- currentNode = currentNode.host;
713
- }
714
-
715
- while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
716
- if (isContainingBlock(currentNode)) {
717
- return currentNode;
718
- } else {
719
- const parent = currentNode.parentNode;
720
- currentNode = isShadowRoot(parent) ? parent.host : parent;
721
- }
722
- }
723
-
724
- return null;
725
- } // Gets the closest ancestor positioned element. Handles some edge cases,
726
- // such as table ancestors and cross browser bugs.
727
-
728
-
729
- function getOffsetParent(element) {
730
- const window = getWindow(element);
731
- let offsetParent = getTrueOffsetParent(element);
732
-
733
- while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {
734
- offsetParent = getTrueOffsetParent(offsetParent);
735
- }
736
-
737
- if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
738
- return window;
739
- }
740
-
741
- return offsetParent || getContainingBlock(element) || window;
742
- }
743
-
744
- function getDimensions(element) {
745
- if (isHTMLElement(element)) {
746
- return {
747
- width: element.offsetWidth,
748
- height: element.offsetHeight
749
- };
750
- }
751
-
752
- const rect = getBoundingClientRect(element);
753
- return {
754
- width: rect.width,
755
- height: rect.height
756
- };
757
- }
758
-
759
813
  function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
760
814
  let {
761
815
  rect,
@@ -764,87 +818,59 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
764
818
  } = _ref;
765
819
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
766
820
  const documentElement = getDocumentElement(offsetParent);
767
-
768
821
  if (offsetParent === documentElement) {
769
822
  return rect;
770
823
  }
771
-
772
824
  let scroll = {
773
825
  scrollLeft: 0,
774
826
  scrollTop: 0
775
827
  };
828
+ let scale = {
829
+ x: 1,
830
+ y: 1
831
+ };
776
832
  const offsets = {
777
833
  x: 0,
778
834
  y: 0
779
835
  };
780
-
781
836
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
782
837
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
783
838
  scroll = getNodeScroll(offsetParent);
784
839
  }
785
-
786
840
  if (isHTMLElement(offsetParent)) {
787
- const offsetRect = getBoundingClientRect(offsetParent, true);
841
+ const offsetRect = getBoundingClientRect(offsetParent);
842
+ scale = getScale(offsetParent);
788
843
  offsets.x = offsetRect.x + offsetParent.clientLeft;
789
844
  offsets.y = offsetRect.y + offsetParent.clientTop;
790
- } // This doesn't appear to be need to be negated.
791
- // else if (documentElement) {
792
- // offsets.x = getWindowScrollBarX(documentElement);
793
- // }
794
-
795
- }
796
-
797
- return { ...rect,
798
- x: rect.x - scroll.scrollLeft + offsets.x,
799
- y: rect.y - scroll.scrollTop + offsets.y
800
- };
801
- }
802
-
803
- function getViewportRect(element, strategy) {
804
- const win = getWindow(element);
805
- const html = getDocumentElement(element);
806
- const visualViewport = win.visualViewport;
807
- let width = html.clientWidth;
808
- let height = html.clientHeight;
809
- let x = 0;
810
- let y = 0;
811
-
812
- if (visualViewport) {
813
- width = visualViewport.width;
814
- height = visualViewport.height;
815
- const layoutViewport = isLayoutViewport();
816
-
817
- if (layoutViewport || !layoutViewport && strategy === 'fixed') {
818
- x = visualViewport.offsetLeft;
819
- y = visualViewport.offsetTop;
820
845
  }
821
846
  }
822
-
823
847
  return {
824
- width,
825
- height,
826
- x,
827
- y
848
+ width: rect.width * scale.x,
849
+ height: rect.height * scale.y,
850
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
851
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y
828
852
  };
829
853
  }
830
854
 
831
- // of the `<html>` and `<body>` rect bounds if horizontally scrollable
855
+ function getWindowScrollBarX(element) {
856
+ // If <html> has a CSS width greater than the viewport, then this will be
857
+ // incorrect for RTL.
858
+ return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
859
+ }
832
860
 
861
+ // Gets the entire size of the scrollable document area, even extending outside
862
+ // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
833
863
  function getDocumentRect(element) {
834
- var _element$ownerDocumen;
835
-
836
864
  const html = getDocumentElement(element);
837
865
  const scroll = getNodeScroll(element);
838
- const body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
839
- const width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
840
- const height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
866
+ const body = element.ownerDocument.body;
867
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
868
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
841
869
  let x = -scroll.scrollLeft + getWindowScrollBarX(element);
842
870
  const y = -scroll.scrollTop;
843
-
844
- if (getComputedStyle(body || html).direction === 'rtl') {
845
- x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
871
+ if (getComputedStyle$1(body).direction === 'rtl') {
872
+ x += max(html.clientWidth, body.clientWidth) - width;
846
873
  }
847
-
848
874
  return {
849
875
  width,
850
876
  height,
@@ -853,132 +879,155 @@ function getDocumentRect(element) {
853
879
  };
854
880
  }
855
881
 
882
+ function getParentNode(node) {
883
+ if (getNodeName(node) === 'html') {
884
+ return node;
885
+ }
886
+ const result =
887
+ // Step into the shadow DOM of the parent of a slotted node.
888
+ node.assignedSlot ||
889
+ // DOM Element detected.
890
+ node.parentNode ||
891
+ // ShadowRoot detected.
892
+ isShadowRoot(node) && node.host ||
893
+ // Fallback.
894
+ getDocumentElement(node);
895
+ return isShadowRoot(result) ? result.host : result;
896
+ }
897
+
856
898
  function getNearestOverflowAncestor(node) {
857
899
  const parentNode = getParentNode(node);
858
-
859
900
  if (isLastTraversableNode(parentNode)) {
860
- // @ts-ignore assume body is always available
861
- return node.ownerDocument.body;
901
+ // `getParentNode` will never return a `Document` due to the fallback
902
+ // check, so it's either the <html> or <body> element.
903
+ return parentNode.ownerDocument.body;
862
904
  }
863
-
864
905
  if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
865
906
  return parentNode;
866
907
  }
867
-
868
908
  return getNearestOverflowAncestor(parentNode);
869
909
  }
870
910
 
871
911
  function getOverflowAncestors(node, list) {
872
912
  var _node$ownerDocument;
873
-
874
913
  if (list === void 0) {
875
914
  list = [];
876
915
  }
877
-
878
916
  const scrollableAncestor = getNearestOverflowAncestor(node);
879
917
  const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
880
918
  const win = getWindow(scrollableAncestor);
881
- const target = isBody ? [win].concat(win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []) : scrollableAncestor;
882
- const updatedList = list.concat(target);
883
- return isBody ? updatedList : // @ts-ignore: isBody tells us target will be an HTMLElement here
884
- updatedList.concat(getOverflowAncestors(target));
885
- }
886
-
887
- function contains(parent, child) {
888
- const rootNode = child.getRootNode == null ? void 0 : child.getRootNode(); // First, attempt with faster native method
889
-
890
- if (parent.contains(child)) {
891
- return true;
892
- } // then fallback to custom implementation with Shadow DOM support
893
- else if (rootNode && isShadowRoot(rootNode)) {
894
- let next = child;
895
-
896
- do {
897
- // use `===` replace node.isSameNode()
898
- if (next && parent === next) {
899
- return true;
900
- } // @ts-ignore: need a better way to handle this...
901
-
902
-
903
- next = next.parentNode || next.host;
904
- } while (next);
919
+ if (isBody) {
920
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []);
905
921
  }
906
-
907
- return false;
922
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor));
908
923
  }
909
924
 
910
- function getNearestParentCapableOfEscapingClipping(element, clippingAncestors) {
911
- let currentNode = element;
912
-
913
- while (currentNode && !isLastTraversableNode(currentNode) && // @ts-expect-error
914
- !clippingAncestors.includes(currentNode)) {
915
- if (isElement(currentNode) && ['absolute', 'fixed'].includes(getComputedStyle(currentNode).position)) {
916
- break;
925
+ function getViewportRect(element, strategy) {
926
+ const win = getWindow(element);
927
+ const html = getDocumentElement(element);
928
+ const visualViewport = win.visualViewport;
929
+ let width = html.clientWidth;
930
+ let height = html.clientHeight;
931
+ let x = 0;
932
+ let y = 0;
933
+ if (visualViewport) {
934
+ width = visualViewport.width;
935
+ height = visualViewport.height;
936
+ const visualViewportBased = isClientRectVisualViewportBased();
937
+ if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
938
+ x = visualViewport.offsetLeft;
939
+ y = visualViewport.offsetTop;
917
940
  }
918
-
919
- const parentNode = getParentNode(currentNode);
920
- currentNode = isShadowRoot(parentNode) ? parentNode.host : parentNode;
921
941
  }
922
-
923
- return currentNode;
942
+ return {
943
+ width,
944
+ height,
945
+ x,
946
+ y
947
+ };
924
948
  }
925
949
 
950
+ // Returns the inner client rect, subtracting scrollbars if present.
926
951
  function getInnerBoundingClientRect(element, strategy) {
927
- const clientRect = getBoundingClientRect(element, false, strategy === 'fixed');
952
+ const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
928
953
  const top = clientRect.top + element.clientTop;
929
954
  const left = clientRect.left + element.clientLeft;
955
+ const scale = isHTMLElement(element) ? getScale(element) : {
956
+ x: 1,
957
+ y: 1
958
+ };
959
+ const width = element.clientWidth * scale.x;
960
+ const height = element.clientHeight * scale.y;
961
+ const x = left * scale.x;
962
+ const y = top * scale.y;
930
963
  return {
931
- top,
932
- left,
933
- x: left,
934
- y: top,
935
- right: left + element.clientWidth,
936
- bottom: top + element.clientHeight,
937
- width: element.clientWidth,
938
- height: element.clientHeight
964
+ width,
965
+ height,
966
+ x,
967
+ y
939
968
  };
940
969
  }
941
-
942
- function getClientRectFromClippingAncestor(element, clippingParent, strategy) {
943
- if (clippingParent === 'viewport') {
944
- return rectToClientRect(getViewportRect(element, strategy));
970
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
971
+ let rect;
972
+ if (clippingAncestor === 'viewport') {
973
+ rect = getViewportRect(element, strategy);
974
+ } else if (clippingAncestor === 'document') {
975
+ rect = getDocumentRect(getDocumentElement(element));
976
+ } else if (isElement(clippingAncestor)) {
977
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
978
+ } else {
979
+ const mutableRect = {
980
+ ...clippingAncestor
981
+ };
982
+ if (isClientRectVisualViewportBased()) {
983
+ var _win$visualViewport, _win$visualViewport2;
984
+ const win = getWindow(element);
985
+ mutableRect.x -= ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0;
986
+ mutableRect.y -= ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0;
987
+ }
988
+ rect = mutableRect;
945
989
  }
990
+ return rectToClientRect(rect);
991
+ }
946
992
 
947
- if (isElement(clippingParent)) {
948
- return getInnerBoundingClientRect(clippingParent, strategy);
993
+ // A "clipping ancestor" is an `overflow` element with the characteristic of
994
+ // clipping (or hiding) child elements. This returns all clipping ancestors
995
+ // of the given element up the tree.
996
+ function getClippingElementAncestors(element, cache) {
997
+ const cachedResult = cache.get(element);
998
+ if (cachedResult) {
999
+ return cachedResult;
949
1000
  }
1001
+ let result = getOverflowAncestors(element).filter(el => isElement(el) && getNodeName(el) !== 'body');
1002
+ let currentContainingBlockComputedStyle = null;
1003
+ const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
1004
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
950
1005
 
951
- return rectToClientRect(getDocumentRect(getDocumentElement(element)));
952
- } // A "clipping ancestor" is an overflowable container with the characteristic of
953
- // clipping (or hiding) overflowing elements with a position different from
954
- // `initial`
955
-
956
-
957
- function getClippingAncestors(element) {
958
- const clippingAncestors = getOverflowAncestors(element);
959
- const nearestEscapableParent = getNearestParentCapableOfEscapingClipping(element, clippingAncestors);
960
- let clipperElement = null;
961
-
962
- if (nearestEscapableParent && isHTMLElement(nearestEscapableParent)) {
963
- const offsetParent = getOffsetParent(nearestEscapableParent);
964
-
965
- if (isOverflowElement(nearestEscapableParent)) {
966
- clipperElement = nearestEscapableParent;
967
- } else if (isHTMLElement(offsetParent)) {
968
- clipperElement = offsetParent;
1006
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1007
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
1008
+ const computedStyle = getComputedStyle$1(currentNode);
1009
+ const containingBlock = isContainingBlock(currentNode);
1010
+ const shouldIgnoreCurrentNode = computedStyle.position === 'fixed';
1011
+ if (shouldIgnoreCurrentNode) {
1012
+ currentContainingBlockComputedStyle = null;
1013
+ } else {
1014
+ const shouldDropCurrentNode = elementIsFixed ? !containingBlock && !currentContainingBlockComputedStyle : !containingBlock && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position);
1015
+ if (shouldDropCurrentNode) {
1016
+ // Drop non-containing blocks.
1017
+ result = result.filter(ancestor => ancestor !== currentNode);
1018
+ } else {
1019
+ // Record last containing block for next iteration.
1020
+ currentContainingBlockComputedStyle = computedStyle;
1021
+ }
969
1022
  }
1023
+ currentNode = getParentNode(currentNode);
970
1024
  }
1025
+ cache.set(element, result);
1026
+ return result;
1027
+ }
971
1028
 
972
- if (!isElement(clipperElement)) {
973
- return [];
974
- } // @ts-ignore isElement check ensures we return Array<Element>
975
-
976
-
977
- return clippingAncestors.filter(clippingAncestors => clipperElement && isElement(clippingAncestors) && contains(clippingAncestors, clipperElement) && getNodeName(clippingAncestors) !== 'body');
978
- } // Gets the maximum area that the element is visible in due to any number of
979
- // clipping ancestors
980
-
981
-
1029
+ // Gets the maximum area that the element is visible in due to any number of
1030
+ // clipping ancestors.
982
1031
  function getClippingRect(_ref) {
983
1032
  let {
984
1033
  element,
@@ -986,8 +1035,8 @@ function getClippingRect(_ref) {
986
1035
  rootBoundary,
987
1036
  strategy
988
1037
  } = _ref;
989
- const mainClippingAncestors = boundary === 'clippingAncestors' ? getClippingAncestors(element) : [].concat(boundary);
990
- const clippingAncestors = [...mainClippingAncestors, rootBoundary];
1038
+ const elementClippingAncestors = boundary === 'clippingAncestors' ? getClippingElementAncestors(element, this._c) : [].concat(boundary);
1039
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
991
1040
  const firstClippingAncestor = clippingAncestors[0];
992
1041
  const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
993
1042
  const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
@@ -1005,6 +1054,80 @@ function getClippingRect(_ref) {
1005
1054
  };
1006
1055
  }
1007
1056
 
1057
+ function getDimensions(element) {
1058
+ if (isHTMLElement(element)) {
1059
+ return getCssDimensions(element);
1060
+ }
1061
+ return element.getBoundingClientRect();
1062
+ }
1063
+
1064
+ function getTrueOffsetParent(element, polyfill) {
1065
+ if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
1066
+ return null;
1067
+ }
1068
+ if (polyfill) {
1069
+ return polyfill(element);
1070
+ }
1071
+ return element.offsetParent;
1072
+ }
1073
+ function getContainingBlock(element) {
1074
+ let currentNode = getParentNode(element);
1075
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
1076
+ if (isContainingBlock(currentNode)) {
1077
+ return currentNode;
1078
+ } else {
1079
+ currentNode = getParentNode(currentNode);
1080
+ }
1081
+ }
1082
+ return null;
1083
+ }
1084
+
1085
+ // Gets the closest ancestor positioned element. Handles some edge cases,
1086
+ // such as table ancestors and cross browser bugs.
1087
+ function getOffsetParent(element, polyfill) {
1088
+ const window = getWindow(element);
1089
+ let offsetParent = getTrueOffsetParent(element, polyfill);
1090
+ while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
1091
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
1092
+ }
1093
+ if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
1094
+ return window;
1095
+ }
1096
+ return offsetParent || getContainingBlock(element) || window;
1097
+ }
1098
+
1099
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1100
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
1101
+ const documentElement = getDocumentElement(offsetParent);
1102
+ const rect = getBoundingClientRect(element, true, strategy === 'fixed', offsetParent);
1103
+ let scroll = {
1104
+ scrollLeft: 0,
1105
+ scrollTop: 0
1106
+ };
1107
+ const offsets = {
1108
+ x: 0,
1109
+ y: 0
1110
+ };
1111
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
1112
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
1113
+ scroll = getNodeScroll(offsetParent);
1114
+ }
1115
+ if (isHTMLElement(offsetParent)) {
1116
+ const offsetRect = getBoundingClientRect(offsetParent, true);
1117
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
1118
+ offsets.y = offsetRect.y + offsetParent.clientTop;
1119
+ } else if (documentElement) {
1120
+ offsets.x = getWindowScrollBarX(documentElement);
1121
+ }
1122
+ }
1123
+ return {
1124
+ x: rect.left + scroll.scrollLeft - offsets.x,
1125
+ y: rect.top + scroll.scrollTop - offsets.y,
1126
+ width: rect.width,
1127
+ height: rect.height
1128
+ };
1129
+ }
1130
+
1008
1131
  const platform = {
1009
1132
  getClippingRect,
1010
1133
  convertOffsetParentRelativeRectToViewportRelativeRect,
@@ -1012,33 +1135,40 @@ const platform = {
1012
1135
  getDimensions,
1013
1136
  getOffsetParent,
1014
1137
  getDocumentElement,
1015
- getElementRects: _ref => {
1138
+ getScale,
1139
+ async getElementRects(_ref) {
1016
1140
  let {
1017
1141
  reference,
1018
1142
  floating,
1019
1143
  strategy
1020
1144
  } = _ref;
1145
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1146
+ const getDimensionsFn = this.getDimensions;
1021
1147
  return {
1022
- reference: getRectRelativeToOffsetParent(reference, getOffsetParent(floating), strategy),
1023
- floating: { ...getDimensions(floating),
1148
+ reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy),
1149
+ floating: {
1024
1150
  x: 0,
1025
- y: 0
1151
+ y: 0,
1152
+ ...(await getDimensionsFn(floating))
1026
1153
  }
1027
1154
  };
1028
1155
  },
1029
1156
  getClientRects: element => Array.from(element.getClientRects()),
1030
- isRTL: element => getComputedStyle(element).direction === 'rtl'
1157
+ isRTL: element => getComputedStyle$1(element).direction === 'rtl'
1031
1158
  };
1032
1159
 
1033
1160
  /**
1034
1161
  * Automatically updates the position of the floating element when necessary.
1162
+ * Should only be called when the floating element is mounted on the DOM or
1163
+ * visible on the screen.
1164
+ * @returns cleanup function that should be invoked when the floating element is
1165
+ * removed from the DOM or hidden from the screen.
1035
1166
  * @see https://floating-ui.com/docs/autoUpdate
1036
1167
  */
1037
1168
  function autoUpdate(reference, floating, update, options) {
1038
1169
  if (options === void 0) {
1039
1170
  options = {};
1040
1171
  }
1041
-
1042
1172
  const {
1043
1173
  ancestorScroll: _ancestorScroll = true,
1044
1174
  ancestorResize = true,
@@ -1046,7 +1176,7 @@ function autoUpdate(reference, floating, update, options) {
1046
1176
  animationFrame = false
1047
1177
  } = options;
1048
1178
  const ancestorScroll = _ancestorScroll && !animationFrame;
1049
- const ancestors = ancestorScroll || ancestorResize ? [...(isElement(reference) ? getOverflowAncestors(reference) : []), ...getOverflowAncestors(floating)] : [];
1179
+ const ancestors = ancestorScroll || ancestorResize ? [...(isElement(reference) ? getOverflowAncestors(reference) : reference.contextElement ? getOverflowAncestors(reference.contextElement) : []), ...getOverflowAncestors(floating)] : [];
1050
1180
  ancestors.forEach(ancestor => {
1051
1181
  ancestorScroll && ancestor.addEventListener('scroll', update, {
1052
1182
  passive: true
@@ -1054,49 +1184,42 @@ function autoUpdate(reference, floating, update, options) {
1054
1184
  ancestorResize && ancestor.addEventListener('resize', update);
1055
1185
  });
1056
1186
  let observer = null;
1057
-
1058
1187
  if (elementResize) {
1059
1188
  let initialUpdate = true;
1060
1189
  observer = new ResizeObserver(() => {
1061
1190
  if (!initialUpdate) {
1062
1191
  update();
1063
1192
  }
1064
-
1065
1193
  initialUpdate = false;
1066
1194
  });
1067
1195
  isElement(reference) && !animationFrame && observer.observe(reference);
1196
+ if (!isElement(reference) && reference.contextElement && !animationFrame) {
1197
+ observer.observe(reference.contextElement);
1198
+ }
1068
1199
  observer.observe(floating);
1069
1200
  }
1070
-
1071
1201
  let frameId;
1072
1202
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
1073
-
1074
1203
  if (animationFrame) {
1075
1204
  frameLoop();
1076
1205
  }
1077
-
1078
1206
  function frameLoop() {
1079
1207
  const nextRefRect = getBoundingClientRect(reference);
1080
-
1081
1208
  if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) {
1082
1209
  update();
1083
1210
  }
1084
-
1085
1211
  prevRefRect = nextRefRect;
1086
1212
  frameId = requestAnimationFrame(frameLoop);
1087
1213
  }
1088
-
1089
1214
  update();
1090
1215
  return () => {
1091
1216
  var _observer;
1092
-
1093
1217
  ancestors.forEach(ancestor => {
1094
1218
  ancestorScroll && ancestor.removeEventListener('scroll', update);
1095
1219
  ancestorResize && ancestor.removeEventListener('resize', update);
1096
1220
  });
1097
1221
  (_observer = observer) == null ? void 0 : _observer.disconnect();
1098
1222
  observer = null;
1099
-
1100
1223
  if (animationFrame) {
1101
1224
  cancelAnimationFrame(frameId);
1102
1225
  }
@@ -1108,12 +1231,25 @@ function autoUpdate(reference, floating, update, options) {
1108
1231
  * next to a reference element when it is given a certain CSS positioning
1109
1232
  * strategy.
1110
1233
  */
1234
+ const computePosition = (reference, floating, options) => {
1235
+ // This caches the expensive `getClippingElementAncestors` function so that
1236
+ // multiple lifecycle resets re-use the same result. It only lives for a
1237
+ // single call. If other functions become expensive, we can add them as well.
1238
+ const cache = new Map();
1239
+ const mergedOptions = {
1240
+ platform,
1241
+ ...options
1242
+ };
1243
+ const platformWithCache = {
1244
+ ...mergedOptions.platform,
1245
+ _c: cache
1246
+ };
1247
+ return computePosition$1(reference, floating, {
1248
+ ...mergedOptions,
1249
+ platform: platformWithCache
1250
+ });
1251
+ };
1111
1252
 
1112
- const computePosition = (reference, floating, options) => computePosition$1(reference, floating, {
1113
- platform,
1114
- ...options
1115
- });
1116
-
1117
- export { autoUpdate as a, computePosition as c, flip as f, offset as o };
1253
+ export { autoUpdate as a, computePosition as c, flip as f, offset as o, shift as s };
1118
1254
 
1119
1255
  //# sourceMappingURL=floating-ui.dom.esm.js.map