@atlaskit/top-layer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +151 -0
  3. package/animations/package.json +17 -0
  4. package/arrow/package.json +17 -0
  5. package/create-close-event/package.json +17 -0
  6. package/dialog/package.json +17 -0
  7. package/dialog-scroll-lock/package.json +17 -0
  8. package/dist/cjs/animations/presets.js +199 -0
  9. package/dist/cjs/animations/types.js +5 -0
  10. package/dist/cjs/arrow/index.js +130 -0
  11. package/dist/cjs/arrow/types.js +5 -0
  12. package/dist/cjs/dialog/create-close-event.js +39 -0
  13. package/dist/cjs/dialog/dialog-content.compiled.css +14 -0
  14. package/dist/cjs/dialog/dialog-content.js +144 -0
  15. package/dist/cjs/dialog/index.js +19 -0
  16. package/dist/cjs/dialog/types.js +5 -0
  17. package/dist/cjs/dialog-scroll-lock/index.js +46 -0
  18. package/dist/cjs/entry-points/animations.js +36 -0
  19. package/dist/cjs/entry-points/arrow.js +12 -0
  20. package/dist/cjs/entry-points/create-close-event.js +19 -0
  21. package/dist/cjs/entry-points/dialog-scroll-lock.js +12 -0
  22. package/dist/cjs/entry-points/dialog.js +12 -0
  23. package/dist/cjs/entry-points/focus.js +24 -0
  24. package/dist/cjs/entry-points/placement-map.js +18 -0
  25. package/dist/cjs/entry-points/popover.js +12 -0
  26. package/dist/cjs/entry-points/popup-surface.js +12 -0
  27. package/dist/cjs/entry-points/popup.js +12 -0
  28. package/dist/cjs/entry-points/use-anchor-position.js +12 -0
  29. package/dist/cjs/entry-points/use-arrow-navigation.js +18 -0
  30. package/dist/cjs/entry-points/use-simple-light-dismiss.js +12 -0
  31. package/dist/cjs/focus/focus.js +115 -0
  32. package/dist/cjs/focus/index.js +24 -0
  33. package/dist/cjs/index.js +8 -0
  34. package/dist/cjs/internal/anchor-positioning-fallback.js +154 -0
  35. package/dist/cjs/internal/combine.js +29 -0
  36. package/dist/cjs/internal/ensure-preset-styles.js +34 -0
  37. package/dist/cjs/internal/reduced-motion.js +27 -0
  38. package/dist/cjs/internal/resolve-placement.js +24 -0
  39. package/dist/cjs/internal/role-types.js +66 -0
  40. package/dist/cjs/internal/set-style.js +42 -0
  41. package/dist/cjs/internal/slot.js +65 -0
  42. package/dist/cjs/internal/use-anchor-positioning.js +336 -0
  43. package/dist/cjs/internal/use-animated-visibility.js +169 -0
  44. package/dist/cjs/internal/use-animation-preset.js +24 -0
  45. package/dist/cjs/internal/use-focus-wrap.js +94 -0
  46. package/dist/cjs/internal/use-initial-focus.js +112 -0
  47. package/dist/cjs/internal/use-preset-styles.js +27 -0
  48. package/dist/cjs/placement-map/index.js +147 -0
  49. package/dist/cjs/popover/create-close-event.js +44 -0
  50. package/dist/cjs/popover/index.js +19 -0
  51. package/dist/cjs/popover/popover.compiled.css +13 -0
  52. package/dist/cjs/popover/popover.js +251 -0
  53. package/dist/cjs/popover/types.js +5 -0
  54. package/dist/cjs/popup/index.js +37 -0
  55. package/dist/cjs/popup/popup-content.js +201 -0
  56. package/dist/cjs/popup/popup-context.js +42 -0
  57. package/dist/cjs/popup/popup-surface.compiled.css +5 -0
  58. package/dist/cjs/popup/popup-surface.js +30 -0
  59. package/dist/cjs/popup/popup-trigger-function.js +74 -0
  60. package/dist/cjs/popup/popup-trigger.js +82 -0
  61. package/dist/cjs/popup/popup.js +70 -0
  62. package/dist/cjs/popup/types.js +5 -0
  63. package/dist/cjs/use-arrow-navigation/index.js +18 -0
  64. package/dist/cjs/use-arrow-navigation/use-arrow-navigation.js +245 -0
  65. package/dist/cjs/use-simple-light-dismiss/index.js +84 -0
  66. package/dist/es2019/animations/presets.js +375 -0
  67. package/dist/es2019/animations/types.js +1 -0
  68. package/dist/es2019/arrow/index.js +249 -0
  69. package/dist/es2019/arrow/types.js +1 -0
  70. package/dist/es2019/dialog/create-close-event.js +34 -0
  71. package/dist/es2019/dialog/dialog-content.compiled.css +14 -0
  72. package/dist/es2019/dialog/dialog-content.js +138 -0
  73. package/dist/es2019/dialog/index.js +2 -0
  74. package/dist/es2019/dialog/types.js +1 -0
  75. package/dist/es2019/dialog-scroll-lock/index.js +41 -0
  76. package/dist/es2019/entry-points/animations.js +1 -0
  77. package/dist/es2019/entry-points/arrow.js +1 -0
  78. package/dist/es2019/entry-points/create-close-event.js +2 -0
  79. package/dist/es2019/entry-points/dialog-scroll-lock.js +1 -0
  80. package/dist/es2019/entry-points/dialog.js +1 -0
  81. package/dist/es2019/entry-points/focus.js +1 -0
  82. package/dist/es2019/entry-points/placement-map.js +1 -0
  83. package/dist/es2019/entry-points/popover.js +1 -0
  84. package/dist/es2019/entry-points/popup-surface.js +1 -0
  85. package/dist/es2019/entry-points/popup.js +1 -0
  86. package/dist/es2019/entry-points/use-anchor-position.js +1 -0
  87. package/dist/es2019/entry-points/use-arrow-navigation.js +1 -0
  88. package/dist/es2019/entry-points/use-simple-light-dismiss.js +1 -0
  89. package/dist/es2019/focus/focus.js +107 -0
  90. package/dist/es2019/focus/index.js +1 -0
  91. package/dist/es2019/index.js +7 -0
  92. package/dist/es2019/internal/anchor-positioning-fallback.js +153 -0
  93. package/dist/es2019/internal/combine.js +18 -0
  94. package/dist/es2019/internal/ensure-preset-styles.js +29 -0
  95. package/dist/es2019/internal/reduced-motion.js +21 -0
  96. package/dist/es2019/internal/resolve-placement.js +19 -0
  97. package/dist/es2019/internal/role-types.js +61 -0
  98. package/dist/es2019/internal/set-style.js +39 -0
  99. package/dist/es2019/internal/slot.js +57 -0
  100. package/dist/es2019/internal/use-anchor-positioning.js +330 -0
  101. package/dist/es2019/internal/use-animated-visibility.js +159 -0
  102. package/dist/es2019/internal/use-animation-preset.js +18 -0
  103. package/dist/es2019/internal/use-focus-wrap.js +90 -0
  104. package/dist/es2019/internal/use-initial-focus.js +109 -0
  105. package/dist/es2019/internal/use-preset-styles.js +22 -0
  106. package/dist/es2019/placement-map/index.js +142 -0
  107. package/dist/es2019/popover/create-close-event.js +39 -0
  108. package/dist/es2019/popover/index.js +2 -0
  109. package/dist/es2019/popover/popover.compiled.css +13 -0
  110. package/dist/es2019/popover/popover.js +240 -0
  111. package/dist/es2019/popover/types.js +1 -0
  112. package/dist/es2019/popup/index.js +33 -0
  113. package/dist/es2019/popup/popup-content.js +192 -0
  114. package/dist/es2019/popup/popup-context.js +34 -0
  115. package/dist/es2019/popup/popup-surface.compiled.css +5 -0
  116. package/dist/es2019/popup/popup-surface.js +24 -0
  117. package/dist/es2019/popup/popup-trigger-function.js +69 -0
  118. package/dist/es2019/popup/popup-trigger.js +76 -0
  119. package/dist/es2019/popup/popup.js +56 -0
  120. package/dist/es2019/popup/types.js +1 -0
  121. package/dist/es2019/use-arrow-navigation/index.js +1 -0
  122. package/dist/es2019/use-arrow-navigation/use-arrow-navigation.js +238 -0
  123. package/dist/es2019/use-simple-light-dismiss/index.js +79 -0
  124. package/dist/esm/animations/presets.js +190 -0
  125. package/dist/esm/animations/types.js +1 -0
  126. package/dist/esm/arrow/index.js +123 -0
  127. package/dist/esm/arrow/types.js +1 -0
  128. package/dist/esm/dialog/create-close-event.js +33 -0
  129. package/dist/esm/dialog/dialog-content.compiled.css +14 -0
  130. package/dist/esm/dialog/dialog-content.js +135 -0
  131. package/dist/esm/dialog/index.js +2 -0
  132. package/dist/esm/dialog/types.js +1 -0
  133. package/dist/esm/dialog-scroll-lock/index.js +41 -0
  134. package/dist/esm/entry-points/animations.js +1 -0
  135. package/dist/esm/entry-points/arrow.js +1 -0
  136. package/dist/esm/entry-points/create-close-event.js +2 -0
  137. package/dist/esm/entry-points/dialog-scroll-lock.js +1 -0
  138. package/dist/esm/entry-points/dialog.js +1 -0
  139. package/dist/esm/entry-points/focus.js +1 -0
  140. package/dist/esm/entry-points/placement-map.js +1 -0
  141. package/dist/esm/entry-points/popover.js +1 -0
  142. package/dist/esm/entry-points/popup-surface.js +1 -0
  143. package/dist/esm/entry-points/popup.js +1 -0
  144. package/dist/esm/entry-points/use-anchor-position.js +1 -0
  145. package/dist/esm/entry-points/use-arrow-navigation.js +1 -0
  146. package/dist/esm/entry-points/use-simple-light-dismiss.js +1 -0
  147. package/dist/esm/focus/focus.js +107 -0
  148. package/dist/esm/focus/index.js +1 -0
  149. package/dist/esm/index.js +7 -0
  150. package/dist/esm/internal/anchor-positioning-fallback.js +147 -0
  151. package/dist/esm/internal/combine.js +23 -0
  152. package/dist/esm/internal/ensure-preset-styles.js +28 -0
  153. package/dist/esm/internal/reduced-motion.js +21 -0
  154. package/dist/esm/internal/resolve-placement.js +18 -0
  155. package/dist/esm/internal/role-types.js +60 -0
  156. package/dist/esm/internal/set-style.js +36 -0
  157. package/dist/esm/internal/slot.js +59 -0
  158. package/dist/esm/internal/use-anchor-positioning.js +323 -0
  159. package/dist/esm/internal/use-animated-visibility.js +162 -0
  160. package/dist/esm/internal/use-animation-preset.js +18 -0
  161. package/dist/esm/internal/use-focus-wrap.js +89 -0
  162. package/dist/esm/internal/use-initial-focus.js +107 -0
  163. package/dist/esm/internal/use-preset-styles.js +21 -0
  164. package/dist/esm/placement-map/index.js +141 -0
  165. package/dist/esm/popover/create-close-event.js +38 -0
  166. package/dist/esm/popover/index.js +2 -0
  167. package/dist/esm/popover/popover.compiled.css +13 -0
  168. package/dist/esm/popover/popover.js +242 -0
  169. package/dist/esm/popover/types.js +1 -0
  170. package/dist/esm/popup/index.js +33 -0
  171. package/dist/esm/popup/popup-content.js +192 -0
  172. package/dist/esm/popup/popup-context.js +34 -0
  173. package/dist/esm/popup/popup-surface.compiled.css +5 -0
  174. package/dist/esm/popup/popup-surface.js +23 -0
  175. package/dist/esm/popup/popup-trigger-function.js +69 -0
  176. package/dist/esm/popup/popup-trigger.js +74 -0
  177. package/dist/esm/popup/popup.js +61 -0
  178. package/dist/esm/popup/types.js +1 -0
  179. package/dist/esm/use-arrow-navigation/index.js +1 -0
  180. package/dist/esm/use-arrow-navigation/use-arrow-navigation.js +238 -0
  181. package/dist/esm/use-simple-light-dismiss/index.js +78 -0
  182. package/dist/types/animations/presets.d.ts +94 -0
  183. package/dist/types/animations/types.d.ts +42 -0
  184. package/dist/types/arrow/index.d.ts +24 -0
  185. package/dist/types/arrow/types.d.ts +29 -0
  186. package/dist/types/dialog/create-close-event.d.ts +24 -0
  187. package/dist/types/dialog/dialog-content.d.ts +20 -0
  188. package/dist/types/dialog/index.d.ts +3 -0
  189. package/dist/types/dialog/types.d.ts +92 -0
  190. package/dist/types/dialog-scroll-lock/index.d.ts +24 -0
  191. package/dist/types/entry-points/animations.d.ts +2 -0
  192. package/dist/types/entry-points/arrow.d.ts +2 -0
  193. package/dist/types/entry-points/create-close-event.d.ts +4 -0
  194. package/dist/types/entry-points/dialog-scroll-lock.d.ts +1 -0
  195. package/dist/types/entry-points/dialog.d.ts +2 -0
  196. package/dist/types/entry-points/focus.d.ts +2 -0
  197. package/dist/types/entry-points/placement-map.d.ts +2 -0
  198. package/dist/types/entry-points/popover.d.ts +2 -0
  199. package/dist/types/entry-points/popup-surface.d.ts +2 -0
  200. package/dist/types/entry-points/popup.d.ts +2 -0
  201. package/dist/types/entry-points/use-anchor-position.d.ts +1 -0
  202. package/dist/types/entry-points/use-arrow-navigation.d.ts +2 -0
  203. package/dist/types/entry-points/use-simple-light-dismiss.d.ts +2 -0
  204. package/dist/types/focus/focus.d.ts +42 -0
  205. package/dist/types/focus/index.d.ts +2 -0
  206. package/dist/types/index.d.ts +0 -0
  207. package/dist/types/internal/anchor-positioning-fallback.d.ts +24 -0
  208. package/dist/types/internal/combine.d.ts +14 -0
  209. package/dist/types/internal/ensure-preset-styles.d.ts +6 -0
  210. package/dist/types/internal/reduced-motion.d.ts +14 -0
  211. package/dist/types/internal/resolve-placement.d.ts +16 -0
  212. package/dist/types/internal/role-types.d.ts +62 -0
  213. package/dist/types/internal/set-style.d.ts +28 -0
  214. package/dist/types/internal/slot.d.ts +29 -0
  215. package/dist/types/internal/use-anchor-positioning.d.ts +95 -0
  216. package/dist/types/internal/use-animated-visibility.d.ts +74 -0
  217. package/dist/types/internal/use-animation-preset.d.ts +11 -0
  218. package/dist/types/internal/use-focus-wrap.d.ts +20 -0
  219. package/dist/types/internal/use-initial-focus.d.ts +21 -0
  220. package/dist/types/internal/use-preset-styles.d.ts +15 -0
  221. package/dist/types/placement-map/index.d.ts +55 -0
  222. package/dist/types/popover/create-close-event.d.ts +26 -0
  223. package/dist/types/popover/index.d.ts +3 -0
  224. package/dist/types/popover/popover.d.ts +22 -0
  225. package/dist/types/popover/types.d.ts +153 -0
  226. package/dist/types/popup/index.d.ts +34 -0
  227. package/dist/types/popup/popup-content.d.ts +14 -0
  228. package/dist/types/popup/popup-context.d.ts +96 -0
  229. package/dist/types/popup/popup-surface.d.ts +16 -0
  230. package/dist/types/popup/popup-trigger-function.d.ts +108 -0
  231. package/dist/types/popup/popup-trigger.d.ts +23 -0
  232. package/dist/types/popup/popup.d.ts +14 -0
  233. package/dist/types/popup/types.d.ts +289 -0
  234. package/dist/types/use-arrow-navigation/index.d.ts +2 -0
  235. package/dist/types/use-arrow-navigation/use-arrow-navigation.d.ts +136 -0
  236. package/dist/types/use-simple-light-dismiss/index.d.ts +45 -0
  237. package/dist/types-ts4.5/animations/presets.d.ts +94 -0
  238. package/dist/types-ts4.5/animations/types.d.ts +42 -0
  239. package/dist/types-ts4.5/arrow/index.d.ts +24 -0
  240. package/dist/types-ts4.5/arrow/types.d.ts +29 -0
  241. package/dist/types-ts4.5/dialog/create-close-event.d.ts +24 -0
  242. package/dist/types-ts4.5/dialog/dialog-content.d.ts +20 -0
  243. package/dist/types-ts4.5/dialog/index.d.ts +3 -0
  244. package/dist/types-ts4.5/dialog/types.d.ts +92 -0
  245. package/dist/types-ts4.5/dialog-scroll-lock/index.d.ts +24 -0
  246. package/dist/types-ts4.5/entry-points/animations.d.ts +2 -0
  247. package/dist/types-ts4.5/entry-points/arrow.d.ts +2 -0
  248. package/dist/types-ts4.5/entry-points/create-close-event.d.ts +4 -0
  249. package/dist/types-ts4.5/entry-points/dialog-scroll-lock.d.ts +1 -0
  250. package/dist/types-ts4.5/entry-points/dialog.d.ts +2 -0
  251. package/dist/types-ts4.5/entry-points/focus.d.ts +2 -0
  252. package/dist/types-ts4.5/entry-points/placement-map.d.ts +2 -0
  253. package/dist/types-ts4.5/entry-points/popover.d.ts +2 -0
  254. package/dist/types-ts4.5/entry-points/popup-surface.d.ts +2 -0
  255. package/dist/types-ts4.5/entry-points/popup.d.ts +2 -0
  256. package/dist/types-ts4.5/entry-points/use-anchor-position.d.ts +1 -0
  257. package/dist/types-ts4.5/entry-points/use-arrow-navigation.d.ts +2 -0
  258. package/dist/types-ts4.5/entry-points/use-simple-light-dismiss.d.ts +2 -0
  259. package/dist/types-ts4.5/focus/focus.d.ts +42 -0
  260. package/dist/types-ts4.5/focus/index.d.ts +2 -0
  261. package/dist/types-ts4.5/index.d.ts +0 -0
  262. package/dist/types-ts4.5/internal/anchor-positioning-fallback.d.ts +24 -0
  263. package/dist/types-ts4.5/internal/combine.d.ts +14 -0
  264. package/dist/types-ts4.5/internal/ensure-preset-styles.d.ts +6 -0
  265. package/dist/types-ts4.5/internal/reduced-motion.d.ts +14 -0
  266. package/dist/types-ts4.5/internal/resolve-placement.d.ts +16 -0
  267. package/dist/types-ts4.5/internal/role-types.d.ts +62 -0
  268. package/dist/types-ts4.5/internal/set-style.d.ts +28 -0
  269. package/dist/types-ts4.5/internal/slot.d.ts +29 -0
  270. package/dist/types-ts4.5/internal/use-anchor-positioning.d.ts +95 -0
  271. package/dist/types-ts4.5/internal/use-animated-visibility.d.ts +74 -0
  272. package/dist/types-ts4.5/internal/use-animation-preset.d.ts +11 -0
  273. package/dist/types-ts4.5/internal/use-focus-wrap.d.ts +20 -0
  274. package/dist/types-ts4.5/internal/use-initial-focus.d.ts +21 -0
  275. package/dist/types-ts4.5/internal/use-preset-styles.d.ts +15 -0
  276. package/dist/types-ts4.5/placement-map/index.d.ts +55 -0
  277. package/dist/types-ts4.5/popover/create-close-event.d.ts +26 -0
  278. package/dist/types-ts4.5/popover/index.d.ts +3 -0
  279. package/dist/types-ts4.5/popover/popover.d.ts +22 -0
  280. package/dist/types-ts4.5/popover/types.d.ts +153 -0
  281. package/dist/types-ts4.5/popup/index.d.ts +34 -0
  282. package/dist/types-ts4.5/popup/popup-content.d.ts +14 -0
  283. package/dist/types-ts4.5/popup/popup-context.d.ts +96 -0
  284. package/dist/types-ts4.5/popup/popup-surface.d.ts +16 -0
  285. package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +108 -0
  286. package/dist/types-ts4.5/popup/popup-trigger.d.ts +23 -0
  287. package/dist/types-ts4.5/popup/popup.d.ts +14 -0
  288. package/dist/types-ts4.5/popup/types.d.ts +289 -0
  289. package/dist/types-ts4.5/use-arrow-navigation/index.d.ts +2 -0
  290. package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +136 -0
  291. package/dist/types-ts4.5/use-simple-light-dismiss/index.d.ts +45 -0
  292. package/focus/package.json +17 -0
  293. package/package.json +95 -0
  294. package/placement-map/package.json +17 -0
  295. package/popover/package.json +17 -0
  296. package/popup/package.json +17 -0
  297. package/popup-surface/package.json +17 -0
  298. package/use-anchor-position/package.json +17 -0
  299. package/use-arrow-navigation/package.json +17 -0
  300. package/use-simple-light-dismiss/package.json +17 -0
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "getPlacement", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _resolvePlacement.getPlacement;
11
+ }
12
+ });
13
+ exports.placementToPositionArea = placementToPositionArea;
14
+ exports.placementToTryFallbacks = placementToTryFallbacks;
15
+ exports.useAnchorPosition = useAnchorPosition;
16
+ var _react = require("react");
17
+ var _bindEventListener = require("bind-event-listener");
18
+ var _rafSchd = _interopRequireDefault(require("raf-schd"));
19
+ var _once = _interopRequireDefault(require("@atlaskit/ds-lib/once"));
20
+ var _anchorPositioningFallback = require("./anchor-positioning-fallback");
21
+ var _combine = require("./combine");
22
+ var _resolvePlacement = require("./resolve-placement");
23
+ var _setStyle = require("./set-style");
24
+ /**
25
+ * Resolves placement options to CSS `position-area` syntax.
26
+ *
27
+ * The `align` field represents the *visual* alignment:
28
+ * - `align: 'start'` means "aligned to the trigger's start edge" (left in LTR for block axis)
29
+ * - `align: 'end'` means "aligned to the trigger's end edge"
30
+ * - `align: 'center'` means centered (single-axis position-area)
31
+ *
32
+ * CSS `position-area` uses `span-*` keywords which indicate the *expansion direction*.
33
+ * Visual start-alignment requires `span-{cross-axis}-end` (expand toward end = start-aligned).
34
+ * This function handles the inversion internally.
35
+ *
36
+ * @example
37
+ * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'center' } }) // → 'block-end'
38
+ * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'start' } }) // → 'block-end span-inline-end'
39
+ * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'end' } }) // → 'block-end span-inline-start'
40
+ */
41
+ function placementToPositionArea(_ref) {
42
+ var placement = _ref.placement;
43
+ var _getPlacement = (0, _resolvePlacement.getPlacement)({
44
+ placement: placement
45
+ }),
46
+ axis = _getPlacement.axis,
47
+ edge = _getPlacement.edge,
48
+ align = _getPlacement.align;
49
+ var edgeValue = "".concat(axis, "-").concat(edge);
50
+ if (align === 'center') {
51
+ return edgeValue;
52
+ }
53
+
54
+ // Cross-axis name: block ↔ inline
55
+ var crossAxis = axis === 'block' ? 'inline' : 'block';
56
+ // Invert align → CSS span direction: visual 'start' → span toward 'end'
57
+ var spanDir = align === 'start' ? 'end' : 'start';
58
+ return "".concat(edgeValue, " span-").concat(crossAxis, "-").concat(spanDir);
59
+ }
60
+
61
+ /**
62
+ * Returns `position-try-fallbacks` value based on placement.
63
+ *
64
+ * For centered placements, includes cross-axis aligned position-area
65
+ * values so the browser can shift the popover along the cross-axis
66
+ * when the centered position would overflow the viewport edge.
67
+ *
68
+ * Fallback order for centered placements (e.g. `block-end`):
69
+ * 1. Same edge, start-aligned (shift for near-edge overflow)
70
+ * 2. Same edge, end-aligned (shift for far-edge overflow)
71
+ * 3. Flipped edge, centered
72
+ * 4. Flipped edge, start-aligned
73
+ * 5. Flipped edge, end-aligned
74
+ *
75
+ * For aligned placements (start/end), includes the same-edge centered
76
+ * position as fallbacks so the browser can try centering when the aligned
77
+ * position would overflow, before flipping to the opposite edge.
78
+ */
79
+ function placementToTryFallbacks(_ref2) {
80
+ var placement = _ref2.placement;
81
+ var _getPlacement2 = (0, _resolvePlacement.getPlacement)({
82
+ placement: placement
83
+ }),
84
+ axis = _getPlacement2.axis,
85
+ edge = _getPlacement2.edge,
86
+ align = _getPlacement2.align;
87
+ var crossAxis = axis === 'block' ? 'inline' : 'block';
88
+ var flippedEdge = edge === 'start' ? 'end' : 'start';
89
+ if (align !== 'center') {
90
+ var _sameEdge = "".concat(axis, "-").concat(edge);
91
+ var _oppositeEdge = "".concat(axis, "-").concat(flippedEdge);
92
+ var _flipKeyword = axis === 'block' ? 'flip-block' : 'flip-inline';
93
+ // Legacy Popper fallbacks for e.g. bottom-start: [bottom, bottom-end, top-start, top, top-end, auto].
94
+ // Include same-edge centered so the browser can try center when start/end would overflow.
95
+ return ["".concat(_sameEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'end' : 'start'), _sameEdge, "".concat(_sameEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'start' : 'end'), _flipKeyword, "".concat(_oppositeEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'end' : 'start'), _oppositeEdge, "".concat(_oppositeEdge, " span-").concat(crossAxis, "-").concat(align === 'start' ? 'start' : 'end')].join(', ');
96
+ }
97
+ var sameEdge = "".concat(axis, "-").concat(edge);
98
+ var oppositeEdge = "".concat(axis, "-").concat(flippedEdge);
99
+ var flipKeyword = axis === 'block' ? 'flip-block' : 'flip-inline';
100
+ return ["".concat(sameEdge, " span-").concat(crossAxis, "-end"), "".concat(sameEdge, " span-").concat(crossAxis, "-start"), flipKeyword, "".concat(oppositeEdge, " span-").concat(crossAxis, "-end"), "".concat(oppositeEdge, " span-").concat(crossAxis, "-start")].join(', ');
101
+ }
102
+
103
+ /**
104
+ * Detects whether the browser supports CSS Anchor Positioning.
105
+ * Uses `once()` for lazy evaluation — safe for SSR and avoids hydration mismatches.
106
+ */
107
+ var supportsAnchorPositioning = (0, _once.default)(function () {
108
+ if (typeof window === 'undefined' || typeof CSS === 'undefined' || typeof CSS.supports !== 'function') {
109
+ return false;
110
+ }
111
+ return CSS.supports('anchor-name', '--a');
112
+ });
113
+
114
+ /**
115
+ * Default gap between the popover and its trigger (in pixels).
116
+ * Maps to `space.100` (8px) in the design token scale.
117
+ */
118
+ var DEFAULT_OFFSET = 8;
119
+
120
+ /**
121
+ * Returns the CSS margin declaration that creates a gap between the
122
+ * popover and its trigger on the side facing the anchor.
123
+ *
124
+ * For example, a `block-end` placement (popover below) gets
125
+ * `margin-block-start: 8px` to push it away from the trigger's bottom edge.
126
+ */
127
+ function edgeMargin(_ref3) {
128
+ var placement = _ref3.placement,
129
+ offset = _ref3.offset;
130
+ var axis = placement.axis,
131
+ edge = placement.edge;
132
+ var value = "".concat(offset, "px");
133
+ if (axis === 'block' && edge === 'end') {
134
+ return {
135
+ property: 'margin-block-start',
136
+ value: value
137
+ };
138
+ }
139
+ if (axis === 'block' && edge === 'start') {
140
+ return {
141
+ property: 'margin-block-end',
142
+ value: value
143
+ };
144
+ }
145
+ if (axis === 'inline' && edge === 'end') {
146
+ return {
147
+ property: 'margin-inline-start',
148
+ value: value
149
+ };
150
+ }
151
+ if (axis === 'inline' && edge === 'start') {
152
+ return {
153
+ property: 'margin-inline-end',
154
+ value: value
155
+ };
156
+ }
157
+ return {
158
+ property: 'margin-block-start',
159
+ value: value
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Hook that positions an element relative to an anchor element using
165
+ * CSS Anchor Positioning (with a JS fallback for older browsers).
166
+ *
167
+ * This hook is the positioning primitive — it has no knowledge of popovers,
168
+ * visibility, or animation. Compose it with `Popover` for anchor-positioned
169
+ * top-layer content.
170
+ *
171
+ * When CSS Anchor Positioning is supported, it sets CSS properties
172
+ * (`anchor-name`, `position-anchor`, `position-area`, `position-try-fallbacks`)
173
+ * directly on the elements via `el.style.setProperty()`.
174
+ *
175
+ * When not supported, it falls back to JavaScript-based positioning using
176
+ * `position: fixed` with measured coordinates, re-running on scroll (capture)
177
+ * and resize events.
178
+ */
179
+ function useAnchorPosition(_ref4) {
180
+ var anchorRef = _ref4.anchorRef,
181
+ popoverRef = _ref4.popoverRef,
182
+ placement = _ref4.placement,
183
+ _ref4$offset = _ref4.offset,
184
+ offset = _ref4$offset === void 0 ? DEFAULT_OFFSET : _ref4$offset,
185
+ _ref4$forceFallbackPo = _ref4.forceFallbackPositioning,
186
+ forceFallbackPositioning = _ref4$forceFallbackPo === void 0 ? false : _ref4$forceFallbackPo,
187
+ arrow = _ref4.arrow;
188
+ var id = (0, _react.useId)();
189
+ var anchorName = "--anchor-".concat(id.replace(/:/g, ''));
190
+ (0, _react.useLayoutEffect)(function () {
191
+ var trigger = anchorRef.current;
192
+ var popover = popoverRef.current;
193
+ if (!trigger || !popover) {
194
+ return;
195
+ }
196
+ var resolvedPlacement = (0, _resolvePlacement.getPlacement)({
197
+ placement: placement
198
+ });
199
+ var shouldForceFallback = Boolean(forceFallbackPositioning);
200
+ if (supportsAnchorPositioning() && !shouldForceFallback) {
201
+ var gap = edgeMargin({
202
+ placement: resolvedPlacement,
203
+ offset: offset
204
+ });
205
+ var popoverStyles = [{
206
+ property: 'position-anchor',
207
+ value: anchorName
208
+ }, {
209
+ property: 'position-area',
210
+ value: placementToPositionArea({
211
+ placement: resolvedPlacement
212
+ })
213
+ }, {
214
+ property: 'position-try-fallbacks',
215
+ value: arrow ? arrow.getTryFallbacks({
216
+ placement: resolvedPlacement
217
+ }) : placementToTryFallbacks({
218
+ placement: resolvedPlacement
219
+ })
220
+ },
221
+ // Reset browser default popover positioning that conflicts
222
+ // with anchor positioning (UA: `inset: 0; margin: auto;`)
223
+ {
224
+ property: 'margin',
225
+ value: '0'
226
+ }, {
227
+ property: 'inset',
228
+ value: 'auto'
229
+ },
230
+ // Gap between the popover and its trigger
231
+ {
232
+ property: gap.property,
233
+ value: gap.value
234
+ }];
235
+ if (arrow) {
236
+ // Set the arrow size variable used by the injected arrow CSS
237
+ // and the @position-try rules for margin values.
238
+ popoverStyles.push({
239
+ property: '--ds-arrow-size',
240
+ value: "".concat(offset, "px")
241
+ });
242
+ }
243
+ var _undoPositioning = (0, _combine.combine)((0, _setStyle.setStyle)({
244
+ el: trigger,
245
+ styles: [{
246
+ property: 'anchor-name',
247
+ value: anchorName
248
+ }]
249
+ }), (0, _setStyle.setStyle)({
250
+ el: popover,
251
+ styles: popoverStyles
252
+ }));
253
+ return _undoPositioning;
254
+ }
255
+
256
+ // ── JS fallback ──
257
+ // The popover is already in the browser's top layer via popover="auto",
258
+ // so it does not need position:fixed. We only reset the UA defaults
259
+ // (inset: 0; margin: auto) and set top/left based on measurements.
260
+ var cleanupBaseStyles = (0, _setStyle.setStyle)({
261
+ el: popover,
262
+ styles: [{
263
+ property: 'margin',
264
+ value: '0'
265
+ }, {
266
+ property: 'inset',
267
+ value: 'auto'
268
+ }]
269
+ });
270
+ function update() {
271
+ if (!trigger || !popover) {
272
+ return;
273
+ }
274
+ var triggerRect = trigger.getBoundingClientRect();
275
+ var viewport = {
276
+ width: window.innerWidth,
277
+ height: window.innerHeight
278
+ };
279
+ var _computeFallbackPosit = (0, _anchorPositioningFallback.computeFallbackPosition)({
280
+ triggerRect: triggerRect,
281
+ popoverEl: popover,
282
+ placement: resolvedPlacement,
283
+ viewport: viewport,
284
+ offset: offset
285
+ }),
286
+ top = _computeFallbackPosit.top,
287
+ left = _computeFallbackPosit.left;
288
+ popover.style.setProperty('top', "".concat(top, "px"));
289
+ popover.style.setProperty('left', "".concat(left, "px"));
290
+ }
291
+
292
+ // Throttle scroll/resize updates to one per animation frame
293
+ var scheduledUpdate = (0, _rafSchd.default)(update);
294
+ var pendingFrame = null;
295
+ var undoPositioning = (0, _combine.combine)(cleanupBaseStyles,
296
+ // Position when the popover transitions to visible.
297
+ // The popover starts hidden (`display: none` per the popover
298
+ // UA stylesheet), so `offsetWidth`/`offsetHeight` are 0 until
299
+ // `showPopover()` is called. We defer positioning to the next
300
+ // animation frame because some browsers (Firefox) fire the
301
+ // `toggle` event synchronously during `showPopover()`, before
302
+ // the element has been laid out — so dimensions are still 0.
303
+ // Waiting one frame guarantees layout has run and measurements
304
+ // are accurate.
305
+ (0, _bindEventListener.bind)(popover, {
306
+ type: 'toggle',
307
+ listener: function listener(event) {
308
+ var toggleEvent = event;
309
+ if (toggleEvent.newState === 'open') {
310
+ pendingFrame = requestAnimationFrame(update);
311
+ }
312
+ }
313
+ }), (0, _bindEventListener.bind)(window, {
314
+ type: 'scroll',
315
+ listener: scheduledUpdate,
316
+ options: {
317
+ capture: true,
318
+ passive: true
319
+ }
320
+ }), (0, _bindEventListener.bind)(window, {
321
+ type: 'resize',
322
+ listener: scheduledUpdate,
323
+ options: {
324
+ passive: true
325
+ }
326
+ }), function () {
327
+ scheduledUpdate.cancel();
328
+ if (pendingFrame !== null) {
329
+ cancelAnimationFrame(pendingFrame);
330
+ }
331
+ popover.style.removeProperty('top');
332
+ popover.style.removeProperty('left');
333
+ });
334
+ return undoPositioning;
335
+ }, [anchorRef, popoverRef, placement, anchorName, offset, forceFallbackPositioning, arrow]);
336
+ }
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useAnimatedVisibility = useAnimatedVisibility;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _react = require("react");
10
+ var _bindEventListener = require("bind-event-listener");
11
+ var _reducedMotion = require("./reduced-motion");
12
+ var _usePresetStyles = require("./use-preset-styles");
13
+ /**
14
+ * Manages the children mount/unmount lifecycle around CSS exit transitions.
15
+ *
16
+ * Used by both `Popover` and `Dialog` to share the same animation lifecycle
17
+ * logic. Those components own their own show/hide mechanisms (showPopover /
18
+ * hidePopover vs showModal / close) and event handling — this hook only
19
+ * manages the relationship between `isOpen` and when children are rendered.
20
+ *
21
+ * ## Problem
22
+ *
23
+ * We want to delay the unmount of children until a CSS exit transition has
24
+ * finished playing. If we unmount children the moment `isOpen` becomes
25
+ * `false`, the exit animation is never visible — the content just disappears.
26
+ *
27
+ * ## How it works
28
+ *
29
+ * `showChildren` tracks whether the consumer's children should be in the DOM.
30
+ * It does not mirror `isOpen` exactly — it intentionally lags behind during
31
+ * exit animations:
32
+ *
33
+ * ```
34
+ * isOpen: true ──────────────── false
35
+ * showChildren: true ──────────────── true ─── (exit animation) ─── false
36
+ * ```
37
+ *
38
+ * Two close paths exist:
39
+ *
40
+ * 1. **Animated close** (`willAnimate === true`):
41
+ * `isOpen` goes `false` → `showChildren` stays `true` → the CSS exit
42
+ * transition plays → `transitionend` fires → `showChildren` → `false`
43
+ * → `onExitFinish` fires. A timeout fallback ensures we still unmount
44
+ * if `transitionend` never fires (e.g. browser quirks, zero-duration).
45
+ *
46
+ * 2. **Non-animated close** (`willAnimate === false`):
47
+ * `isOpen` goes `false` → `showChildren` → `false` synchronously during
48
+ * the same render → `onExitFinish` fires in a follow-up effect.
49
+ */
50
+ function useAnimatedVisibility(_ref) {
51
+ var isOpen = _ref.isOpen,
52
+ animate = _ref.animate,
53
+ elementRef = _ref.elementRef,
54
+ onExitFinish = _ref.onExitFinish;
55
+ // Resolve the animation preset and inject its CSS (idempotent).
56
+ // Returns `null` when `animate` is falsy.
57
+ var preset = (0, _usePresetStyles.usePresetStyles)({
58
+ preset: animate
59
+ });
60
+
61
+ // Whether we should play CSS transitions. False when there is no preset
62
+ // or the user has enabled the "prefers reduced motion" OS setting.
63
+ var willAnimate = Boolean(animate) && !(0, _reducedMotion.prefersReducedMotion)();
64
+
65
+ // ── showChildren state ──
66
+ //
67
+ // This is the core of the hook. `showChildren` controls whether the
68
+ // consumer's children are in the DOM. The two `if` blocks below are
69
+ // intentionally written as synchronous state updates during render
70
+ // (React supports this pattern — setState during render is treated as
71
+ // a synchronous re-render before the browser paints).
72
+ //
73
+ // Mount path: isOpen went true but showChildren is still false → mount.
74
+ // Unmount path: isOpen went false, showChildren is still true, and we
75
+ // are NOT animating → unmount immediately (no transition
76
+ // to wait for). If we ARE animating, showChildren stays
77
+ // true here and the effect below will set it to false
78
+ // after `transitionend`.
79
+ var _useState = (0, _react.useState)(isOpen),
80
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
81
+ showChildren = _useState2[0],
82
+ setShowChildren = _useState2[1];
83
+ if (isOpen && !showChildren) {
84
+ setShowChildren(true);
85
+ }
86
+ if (!isOpen && showChildren && !willAnimate) {
87
+ setShowChildren(false);
88
+ }
89
+
90
+ // Keep a stable ref to the latest `onExitFinish` so the effect and
91
+ // timeout closures below always call the current callback without
92
+ // needing `onExitFinish` in dependency arrays (which would reset
93
+ // the timeout on every new closure).
94
+ var onExitFinishRef = (0, _react.useRef)(onExitFinish);
95
+ onExitFinishRef.current = onExitFinish;
96
+
97
+ // ── Animated exit effect ──
98
+ //
99
+ // Runs when all three conditions are true:
100
+ // • `isOpen` is false (consumer wants to close)
101
+ // • `showChildren` is true (children are still mounted for exit anim)
102
+ // • `willAnimate` is true (we have a preset and reduced motion is off)
103
+ //
104
+ // Listens for `transitionend` on the element to know when the CSS exit
105
+ // transition has finished, then unmounts children and fires onExitFinish.
106
+ //
107
+ // Fallback timeout: `transitionend` can fail to fire in edge cases
108
+ // (e.g. element removed from top layer by browser, zero-duration
109
+ // transition, interrupted animation). The timeout is set to the
110
+ // preset's exit duration + 50ms buffer to guarantee we always unmount.
111
+ (0, _react.useEffect)(function () {
112
+ var _preset$exitDurationM;
113
+ // Guard: only run during the "exiting" window
114
+ if (isOpen || !showChildren || !willAnimate) {
115
+ return;
116
+ }
117
+ var el = elementRef.current;
118
+ if (!el) {
119
+ return;
120
+ }
121
+ function finish() {
122
+ var _onExitFinishRef$curr;
123
+ clearTimeout(fallbackId);
124
+ setShowChildren(false);
125
+ (_onExitFinishRef$curr = onExitFinishRef.current) === null || _onExitFinishRef$curr === void 0 || _onExitFinishRef$curr.call(onExitFinishRef);
126
+ }
127
+
128
+ // Fallback: unmount even if transitionend never fires
129
+ var fallbackId = setTimeout(finish, ((_preset$exitDurationM = preset === null || preset === void 0 ? void 0 : preset.exitDurationMs) !== null && _preset$exitDurationM !== void 0 ? _preset$exitDurationM : 0) + 50);
130
+
131
+ // Primary: listen for the CSS transition to complete
132
+ var unbind = (0, _bindEventListener.bind)(el, {
133
+ type: 'transitionend',
134
+ listener: finish,
135
+ options: {
136
+ once: true
137
+ }
138
+ });
139
+
140
+ // Cleanup on re-render or unmount: cancel pending timeout and listener
141
+ return function () {
142
+ clearTimeout(fallbackId);
143
+ unbind();
144
+ };
145
+ }, [isOpen, showChildren, willAnimate, preset === null || preset === void 0 ? void 0 : preset.exitDurationMs, elementRef]);
146
+
147
+ // ── Non-animated exit callback ──
148
+ //
149
+ // When there is no animation, children unmount synchronously (handled
150
+ // by the `if` block above). But `onExitFinish` still needs to fire —
151
+ // we do that in a follow-up effect so the consumer can react to it.
152
+ //
153
+ // Uses a previous-value ref (`wasOpenRef`) to detect the exact
154
+ // true→false transition of `isOpen`, avoiding false positives on
155
+ // mount or re-renders where `isOpen` was already false.
156
+ var wasOpenRef = (0, _react.useRef)(isOpen);
157
+ (0, _react.useEffect)(function () {
158
+ var wasOpen = wasOpenRef.current;
159
+ wasOpenRef.current = isOpen;
160
+ if (wasOpen && !isOpen && !willAnimate) {
161
+ var _onExitFinishRef$curr2;
162
+ (_onExitFinishRef$curr2 = onExitFinishRef.current) === null || _onExitFinishRef$curr2 === void 0 || _onExitFinishRef$curr2.call(onExitFinishRef);
163
+ }
164
+ }, [isOpen, willAnimate]);
165
+ return {
166
+ showChildren: showChildren,
167
+ preset: preset
168
+ };
169
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useAnimationPreset = useAnimationPreset;
7
+ var _react = require("react");
8
+ var _ensurePresetStyles = require("./ensure-preset-styles");
9
+ /**
10
+ * Normalizes the `animate` prop to a preset (or null) and ensures its CSS
11
+ * is injected once into document.head. Used by PopupContent, Popover, and
12
+ * DialogContent so they don't duplicate this logic.
13
+ */
14
+ function useAnimationPreset(animate) {
15
+ var preset = animate != null && animate !== false ? animate : null;
16
+ (0, _react.useInsertionEffect)(function () {
17
+ if (preset) {
18
+ (0, _ensurePresetStyles.ensurePresetStyles)({
19
+ preset: preset
20
+ });
21
+ }
22
+ }, [preset]);
23
+ return preset;
24
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useFocusWrap = useFocusWrap;
7
+ var _react = require("react");
8
+ var _bindEventListener = require("bind-event-listener");
9
+ var _focus = require("../focus/focus");
10
+ /**
11
+ * Roles that require focus wrapping per WAI-ARIA APG.
12
+ *
13
+ * - `dialog`: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
14
+ * - `alertdialog`: same keyboard pattern as dialog
15
+ *
16
+ * `menu` is intentionally excluded. Menus are composite widgets
17
+ * (https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_general_within)
18
+ * that manage their own internal keyboard navigation via arrow keys,
19
+ * not Tab. Tab/Shift+Tab should move focus OUT of a menu entirely.
20
+ *
21
+ * Menu keyboard behavior (arrow keys, Home/End, type-ahead, Enter/Space)
22
+ * is context-dependent — it varies by orientation, nesting depth, item
23
+ * type, and control pattern (menu button vs menubar). This makes it
24
+ * impossible to implement generically here. The consumer component
25
+ * (e.g. `dropdown-menu`) owns all menu keyboard navigation.
26
+ *
27
+ * See: notes/outputs/menu-keyboard-decision.md
28
+ */
29
+ function roleRequiresFocusWrap(role) {
30
+ return role === 'dialog' || role === 'alertdialog';
31
+ }
32
+
33
+ /**
34
+ * Wraps Tab/Shift+Tab focus within a popover element when its role
35
+ * semantically requires it (dialog, alertdialog).
36
+ *
37
+ * While the popover is open, Tab and Shift+Tab are intercepted
38
+ * (via `preventDefault`) and remapped to cycle through focusable
39
+ * elements within the container using wrapping navigation.
40
+ *
41
+ * Light dismiss (Escape, click outside) continues to work natively
42
+ * via `popover="auto"` — this hook only intercepts Tab.
43
+ *
44
+ * Always call this hook unconditionally. The listener is only
45
+ * attached when the role requires focus wrapping, and is cleaned
46
+ * up and re-evaluated when the role changes.
47
+ */
48
+ function useFocusWrap(_ref) {
49
+ var elementRef = _ref.elementRef,
50
+ role = _ref.role;
51
+ (0, _react.useEffect)(function () {
52
+ var el = elementRef.current;
53
+ if (!el || !roleRequiresFocusWrap(role)) {
54
+ return;
55
+ }
56
+ var unbind = (0, _bindEventListener.bind)(el, {
57
+ type: 'keydown',
58
+ listener: function listener(event) {
59
+ if (event.key !== 'Tab') {
60
+ return;
61
+ }
62
+ event.preventDefault();
63
+ var direction = event.shiftKey ? 'backwards' : 'forwards';
64
+
65
+ // Try to move to the next/previous focusable element relative
66
+ // to the currently focused element within the container.
67
+ var next = (0, _focus.getNextFocusable)({
68
+ container: el,
69
+ direction: direction
70
+ });
71
+ if (next) {
72
+ next.focus();
73
+ return;
74
+ }
75
+
76
+ // Nothing is currently focused inside the container (or the
77
+ // focused element isn't in the focusable list). Fall back to
78
+ // the first or last focusable element depending on direction.
79
+ var fallback = direction === 'forwards' ? (0, _focus.getFirstFocusable)({
80
+ container: el
81
+ }) : (0, _focus.getLastFocusable)({
82
+ container: el
83
+ });
84
+ if (fallback) {
85
+ fallback.focus();
86
+ }
87
+ },
88
+ options: {
89
+ capture: true
90
+ }
91
+ });
92
+ return unbind;
93
+ }, [elementRef, role]);
94
+ }