@mortenbrudvik/waveui 0.9.0 → 0.11.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 (264) hide show
  1. package/README.md +758 -152
  2. package/dist/components/button/Toolbar.cjs +1 -1
  3. package/dist/components/button/Toolbar.cjs.map +1 -1
  4. package/dist/components/button/Toolbar.mjs +25 -30
  5. package/dist/components/button/Toolbar.mjs.map +1 -1
  6. package/dist/components/button/Toolbar.navigation.cjs +2 -0
  7. package/dist/components/button/Toolbar.navigation.cjs.map +1 -0
  8. package/dist/components/button/Toolbar.navigation.mjs +17 -0
  9. package/dist/components/button/Toolbar.navigation.mjs.map +1 -0
  10. package/dist/components/data-display/Avatar.cjs +1 -1
  11. package/dist/components/data-display/Avatar.cjs.map +1 -1
  12. package/dist/components/data-display/Avatar.context.cjs +2 -0
  13. package/dist/components/data-display/Avatar.context.cjs.map +1 -0
  14. package/dist/components/data-display/Avatar.context.mjs +9 -0
  15. package/dist/components/data-display/Avatar.context.mjs.map +1 -0
  16. package/dist/components/data-display/Avatar.mjs +66 -61
  17. package/dist/components/data-display/Avatar.mjs.map +1 -1
  18. package/dist/components/data-display/InteractionTag.cjs +2 -0
  19. package/dist/components/data-display/InteractionTag.cjs.map +1 -0
  20. package/dist/components/data-display/InteractionTag.mjs +234 -0
  21. package/dist/components/data-display/InteractionTag.mjs.map +1 -0
  22. package/dist/components/data-display/Tag.cjs +1 -1
  23. package/dist/components/data-display/Tag.cjs.map +1 -1
  24. package/dist/components/data-display/Tag.mjs +222 -90
  25. package/dist/components/data-display/Tag.mjs.map +1 -1
  26. package/dist/components/data-display/TagGroup.cjs +2 -0
  27. package/dist/components/data-display/TagGroup.cjs.map +1 -0
  28. package/dist/components/data-display/TagGroup.context.cjs +2 -0
  29. package/dist/components/data-display/TagGroup.context.cjs.map +1 -0
  30. package/dist/components/data-display/TagGroup.context.mjs +113 -0
  31. package/dist/components/data-display/TagGroup.context.mjs.map +1 -0
  32. package/dist/components/data-display/TagGroup.mjs +149 -0
  33. package/dist/components/data-display/TagGroup.mjs.map +1 -0
  34. package/dist/components/data-display/tagStyles.cjs +2 -0
  35. package/dist/components/data-display/tagStyles.cjs.map +1 -0
  36. package/dist/components/data-display/tagStyles.mjs +108 -0
  37. package/dist/components/data-display/tagStyles.mjs.map +1 -0
  38. package/dist/components/feedback/Toaster.cjs +1 -1
  39. package/dist/components/feedback/Toaster.cjs.map +1 -1
  40. package/dist/components/feedback/Toaster.mjs +213 -181
  41. package/dist/components/feedback/Toaster.mjs.map +1 -1
  42. package/dist/components/input/Calendar.cjs +2 -0
  43. package/dist/components/input/Calendar.cjs.map +1 -0
  44. package/dist/components/input/Calendar.mjs +352 -0
  45. package/dist/components/input/Calendar.mjs.map +1 -0
  46. package/dist/components/input/Calendar.views.cjs +2 -0
  47. package/dist/components/input/Calendar.views.cjs.map +1 -0
  48. package/dist/components/input/Calendar.views.mjs +194 -0
  49. package/dist/components/input/Calendar.views.mjs.map +1 -0
  50. package/dist/components/input/ColorArea.cjs +1 -1
  51. package/dist/components/input/ColorArea.cjs.map +1 -1
  52. package/dist/components/input/ColorArea.mjs +18 -18
  53. package/dist/components/input/ColorArea.mjs.map +1 -1
  54. package/dist/components/input/Combobox.cjs +1 -1
  55. package/dist/components/input/Combobox.cjs.map +1 -1
  56. package/dist/components/input/Combobox.expand.cjs +1 -1
  57. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  58. package/dist/components/input/Combobox.expand.mjs +7 -7
  59. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  60. package/dist/components/input/Combobox.mjs +232 -156
  61. package/dist/components/input/Combobox.mjs.map +1 -1
  62. package/dist/components/input/Combobox.text.cjs +2 -0
  63. package/dist/components/input/Combobox.text.cjs.map +1 -0
  64. package/dist/components/input/Combobox.text.mjs +24 -0
  65. package/dist/components/input/Combobox.text.mjs.map +1 -0
  66. package/dist/components/input/DatePicker.cjs +1 -1
  67. package/dist/components/input/DatePicker.cjs.map +1 -1
  68. package/dist/components/input/DatePicker.mjs +203 -288
  69. package/dist/components/input/DatePicker.mjs.map +1 -1
  70. package/dist/components/input/Dropdown.cjs +1 -1
  71. package/dist/components/input/Dropdown.cjs.map +1 -1
  72. package/dist/components/input/Dropdown.mjs +135 -109
  73. package/dist/components/input/Dropdown.mjs.map +1 -1
  74. package/dist/components/input/Listbox.cjs +2 -0
  75. package/dist/components/input/Listbox.cjs.map +1 -0
  76. package/dist/components/input/Listbox.mjs +134 -0
  77. package/dist/components/input/Listbox.mjs.map +1 -0
  78. package/dist/components/input/Option.cjs +1 -1
  79. package/dist/components/input/Option.cjs.map +1 -1
  80. package/dist/components/input/Option.mjs +163 -97
  81. package/dist/components/input/Option.mjs.map +1 -1
  82. package/dist/components/input/SwatchPicker.cjs +1 -1
  83. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  84. package/dist/components/input/SwatchPicker.context.cjs +2 -0
  85. package/dist/components/input/SwatchPicker.context.cjs.map +1 -0
  86. package/dist/components/input/SwatchPicker.context.mjs +35 -0
  87. package/dist/components/input/SwatchPicker.context.mjs.map +1 -0
  88. package/dist/components/input/SwatchPicker.mjs +131 -103
  89. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  90. package/dist/components/input/SwatchPicker.swatches.cjs +2 -0
  91. package/dist/components/input/SwatchPicker.swatches.cjs.map +1 -0
  92. package/dist/components/input/SwatchPicker.swatches.mjs +207 -0
  93. package/dist/components/input/SwatchPicker.swatches.mjs.map +1 -0
  94. package/dist/components/input/TagPicker.cjs +1 -1
  95. package/dist/components/input/TagPicker.cjs.map +1 -1
  96. package/dist/components/input/TagPicker.context.cjs +2 -0
  97. package/dist/components/input/TagPicker.context.cjs.map +1 -0
  98. package/dist/components/input/TagPicker.context.mjs +20 -0
  99. package/dist/components/input/TagPicker.context.mjs.map +1 -0
  100. package/dist/components/input/TagPicker.create.cjs +2 -0
  101. package/dist/components/input/TagPicker.create.cjs.map +1 -0
  102. package/dist/components/input/TagPicker.create.mjs +24 -0
  103. package/dist/components/input/TagPicker.create.mjs.map +1 -0
  104. package/dist/components/input/TagPicker.mjs +13 -274
  105. package/dist/components/input/TagPicker.mjs.map +1 -1
  106. package/dist/components/input/TagPicker.option.cjs +2 -0
  107. package/dist/components/input/TagPicker.option.cjs.map +1 -0
  108. package/dist/components/input/TagPicker.option.mjs +45 -0
  109. package/dist/components/input/TagPicker.option.mjs.map +1 -0
  110. package/dist/components/input/TagPicker.overflow.cjs +2 -0
  111. package/dist/components/input/TagPicker.overflow.cjs.map +1 -0
  112. package/dist/components/input/TagPicker.overflow.mjs +153 -0
  113. package/dist/components/input/TagPicker.overflow.mjs.map +1 -0
  114. package/dist/components/input/TagPicker.parts.cjs +2 -0
  115. package/dist/components/input/TagPicker.parts.cjs.map +1 -0
  116. package/dist/components/input/TagPicker.parts.mjs +425 -0
  117. package/dist/components/input/TagPicker.parts.mjs.map +1 -0
  118. package/dist/components/input/TagPicker.root.cjs +2 -0
  119. package/dist/components/input/TagPicker.root.cjs.map +1 -0
  120. package/dist/components/input/TagPicker.root.mjs +416 -0
  121. package/dist/components/input/TagPicker.root.mjs.map +1 -0
  122. package/dist/components/input/TimePicker.cjs +1 -1
  123. package/dist/components/input/TimePicker.cjs.map +1 -1
  124. package/dist/components/input/TimePicker.mjs +77 -77
  125. package/dist/components/input/TimePicker.mjs.map +1 -1
  126. package/dist/components/input/dateUtils.cjs +1 -1
  127. package/dist/components/input/dateUtils.cjs.map +1 -1
  128. package/dist/components/input/dateUtils.mjs +114 -96
  129. package/dist/components/input/dateUtils.mjs.map +1 -1
  130. package/dist/components/input/pickerLabels.cjs +2 -0
  131. package/dist/components/input/pickerLabels.cjs.map +1 -0
  132. package/dist/components/input/pickerLabels.mjs +16 -0
  133. package/dist/components/input/pickerLabels.mjs.map +1 -0
  134. package/dist/components/input/pickerValues.cjs +2 -0
  135. package/dist/components/input/pickerValues.cjs.map +1 -0
  136. package/dist/components/input/pickerValues.mjs +24 -0
  137. package/dist/components/input/pickerValues.mjs.map +1 -0
  138. package/dist/components/layout/Accordion.cjs.map +1 -1
  139. package/dist/components/layout/Accordion.mjs.map +1 -1
  140. package/dist/components/navigation/Hamburger.cjs +2 -0
  141. package/dist/components/navigation/Hamburger.cjs.map +1 -0
  142. package/dist/components/navigation/Hamburger.mjs +54 -0
  143. package/dist/components/navigation/Hamburger.mjs.map +1 -0
  144. package/dist/components/navigation/Nav.cjs +1 -1
  145. package/dist/components/navigation/Nav.cjs.map +1 -1
  146. package/dist/components/navigation/Nav.context.cjs +2 -0
  147. package/dist/components/navigation/Nav.context.cjs.map +1 -0
  148. package/dist/components/navigation/Nav.context.mjs +137 -0
  149. package/dist/components/navigation/Nav.context.mjs.map +1 -0
  150. package/dist/components/navigation/Nav.mjs +151 -258
  151. package/dist/components/navigation/Nav.mjs.map +1 -1
  152. package/dist/components/navigation/Nav.parts.cjs +2 -0
  153. package/dist/components/navigation/Nav.parts.cjs.map +1 -0
  154. package/dist/components/navigation/Nav.parts.mjs +77 -0
  155. package/dist/components/navigation/Nav.parts.mjs.map +1 -0
  156. package/dist/components/navigation/Nav.root.cjs +2 -0
  157. package/dist/components/navigation/Nav.root.cjs.map +1 -0
  158. package/dist/components/navigation/Nav.root.mjs +78 -0
  159. package/dist/components/navigation/Nav.root.mjs.map +1 -0
  160. package/dist/components/navigation/NavDrawer.cjs +2 -0
  161. package/dist/components/navigation/NavDrawer.cjs.map +1 -0
  162. package/dist/components/navigation/NavDrawer.context.cjs +2 -0
  163. package/dist/components/navigation/NavDrawer.context.cjs.map +1 -0
  164. package/dist/components/navigation/NavDrawer.context.mjs +11 -0
  165. package/dist/components/navigation/NavDrawer.context.mjs.map +1 -0
  166. package/dist/components/navigation/NavDrawer.mjs +179 -0
  167. package/dist/components/navigation/NavDrawer.mjs.map +1 -0
  168. package/dist/components/overlays/Dialog.cjs +1 -1
  169. package/dist/components/overlays/Dialog.cjs.map +1 -1
  170. package/dist/components/overlays/Dialog.mjs +190 -125
  171. package/dist/components/overlays/Dialog.mjs.map +1 -1
  172. package/dist/components/overlays/Dialog.shared.cjs +1 -1
  173. package/dist/components/overlays/Dialog.shared.cjs.map +1 -1
  174. package/dist/components/overlays/Dialog.shared.mjs +157 -81
  175. package/dist/components/overlays/Dialog.shared.mjs.map +1 -1
  176. package/dist/components/overlays/Dialog.slots.cjs +2 -0
  177. package/dist/components/overlays/Dialog.slots.cjs.map +1 -0
  178. package/dist/components/overlays/Dialog.slots.mjs +129 -0
  179. package/dist/components/overlays/Dialog.slots.mjs.map +1 -0
  180. package/dist/components/overlays/Drawer.cjs +1 -1
  181. package/dist/components/overlays/Drawer.cjs.map +1 -1
  182. package/dist/components/overlays/Drawer.context.cjs +2 -0
  183. package/dist/components/overlays/Drawer.context.cjs.map +1 -0
  184. package/dist/components/overlays/Drawer.context.mjs +29 -0
  185. package/dist/components/overlays/Drawer.context.mjs.map +1 -0
  186. package/dist/components/overlays/Drawer.mjs +12 -187
  187. package/dist/components/overlays/Drawer.mjs.map +1 -1
  188. package/dist/components/overlays/Drawer.panel.cjs +2 -0
  189. package/dist/components/overlays/Drawer.panel.cjs.map +1 -0
  190. package/dist/components/overlays/Drawer.panel.mjs +159 -0
  191. package/dist/components/overlays/Drawer.panel.mjs.map +1 -0
  192. package/dist/components/overlays/Drawer.parts.cjs +2 -0
  193. package/dist/components/overlays/Drawer.parts.cjs.map +1 -0
  194. package/dist/components/overlays/Drawer.parts.mjs +152 -0
  195. package/dist/components/overlays/Drawer.parts.mjs.map +1 -0
  196. package/dist/components/overlays/Drawer.root.cjs +2 -0
  197. package/dist/components/overlays/Drawer.root.cjs.map +1 -0
  198. package/dist/components/overlays/Drawer.root.mjs +207 -0
  199. package/dist/components/overlays/Drawer.root.mjs.map +1 -0
  200. package/dist/components/overlays/Drawer.scroll.cjs +2 -0
  201. package/dist/components/overlays/Drawer.scroll.cjs.map +1 -0
  202. package/dist/components/overlays/Drawer.scroll.mjs +42 -0
  203. package/dist/components/overlays/Drawer.scroll.mjs.map +1 -0
  204. package/dist/components/table/useGridNavigation.cjs +1 -1
  205. package/dist/components/table/useGridNavigation.cjs.map +1 -1
  206. package/dist/components/table/useGridNavigation.mjs +67 -70
  207. package/dist/components/table/useGridNavigation.mjs.map +1 -1
  208. package/dist/hooks/useActiveDescendant.cjs +2 -0
  209. package/dist/hooks/useActiveDescendant.cjs.map +1 -0
  210. package/dist/hooks/useActiveDescendant.mjs +56 -0
  211. package/dist/hooks/useActiveDescendant.mjs.map +1 -0
  212. package/dist/hooks/useDismiss.cjs.map +1 -1
  213. package/dist/hooks/useDismiss.mjs.map +1 -1
  214. package/dist/hooks/useFocusTrap.cjs +1 -1
  215. package/dist/hooks/useFocusTrap.cjs.map +1 -1
  216. package/dist/hooks/useFocusTrap.mjs +115 -98
  217. package/dist/hooks/useFocusTrap.mjs.map +1 -1
  218. package/dist/hooks/useListbox.cjs +1 -1
  219. package/dist/hooks/useListbox.cjs.map +1 -1
  220. package/dist/hooks/useListbox.mjs +250 -210
  221. package/dist/hooks/useListbox.mjs.map +1 -1
  222. package/dist/hooks/useModalLayer.cjs +1 -1
  223. package/dist/hooks/useModalLayer.cjs.map +1 -1
  224. package/dist/hooks/useModalLayer.mjs +35 -22
  225. package/dist/hooks/useModalLayer.mjs.map +1 -1
  226. package/dist/hooks/useRestoreFocus.cjs +1 -1
  227. package/dist/hooks/useRestoreFocus.cjs.map +1 -1
  228. package/dist/hooks/useRestoreFocus.mjs +91 -78
  229. package/dist/hooks/useRestoreFocus.mjs.map +1 -1
  230. package/dist/hooks/useRovingGrid.cjs +2 -0
  231. package/dist/hooks/useRovingGrid.cjs.map +1 -0
  232. package/dist/hooks/useRovingGrid.mjs +69 -0
  233. package/dist/hooks/useRovingGrid.mjs.map +1 -0
  234. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  235. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  236. package/dist/hooks/useRovingTabIndex.mjs +102 -78
  237. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  238. package/dist/index.cjs +1 -1
  239. package/dist/index.d.cts +4391 -394
  240. package/dist/index.d.ts +4391 -394
  241. package/dist/index.mjs +115 -101
  242. package/dist/lib/classNames.cjs +1 -1
  243. package/dist/lib/classNames.cjs.map +1 -1
  244. package/dist/lib/classNames.mjs +170 -74
  245. package/dist/lib/classNames.mjs.map +1 -1
  246. package/dist/lib/date.cjs +2 -0
  247. package/dist/lib/date.cjs.map +1 -0
  248. package/dist/lib/date.mjs +44 -0
  249. package/dist/lib/date.mjs.map +1 -0
  250. package/dist/lib/focus.cjs +1 -1
  251. package/dist/lib/focus.cjs.map +1 -1
  252. package/dist/lib/focus.mjs +5 -2
  253. package/dist/lib/focus.mjs.map +1 -1
  254. package/dist/lib/icons.cjs +1 -1
  255. package/dist/lib/icons.cjs.map +1 -1
  256. package/dist/lib/icons.mjs +13 -6
  257. package/dist/lib/icons.mjs.map +1 -1
  258. package/dist/lib/layers.cjs +1 -1
  259. package/dist/lib/layers.cjs.map +1 -1
  260. package/dist/lib/layers.mjs +53 -47
  261. package/dist/lib/layers.mjs.map +1 -1
  262. package/dist/styles.css +1 -1
  263. package/package.json +1 -1
  264. package/src/styles/tokens.css +25 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useRestoreFocus.cjs","names":["isFocusable","isInsideOtherOpenModal","getOpenLayers","isInsideLayerTree","compareLayers","getGlobalRegistry","subscribeLayers","getFirstTabbable","getTabbableElements","getLayer","getTopmostLayer","focusElement","React","DismissLayerContext","useRef","require_runtime","require_globalRegistry","require_focus","require_layers","require_useDismiss","react","FOLLOWING","PORTAL_SELECTOR","isValidTarget","el","recordPosition","position","body","node","captureAnchors","opener","layers","layer","b","a","anchors","anchor","container","entry","getSurfaceEntries","tracker","getFocusTracker","isClosingByHover","seen","other","isHoverCloseOf","options","ELEMENT_NODE","isElementTarget","target","recordFocus","doc","refreshFocusRecord","last","retainFocusTracker","onFocusIn","event","onFocusOut","unsubscribe","retained","getLostFocus","element","captureOpener","isCandidate","trigger","triggerRef","active","lost","getLayerTargets","targets","first","isAfterPoint","point","ref","placement","follows","resolvePoint","index","path","root","next","previous","getNearbyTargets","resolved","levels","level","candidates","inLevel","after","before","shouldRestore","onBody","isHoverClose","getReplacementTargets","restoreCandidates","latest","replacements","parentLayer","parentLayerId","outsideParent","restore","candidate","useRestoreFocus","latestRef","capturedRef","insertionEnabledRef","layoutEnabledRef","scheduledRef","entryRef","release","surfaces","wasEnabled","enabled","captured","acts","scheduled","entryHolder","snapshot","token"],"sources":["../../src/hooks/useRestoreFocus.ts"],"sourcesContent":["import * as React from 'react';\nimport { useInsertionEffect, useLayoutEffect, useRef } from 'react';\nimport { focusElement, getFirstTabbable, getTabbableElements, isFocusable } from '../lib/focus';\nimport { getGlobalRegistry } from '../lib/globalRegistry';\nimport {\n ALLOW_OUTSIDE_SELECTOR,\n compareLayers,\n getLayer,\n getOpenLayers,\n getTopmostLayer,\n isInsideLayerTree,\n isInsideOtherOpenModal,\n subscribeLayers,\n type LayerRecord,\n} from '../lib/layers';\nimport { DismissLayerContext } from './useDismiss';\n\n/** Options of {@link useRestoreFocus}. */\nexport interface UseRestoreFocusOptions {\n /** `true` while the surface is open. */\n enabled: boolean;\n /** The layer surface: opener candidates inside it are ignored. */\n container?: HTMLElement | null;\n /** The trigger: preferred restore target. */\n triggerRef?: React.RefObject<HTMLElement | null>;\n /** Consumer override: focused first when valid. */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** Used when neither the override, the opener nor the trigger can take focus. */\n fallback?: () => HTMLElement | null;\n /**\n * Popovers: restore only when focus was inside the surface (or lost to `<body>`) at close, so a\n * click that moved focus elsewhere is respected. @default false\n */\n onlyIfFocusInside?: boolean;\n /**\n * Read when the surface closes, or unmounts while open: `true` when the hover intent closed it\n * (Popover and Menu `openOnHover`, a submenu closing by hover). A hover close never moves focus:\n * it restores only while focus is inside the surface, so focus on `<body>` (where a hover-opened\n * surface leaves it) or elsewhere stays where it is. A surface opened from inside one that closes\n * by hover (its opener, else its trigger, lies in that surface: a submenu, a hover card in a\n * hover card, at any depth) is taken along, and its close counts as a hover close too. Every\n * other close keeps the rules above.\n */\n isHoverClose?: () => boolean;\n}\n\ninterface Latest {\n options: UseRestoreFocusOptions;\n parentLayerId: string | null;\n}\n\n/** Where an element sat in the document, recorded so a spot near it can be found once it is gone. */\ninterface DomPosition {\n /** The element and its ancestors up to `<body>`, innermost first. */\n path: Element[];\n /** The next element sibling of each `path` entry when it was recorded. */\n next: Array<Element | null>;\n /** The previous element sibling of each `path` entry when it was recorded. */\n previous: Array<Element | null>;\n}\n\n/** What is captured about the opener when the surface opens. */\ninterface OpenerRecord {\n element: HTMLElement;\n /** Its place in the document, used when it is removed or can no longer take focus. */\n position: DomPosition;\n /** The anchors (triggers) of the open layers whose tree held it, innermost layer first. */\n anchors: Array<{ element: HTMLElement; position: DomPosition }>;\n}\n\n/** A point in document order: just before `ref`, or just after `ref` and its subtree. */\ninterface DomPoint {\n ref: Element;\n placement: 'before' | 'after';\n}\n\nconst FOLLOWING = 4; // Node.DOCUMENT_POSITION_FOLLOWING\nconst PORTAL_SELECTOR = '[data-wave-portal]';\n\nfunction isValidTarget(el: HTMLElement | null | undefined): el is HTMLElement {\n if (!el || !el.isConnected) return false;\n if (!isFocusable(el)) return false; // also rejects [inert] ancestors, hidden and disabled\n if (el.closest('[aria-hidden=\"true\"]')) return false;\n return !isInsideOtherOpenModal(el);\n}\n\nfunction recordPosition(el: Element): DomPosition {\n const position: DomPosition = { path: [], next: [], previous: [] };\n const body = el.ownerDocument.body;\n for (let node: Element | null = el; node; node = node.parentElement) {\n position.path.push(node);\n position.next.push(node.nextElementSibling);\n position.previous.push(node.previousElementSibling);\n if (node === body) break;\n }\n return position;\n}\n\n/**\n * The anchors of the open layers whose tree contains `opener` (a menu item's menu button),\n * innermost layer first. An opener in an allow-listed region (a toast) belongs to no layer.\n */\nfunction captureAnchors(\n opener: HTMLElement,\n container: HTMLElement | null | undefined,\n): OpenerRecord['anchors'] {\n if (opener.closest(ALLOW_OUTSIDE_SELECTOR)) return [];\n const layers = getOpenLayers()\n .filter((layer) => isInsideLayerTree(layer.id, opener))\n .sort((a, b) => compareLayers(b, a));\n const anchors: OpenerRecord['anchors'] = [];\n for (const layer of layers) {\n const anchor = layer.getAnchor();\n if (!anchor || anchor === opener || (container && container.contains(anchor))) continue;\n if (anchors.some((entry) => entry.element === anchor)) continue;\n anchors.push({ element: anchor, position: recordPosition(anchor) });\n }\n return anchors;\n}\n\n// ---------------------------------------------------------------------------\n// Focus tracker\n// ---------------------------------------------------------------------------\n\n/**\n * Remembers the last focused element, with its place in the document and the anchors of the\n * overlays that held it, recorded while it is still in the document. A surface captures its opener\n * in the mutation phase, and by then React has already deleted anything earlier in the tree that\n * the same commit removes. A popover rendered before a dialog, whose menu item closes the popover\n * and opens the dialog, has lost its menu item (and focus is on `<body>`) when the dialog captures.\n * The record still leads the restore to the popover's trigger. It lives in\n * `getGlobalRegistry('restoreFocusTracker')`, so two copies of the library share one set of\n * listeners.\n */\ninterface FocusTracker {\n /** Mounted `useRestoreFocus` instances: the listeners are installed while there is one. */\n users: number;\n /** The last focused element; `null` once focus was moved away from it on purpose. */\n last: OpenerRecord | null;\n /** Removes the listeners; `null` while none are installed. */\n uninstall: (() => void) | null;\n /**\n * The mounted surfaces, as the other instances see them (see {@link isClosingByHover}). Created\n * on first use: a tracker made by another copy of the library does not have it.\n */\n surfaces?: Set<SurfaceEntry>;\n}\n\n/** A mounted `useRestoreFocus`, as the other instances see it. */\ninterface SurfaceEntry {\n /** Whether the surface is closing by hover (its `isHoverClose`). */\n isHoverClose(): boolean;\n /** The surface element, while there is one. */\n getContainer(): HTMLElement | null;\n /** The element the surface was opened from: its captured opener, else its trigger. */\n getOpener(): HTMLElement | null;\n}\n\nfunction getSurfaceEntries(): Set<SurfaceEntry> {\n const tracker = getFocusTracker();\n tracker.surfaces ??= new Set();\n return tracker.surfaces;\n}\n\n/**\n * Whether the close of `entry` is a hover close: its own, or that of a surface holding the element\n * it was opened from (a submenu in a menu that closes by hover, a hover card inside a hover card,\n * at any depth), which takes it along.\n */\nfunction isClosingByHover(entry: SurfaceEntry, seen = new Set<SurfaceEntry>()): boolean {\n if (seen.has(entry)) return false;\n seen.add(entry);\n if (entry.isHoverClose()) return true;\n const opener = entry.getOpener();\n if (!opener) return false;\n for (const other of getSurfaceEntries()) {\n const container = other === entry ? null : other.getContainer();\n if (container && container.contains(opener) && isClosingByHover(other, seen)) return true;\n }\n return false;\n}\n\n/** Whether this close is a hover close: the surface's own, or that of a surface it was opened from. */\nfunction isHoverCloseOf(entry: SurfaceEntry | null, options: UseRestoreFocusOptions): boolean {\n return entry ? isClosingByHover(entry) : options.isHoverClose?.() === true;\n}\n\nfunction getFocusTracker(): FocusTracker {\n return getGlobalRegistry<FocusTracker>('restoreFocusTracker', () => ({\n users: 0,\n last: null,\n uninstall: null,\n }));\n}\n\nconst ELEMENT_NODE = 1;\n\nfunction isElementTarget(target: EventTarget | null): target is HTMLElement {\n return !!target && (target as Partial<Node>).nodeType === ELEMENT_NODE;\n}\n\nfunction recordFocus(tracker: FocusTracker, el: HTMLElement): void {\n const doc = el.ownerDocument;\n if (el === doc.body || el === doc.documentElement) {\n tracker.last = null;\n return;\n }\n tracker.last = { element: el, position: recordPosition(el), anchors: captureAnchors(el, null) };\n}\n\n/**\n * A layer opened or closed: re-record the focused element's place and overlays while it is still in\n * the document. An element focused as its popover opens (autoFocus) gets focus before the\n * popover's layer registers. Anchors found earlier are kept (a layer unregistering as its content\n * is deleted no longer reports it).\n */\nfunction refreshFocusRecord(tracker: FocusTracker): void {\n const last = tracker.last;\n if (!last || !last.element.isConnected) return;\n const anchors = captureAnchors(last.element, null);\n for (const anchor of last.anchors) {\n if (!anchors.some((entry) => entry.element === anchor.element)) anchors.push(anchor);\n }\n tracker.last = { element: last.element, position: recordPosition(last.element), anchors };\n}\n\n/** Installs the tracker's listeners while at least one `useRestoreFocus` is mounted. */\nfunction retainFocusTracker(): () => void {\n if (typeof document === 'undefined') return () => {};\n const tracker = getFocusTracker();\n tracker.users += 1;\n if (!tracker.uninstall) {\n const doc = document;\n const onFocusIn = (event: FocusEvent) => {\n if (isElementTarget(event.target)) recordFocus(tracker, event.target);\n };\n // Focus leaves for nowhere when the element is removed (some browsers fire focusout then) or\n // when the user presses a non-focusable spot. Decide once the current task has run: an element\n // still in the document that can take focus was left on purpose and is no opener to return to.\n const onFocusOut = (event: FocusEvent) => {\n const target = event.target;\n if (event.relatedTarget || !isElementTarget(target)) return;\n queueMicrotask(() => {\n if (tracker.last?.element !== target) return;\n if (!target.isConnected || !isFocusable(target)) return;\n if (target.ownerDocument.activeElement !== target) tracker.last = null;\n });\n };\n doc.addEventListener('focusin', onFocusIn, true);\n doc.addEventListener('focusout', onFocusOut, true);\n const unsubscribe = subscribeLayers(() => refreshFocusRecord(tracker));\n if (isElementTarget(doc.activeElement)) recordFocus(tracker, doc.activeElement);\n tracker.uninstall = () => {\n doc.removeEventListener('focusin', onFocusIn, true);\n doc.removeEventListener('focusout', onFocusOut, true);\n unsubscribe();\n tracker.last = null;\n };\n }\n let retained = true;\n return () => {\n if (!retained) return;\n retained = false;\n tracker.users = Math.max(0, tracker.users - 1);\n if (tracker.users > 0) return;\n tracker.uninstall?.();\n tracker.uninstall = null;\n };\n}\n\n/**\n * The tracker's record of the element focus was lost from: it no longer has focus and was removed,\n * or can no longer take focus (disabled, hidden, made inert). `null` when focus was moved away from\n * it on purpose, or it still has focus.\n */\nfunction getLostFocus(): OpenerRecord | null {\n const last = getFocusTracker().last;\n if (!last) return null;\n const { element } = last;\n if (element.ownerDocument.activeElement === element) return null;\n if (element.isConnected && isFocusable(element)) return null;\n return last;\n}\n\n/**\n * The element to restore to when the surface opens: the trigger, else the focused element, else —\n * focus already lost to `<body>` — the element the focus tracker saw lose it.\n */\nfunction captureOpener(options: UseRestoreFocusOptions): OpenerRecord | null {\n if (typeof document === 'undefined') return null;\n const { container, triggerRef } = options;\n const isCandidate = (el: Element | null | undefined): el is HTMLElement =>\n !!el &&\n el !== el.ownerDocument.body &&\n el !== el.ownerDocument.documentElement &&\n !(container && container.contains(el));\n const trigger = triggerRef?.current;\n const active = document.activeElement;\n let element: HTMLElement | null = null;\n if (isCandidate(trigger)) element = trigger;\n else if (isCandidate(active)) element = active;\n if (element) {\n return {\n element,\n position: recordPosition(element),\n anchors: captureAnchors(element, container),\n };\n }\n // The opener was removed earlier in this commit (a menu item in a popover that closed as this\n // surface opened), or can no longer take focus: use what the tracker recorded while it could.\n const lost = getLostFocus();\n if (!lost || !isCandidate(lost.element)) return null;\n return {\n element: lost.element,\n position: lost.position,\n anchors: lost.anchors.filter((anchor) => !(container && container.contains(anchor.element))),\n };\n}\n\n/** A layer's surface (or its first tabbable element), for the last-resort fallbacks. */\nfunction getLayerTargets(layer: LayerRecord | null): HTMLElement[] {\n if (!layer) return [];\n const targets: HTMLElement[] = [];\n for (const el of layer.getElements()) {\n if (!el) continue;\n targets.push(el);\n const first = getFirstTabbable(el);\n if (first) targets.push(first);\n }\n return targets;\n}\n\nfunction isAfterPoint(el: Element, point: DomPoint): boolean {\n const { ref, placement } = point;\n if (el === ref) return placement === 'before';\n const follows = (ref.compareDocumentPosition(el) & FOLLOWING) !== 0;\n return placement === 'before' ? follows : follows && !ref.contains(el);\n}\n\n/**\n * Where to look once the recorded element is gone (or cannot take focus): its nearest ancestor\n * still in the document, and the point where the element used to be. `null` when its whole overlay\n * (the portal wrapper) was removed: that spot means nothing on the page.\n */\nfunction resolvePoint(position: DomPosition): { root: Element; point: DomPoint } | null {\n const { path } = position;\n const index = path.findIndex((el) => el.isConnected);\n if (index === -1) return null;\n if (index === 0) {\n const root = path[0].parentElement;\n return root ? { root, point: { ref: path[0], placement: 'after' } } : null;\n }\n if (path.slice(0, index).some((el) => el.matches(PORTAL_SELECTOR))) return null;\n const root = path[index];\n const next = position.next[index - 1];\n if (next && next.parentElement === root) {\n return { root, point: { ref: next, placement: 'before' } };\n }\n const previous = position.previous[index - 1];\n if (previous && previous.parentElement === root) {\n return { root, point: { ref: previous, placement: 'after' } };\n }\n return { root, point: { ref: root, placement: 'before' } };\n}\n\n/**\n * Tabbable elements near a recorded position, nearest first. In the innermost surviving ancestor\n * that holds a valid one: the first after the old spot (where Tab would have gone from there),\n * else the last before it; then the same one level up. The search stops at the element's overlay\n * (its portal wrapper) and never reaches behind an open modal.\n */\nfunction getNearbyTargets(\n position: DomPosition,\n container: HTMLElement | null | undefined,\n): HTMLElement[] {\n const resolved = resolvePoint(position);\n if (!resolved) return [];\n const { root, point } = resolved;\n const body = root.ownerDocument.body;\n const levels: Element[] = [];\n for (let level: Element | null = root; level; level = level.parentElement) {\n if (isInsideOtherOpenModal(level)) break;\n levels.push(level);\n if (level === body || level.matches(PORTAL_SELECTOR)) break;\n }\n if (levels.length === 0) return [];\n const candidates = getTabbableElements(levels[levels.length - 1])\n .filter((el) => !(container && container.contains(el)) && isValidTarget(el))\n .sort((a, b) => ((a.compareDocumentPosition(b) & FOLLOWING) !== 0 ? -1 : 1));\n const targets: HTMLElement[] = [];\n for (const level of levels) {\n const inLevel = candidates.filter((el) => level.contains(el) && !targets.includes(el));\n const after = inLevel.find((el) => isAfterPoint(el, point));\n const before = inLevel.filter((el) => !isAfterPoint(el, point)).pop();\n if (after) targets.push(after);\n if (before) targets.push(before);\n }\n return targets;\n}\n\n/**\n * Whether the restore acts for this close: always while focus is inside the surface; otherwise\n * never for a hover close (`isClosingByHover`, asked only then), and with `onlyIfFocusInside` only\n * when focus was lost to `<body>`.\n */\nfunction shouldRestore(options: UseRestoreFocusOptions, isHoverClose: () => boolean): boolean {\n if (typeof document === 'undefined') return false;\n const active = document.activeElement;\n const onBody = !active || active === document.body || active === document.documentElement;\n if (!onBody && options.container?.contains(active)) return true;\n if (!onBody && options.onlyIfFocusInside) return false;\n return !isHoverClose();\n}\n\n/**\n * Where to go when the opener was removed or can no longer take focus, nearest first: the tabbable\n * element next to where it was, else the trigger of the overlay it was in (a menu item's menu\n * button), else the element next to that trigger.\n */\nfunction* getReplacementTargets(\n opener: OpenerRecord,\n container: HTMLElement | null | undefined,\n): Generator<HTMLElement> {\n yield* getNearbyTargets(opener.position, container);\n for (const anchor of opener.anchors) yield anchor.element;\n for (const anchor of opener.anchors) yield* getNearbyTargets(anchor.position, container);\n}\n\n/** Restore targets in order of preference, computed lazily (the later ones cost more). */\nfunction* restoreCandidates(\n latest: Latest,\n opener: OpenerRecord | null,\n): Generator<HTMLElement | null | undefined> {\n const { options, parentLayerId } = latest;\n yield options.finalFocusRef?.current;\n yield opener?.element;\n yield options.triggerRef?.current;\n yield options.fallback?.();\n const replacements = opener ? getReplacementTargets(opener, options.container) : null;\n const parentLayer = parentLayerId === null ? null : getLayer(parentLayerId);\n const outsideParent: HTMLElement[] = [];\n if (parentLayer) {\n // The surface was rendered inside a layer that stays open (a confirm Dialog in a Drawer): the\n // opener's replacement inside that layer (the next row after a delete) comes before the\n // layer's surface, so where the surface sits in the React tree does not change the result.\n for (const target of replacements ?? []) {\n if (isInsideLayerTree(parentLayer.id, target)) yield target;\n else outsideParent.push(target);\n }\n yield* getLayerTargets(parentLayer);\n yield* outsideParent;\n } else if (replacements) {\n yield* replacements;\n }\n // Still nothing: into the modal that stays open, never onto the inert page behind it.\n yield* getLayerTargets(getTopmostLayer((layer) => layer.kind === 'modal'));\n}\n\nfunction restore(latest: Latest, opener: OpenerRecord | null): void {\n const container = latest.options.container;\n for (const candidate of restoreCandidates(latest, opener)) {\n if (container && candidate && container.contains(candidate)) continue;\n if (isValidTarget(candidate) && focusElement(candidate, { preventScroll: true })) return;\n }\n}\n\n/**\n * Returns focus to where it came from when a surface closes (dialogs, drawers, popovers, menus,\n * the DatePicker calendar, TeachingPopover).\n *\n * - **Capture**: when `enabled` flips to `true`, the opener is captured in an insertion effect —\n * before React applies `autoFocus` inside the new surface — preferring `triggerRef.current` and\n * ignoring `<body>` and elements inside `container`. Its place in the document and the triggers\n * of the overlays it sits in are recorded with it. When focus is already on `<body>` because\n * the focused element was removed earlier in the same commit (a menu item in a popover that\n * closes as the dialog it opens appears, the popover coming first in the tree), a document\n * focus tracker supplies that element with its recorded place and overlay triggers. The tracker\n * runs while any instance of the hook is mounted, and it forgets an element the user moved focus\n * away from on purpose.\n * - **Restore** when `enabled` flips to `false` (layout phase) and when the component unmounts\n * while enabled. The unmount restore runs in a microtask and is cancelled if the same instance\n * mounts again, so React StrictMode's simulated unmount does not pull focus out of a surface\n * that just opened.\n * - **Targets**, first valid wins:\n * 1. `finalFocusRef` → the captured opener → `triggerRef` → `fallback()`.\n * 2. When the opener was removed or cannot take focus, its replacement, nearest first: the\n * tabbable element next to where it was (in the innermost surviving ancestor that holds one,\n * the next one — the next row's action after a delete — else the previous one; then the same\n * one level up), else the trigger of the overlay it was in (a menu item's menu button), else\n * the element next to that trigger. When the surface is rendered inside another open layer\n * (its parent layer, from `DismissLayerContext`: a confirm Dialog in a Drawer's content),\n * only the replacements inside that layer's tree are tried here.\n * 3. The parent layer's surface, then the replacements outside the parent layer.\n * 4. The surface of the modal layer that stays open.\n *\n * So a confirm Dialog rendered in a Drawer's content and one rendered next to the Drawer both\n * return focus to the adjacent row, not to the Drawer's panel. A target is valid when it is\n * connected, focusable, not inside `[inert]` or `[aria-hidden=\"true\"]`, and not cut off behind\n * another open modal layer — so focus never lands on the inert page behind a Drawer that stays\n * open, and is not dropped on `<body>` while a valid target exists. Focus uses `preventScroll`.\n * - `onlyIfFocusInside` (popovers): restores only when focus is inside the surface or was lost to\n * `<body>`.\n * - `isHoverClose`: a close by the hover intent restores only when focus is inside the surface, so\n * a hover close never moves focus from `<body>` or from where the user put it. The same holds for\n * a surface opened from inside one that closes by hover (a submenu, a hover card in a hover\n * card): every mounted instance is known to the others through the focus tracker's record.\n */\nexport function useRestoreFocus(options: UseRestoreFocusOptions): void {\n const parentLayerId = React.useContext(DismissLayerContext);\n const latestRef = useRef<Latest>({ options, parentLayerId });\n const capturedRef = useRef<OpenerRecord | null>(null);\n const insertionEnabledRef = useRef(false);\n const layoutEnabledRef = useRef(false);\n const scheduledRef = useRef<object | null>(null);\n const entryRef = useRef<SurfaceEntry | null>(null);\n const { enabled } = options;\n\n // Track focus while mounted, so an opener removed in the commit that opens the surface is known.\n // And be known to the other instances: a surface closing by hover takes along the surfaces opened\n // from inside it, whose closes are then hover closes too.\n useLayoutEffect(() => {\n const release = retainFocusTracker();\n const entry: SurfaceEntry = {\n isHoverClose: () => latestRef.current.options.isHoverClose?.() === true,\n getContainer: () => latestRef.current.options.container ?? null,\n getOpener: () =>\n capturedRef.current?.element ?? latestRef.current.options.triggerRef?.current ?? null,\n };\n entryRef.current = entry;\n const surfaces = getSurfaceEntries();\n surfaces.add(entry);\n return () => {\n release();\n // Kept to the end of the commit: a surface opened from inside this one, closing along with\n // it, still asks about it.\n queueMicrotask(() => surfaces.delete(entry));\n };\n }, []);\n\n // Mutation phase: record the latest options and capture the opener when `enabled` turns on,\n // before autoFocus (layout phase) or a focus trap's initial focus moves focus into the surface.\n useInsertionEffect(() => {\n latestRef.current = { options, parentLayerId };\n const wasEnabled = insertionEnabledRef.current;\n insertionEnabledRef.current = options.enabled;\n if (options.enabled && !wasEnabled) capturedRef.current = captureOpener(options);\n });\n\n // `enabled` true → false: restore in the layout phase (after every cleanup of this commit, so a\n // modal's isolation is already gone).\n useLayoutEffect(() => {\n const wasEnabled = layoutEnabledRef.current;\n layoutEnabledRef.current = enabled;\n if (!wasEnabled || enabled) return;\n const latest = latestRef.current;\n const captured = capturedRef.current;\n const entry = entryRef.current;\n // Decided before the opener is dropped: a hover close is also recognised through it.\n const acts = shouldRestore(latest.options, () => isHoverCloseOf(entry, latest.options));\n capturedRef.current = null;\n if (acts) restore(latest, captured);\n }, [enabled]);\n\n // Unmount while enabled: restore in a microtask, cancelled by a remount of this instance.\n useLayoutEffect(() => {\n const latest = latestRef;\n const captured = capturedRef;\n const scheduled = scheduledRef;\n const entryHolder = entryRef;\n scheduled.current = null;\n return () => {\n const snapshot = latest.current;\n if (!snapshot.options.enabled) return;\n // Decide now, while the surface is still in the document.\n const entry = entryHolder.current;\n if (!shouldRestore(snapshot.options, () => isHoverCloseOf(entry, snapshot.options))) return;\n const token = {};\n scheduled.current = token;\n const opener = captured.current;\n queueMicrotask(() => {\n if (scheduled.current !== token) return;\n scheduled.current = null;\n const active = typeof document === 'undefined' ? null : document.activeElement;\n const container = snapshot.options.container;\n // Focus placed elsewhere in the meantime (another surface opened) wins.\n if (\n active &&\n active !== document.body &&\n active !== document.documentElement &&\n !(container && container.contains(active))\n ) {\n return;\n }\n restore(snapshot, opener);\n });\n };\n }, []);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useRestoreFocus.cjs","names":["isFocusable","isInsideOtherOpenModal","getOpenLayers","isInsideLayerTree","compareLayers","getGlobalRegistry","subscribeLayers","getFirstTabbable","getTabbableElements","isDescendantLayer","getLayer","getTopmostLayer","focusElement","React","DismissLayerContext","useRef","require_runtime","require_globalRegistry","require_focus","require_layers","require_useDismiss","react","FOLLOWING","PORTAL_SELECTOR","isValidTarget","el","recordPosition","position","body","node","captureAnchors","opener","layers","layer","b","a","anchors","anchor","container","entry","getSurfaceEntries","tracker","getFocusTracker","isClosingByHover","seen","other","isHoverCloseOf","options","ELEMENT_NODE","isElementTarget","target","recordFocus","doc","refreshFocusRecord","last","retainFocusTracker","onFocusIn","event","onFocusOut","unsubscribe","retained","getLostFocus","element","captureOpener","isCandidate","trigger","triggerRef","active","lost","getLayerTargets","targets","first","isAfterPoint","point","ref","placement","follows","resolvePoint","index","path","root","next","previous","getNearbyTargets","resolved","levels","level","candidates","inLevel","after","before","isFocusLostFromInside","isInLayerOpenedFrom","layerId","shouldRestore","onBody","isHoverClose","getReplacementTargets","restoreCandidates","latest","replacements","parentLayer","parentLayerId","outsideParent","restore","candidate","useRestoreFocus","latestRef","capturedRef","insertionEnabledRef","layoutEnabledRef","scheduledRef","entryRef","release","surfaces","wasEnabled","enabled","captured","acts","scheduled","entryHolder","snapshot","token"],"sources":["../../src/hooks/useRestoreFocus.ts"],"sourcesContent":["import * as React from 'react';\nimport { useInsertionEffect, useLayoutEffect, useRef } from 'react';\nimport { focusElement, getFirstTabbable, getTabbableElements, isFocusable } from '../lib/focus';\nimport { getGlobalRegistry } from '../lib/globalRegistry';\nimport {\n ALLOW_OUTSIDE_SELECTOR,\n compareLayers,\n getLayer,\n getOpenLayers,\n getTopmostLayer,\n isDescendantLayer,\n isInsideLayerTree,\n isInsideOtherOpenModal,\n subscribeLayers,\n type LayerRecord,\n} from '../lib/layers';\nimport { DismissLayerContext } from './useDismiss';\n\n/** Options of {@link useRestoreFocus}. */\nexport interface UseRestoreFocusOptions {\n /** `true` while the surface is open. */\n enabled: boolean;\n /** The layer surface: opener candidates inside it are ignored. */\n container?: HTMLElement | null;\n /** The trigger: preferred restore target. */\n triggerRef?: React.RefObject<HTMLElement | null>;\n /** Consumer override: focused first when valid. */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** Used when neither the override, the opener nor the trigger can take focus. */\n fallback?: () => HTMLElement | null;\n /**\n * Popovers: restore only when focus was inside the surface (or lost to `<body>`) at close, so a\n * click that moved focus elsewhere is respected. @default false\n */\n onlyIfFocusInside?: boolean;\n /**\n * Read when the surface closes, or unmounts while open: `true` when the hover intent closed it\n * (Popover and Menu `openOnHover`, a submenu closing by hover). A hover close never moves focus:\n * it restores only while focus is inside the surface, so focus on `<body>` (where a hover-opened\n * surface leaves it) or elsewhere stays where it is. A surface opened from inside one that closes\n * by hover (its opener, else its trigger, lies in that surface: a submenu, a hover card in a\n * hover card, at any depth) is taken along, and its close counts as a hover close too. Every\n * other close keeps the rules above.\n */\n isHoverClose?: () => boolean;\n /**\n * Surfaces that do not trap focus (a non-modal Dialog or Drawer, an inline Drawer): restore only\n * when focus is inside the surface at close, or was lost to `<body>` from an element inside it\n * (removed, or made unable to take focus). Focus elsewhere, or on `<body>` for another reason\n * (nothing had focus, a press on a spot that takes no focus, a close from code), stays where it\n * is. Wins over `onlyIfFocusInside`. Focus in a layer opened from the surface (a Popover or a\n * confirm Dialog, portaled outside it) counts as inside: a descendant layer of `layerId`, or a\n * layer anchored to an element inside the surface; so does focus lost to `<body>` from one.\n * @default false\n */\n requireFocusInside?: boolean;\n /**\n * The surface's own dismiss layer, with `requireFocusInside`: focus in one of its descendant\n * layers counts as inside the surface, also after the surface's layer has unregistered (in the\n * commit that closes it).\n */\n layerId?: string;\n}\n\ninterface Latest {\n options: UseRestoreFocusOptions;\n parentLayerId: string | null;\n}\n\n/** Where an element sat in the document, recorded so a spot near it can be found once it is gone. */\ninterface DomPosition {\n /** The element and its ancestors up to `<body>`, innermost first. */\n path: Element[];\n /** The next element sibling of each `path` entry when it was recorded. */\n next: Array<Element | null>;\n /** The previous element sibling of each `path` entry when it was recorded. */\n previous: Array<Element | null>;\n}\n\n/** What is captured about the opener when the surface opens. */\ninterface OpenerRecord {\n element: HTMLElement;\n /** Its place in the document, used when it is removed or can no longer take focus. */\n position: DomPosition;\n /** The anchors (triggers) of the open layers whose tree held it, innermost layer first. */\n anchors: Array<{ element: HTMLElement; position: DomPosition }>;\n}\n\n/** A point in document order: just before `ref`, or just after `ref` and its subtree. */\ninterface DomPoint {\n ref: Element;\n placement: 'before' | 'after';\n}\n\nconst FOLLOWING = 4; // Node.DOCUMENT_POSITION_FOLLOWING\nconst PORTAL_SELECTOR = '[data-wave-portal]';\n\nfunction isValidTarget(el: HTMLElement | null | undefined): el is HTMLElement {\n if (!el || !el.isConnected) return false;\n if (!isFocusable(el)) return false; // also rejects [inert] ancestors, hidden and disabled\n if (el.closest('[aria-hidden=\"true\"]')) return false;\n return !isInsideOtherOpenModal(el);\n}\n\nfunction recordPosition(el: Element): DomPosition {\n const position: DomPosition = { path: [], next: [], previous: [] };\n const body = el.ownerDocument.body;\n for (let node: Element | null = el; node; node = node.parentElement) {\n position.path.push(node);\n position.next.push(node.nextElementSibling);\n position.previous.push(node.previousElementSibling);\n if (node === body) break;\n }\n return position;\n}\n\n/**\n * The anchors of the open layers whose tree contains `opener` (a menu item's menu button),\n * innermost layer first. An opener in an allow-listed region (a toast) belongs to no layer.\n */\nfunction captureAnchors(\n opener: HTMLElement,\n container: HTMLElement | null | undefined,\n): OpenerRecord['anchors'] {\n if (opener.closest(ALLOW_OUTSIDE_SELECTOR)) return [];\n const layers = getOpenLayers()\n .filter((layer) => isInsideLayerTree(layer.id, opener))\n .sort((a, b) => compareLayers(b, a));\n const anchors: OpenerRecord['anchors'] = [];\n for (const layer of layers) {\n const anchor = layer.getAnchor();\n if (!anchor || anchor === opener || (container && container.contains(anchor))) continue;\n if (anchors.some((entry) => entry.element === anchor)) continue;\n anchors.push({ element: anchor, position: recordPosition(anchor) });\n }\n return anchors;\n}\n\n// ---------------------------------------------------------------------------\n// Focus tracker\n// ---------------------------------------------------------------------------\n\n/**\n * Remembers the last focused element, with its place in the document and the anchors of the\n * overlays that held it, recorded while it is still in the document. A surface captures its opener\n * in the mutation phase, and by then React has already deleted anything earlier in the tree that\n * the same commit removes. A popover rendered before a dialog, whose menu item closes the popover\n * and opens the dialog, has lost its menu item (and focus is on `<body>`) when the dialog captures.\n * The record still leads the restore to the popover's trigger. It lives in\n * `getGlobalRegistry('restoreFocusTracker')`, so two copies of the library share one set of\n * listeners.\n */\ninterface FocusTracker {\n /** Mounted `useRestoreFocus` instances: the listeners are installed while there is one. */\n users: number;\n /** The last focused element; `null` once focus was moved away from it on purpose. */\n last: OpenerRecord | null;\n /** Removes the listeners; `null` while none are installed. */\n uninstall: (() => void) | null;\n /**\n * The mounted surfaces, as the other instances see them (see {@link isClosingByHover}). Created\n * on first use: a tracker made by another copy of the library does not have it.\n */\n surfaces?: Set<SurfaceEntry>;\n}\n\n/** A mounted `useRestoreFocus`, as the other instances see it. */\ninterface SurfaceEntry {\n /** Whether the surface is closing by hover (its `isHoverClose`). */\n isHoverClose(): boolean;\n /** The surface element, while there is one. */\n getContainer(): HTMLElement | null;\n /** The element the surface was opened from: its captured opener, else its trigger. */\n getOpener(): HTMLElement | null;\n}\n\nfunction getSurfaceEntries(): Set<SurfaceEntry> {\n const tracker = getFocusTracker();\n tracker.surfaces ??= new Set();\n return tracker.surfaces;\n}\n\n/**\n * Whether the close of `entry` is a hover close: its own, or that of a surface holding the element\n * it was opened from (a submenu in a menu that closes by hover, a hover card inside a hover card,\n * at any depth), which takes it along.\n */\nfunction isClosingByHover(entry: SurfaceEntry, seen = new Set<SurfaceEntry>()): boolean {\n if (seen.has(entry)) return false;\n seen.add(entry);\n if (entry.isHoverClose()) return true;\n const opener = entry.getOpener();\n if (!opener) return false;\n for (const other of getSurfaceEntries()) {\n const container = other === entry ? null : other.getContainer();\n if (container && container.contains(opener) && isClosingByHover(other, seen)) return true;\n }\n return false;\n}\n\n/** Whether this close is a hover close: the surface's own, or that of a surface it was opened from. */\nfunction isHoverCloseOf(entry: SurfaceEntry | null, options: UseRestoreFocusOptions): boolean {\n return entry ? isClosingByHover(entry) : options.isHoverClose?.() === true;\n}\n\nfunction getFocusTracker(): FocusTracker {\n return getGlobalRegistry<FocusTracker>('restoreFocusTracker', () => ({\n users: 0,\n last: null,\n uninstall: null,\n }));\n}\n\nconst ELEMENT_NODE = 1;\n\nfunction isElementTarget(target: EventTarget | null): target is HTMLElement {\n return !!target && (target as Partial<Node>).nodeType === ELEMENT_NODE;\n}\n\nfunction recordFocus(tracker: FocusTracker, el: HTMLElement): void {\n const doc = el.ownerDocument;\n if (el === doc.body || el === doc.documentElement) {\n tracker.last = null;\n return;\n }\n tracker.last = { element: el, position: recordPosition(el), anchors: captureAnchors(el, null) };\n}\n\n/**\n * A layer opened or closed: re-record the focused element's place and overlays while it is still in\n * the document. An element focused as its popover opens (autoFocus) gets focus before the\n * popover's layer registers. Anchors found earlier are kept (a layer unregistering as its content\n * is deleted no longer reports it).\n */\nfunction refreshFocusRecord(tracker: FocusTracker): void {\n const last = tracker.last;\n if (!last || !last.element.isConnected) return;\n const anchors = captureAnchors(last.element, null);\n for (const anchor of last.anchors) {\n if (!anchors.some((entry) => entry.element === anchor.element)) anchors.push(anchor);\n }\n tracker.last = { element: last.element, position: recordPosition(last.element), anchors };\n}\n\n/** Installs the tracker's listeners while at least one `useRestoreFocus` is mounted. */\nfunction retainFocusTracker(): () => void {\n if (typeof document === 'undefined') return () => {};\n const tracker = getFocusTracker();\n tracker.users += 1;\n if (!tracker.uninstall) {\n const doc = document;\n const onFocusIn = (event: FocusEvent) => {\n if (isElementTarget(event.target)) recordFocus(tracker, event.target);\n };\n // Focus leaves for nowhere when the element is removed (some browsers fire focusout then) or\n // when the user presses a non-focusable spot. Decide once the current task has run: an element\n // still in the document that can take focus was left on purpose and is no opener to return to.\n const onFocusOut = (event: FocusEvent) => {\n const target = event.target;\n if (event.relatedTarget || !isElementTarget(target)) return;\n queueMicrotask(() => {\n if (tracker.last?.element !== target) return;\n if (!target.isConnected || !isFocusable(target)) return;\n if (target.ownerDocument.activeElement !== target) tracker.last = null;\n });\n };\n doc.addEventListener('focusin', onFocusIn, true);\n doc.addEventListener('focusout', onFocusOut, true);\n const unsubscribe = subscribeLayers(() => refreshFocusRecord(tracker));\n if (isElementTarget(doc.activeElement)) recordFocus(tracker, doc.activeElement);\n tracker.uninstall = () => {\n doc.removeEventListener('focusin', onFocusIn, true);\n doc.removeEventListener('focusout', onFocusOut, true);\n unsubscribe();\n tracker.last = null;\n };\n }\n let retained = true;\n return () => {\n if (!retained) return;\n retained = false;\n tracker.users = Math.max(0, tracker.users - 1);\n if (tracker.users > 0) return;\n tracker.uninstall?.();\n tracker.uninstall = null;\n };\n}\n\n/**\n * The tracker's record of the element focus was lost from: it no longer has focus and was removed,\n * or can no longer take focus (disabled, hidden, made inert). `null` when focus was moved away from\n * it on purpose, or it still has focus.\n */\nfunction getLostFocus(): OpenerRecord | null {\n const last = getFocusTracker().last;\n if (!last) return null;\n const { element } = last;\n if (element.ownerDocument.activeElement === element) return null;\n if (element.isConnected && isFocusable(element)) return null;\n return last;\n}\n\n/**\n * The element to restore to when the surface opens: the trigger, else the focused element, else —\n * focus already lost to `<body>` — the element the focus tracker saw lose it.\n */\nfunction captureOpener(options: UseRestoreFocusOptions): OpenerRecord | null {\n if (typeof document === 'undefined') return null;\n const { container, triggerRef } = options;\n const isCandidate = (el: Element | null | undefined): el is HTMLElement =>\n !!el &&\n el !== el.ownerDocument.body &&\n el !== el.ownerDocument.documentElement &&\n !(container && container.contains(el));\n const trigger = triggerRef?.current;\n const active = document.activeElement;\n let element: HTMLElement | null = null;\n if (isCandidate(trigger)) element = trigger;\n else if (isCandidate(active)) element = active;\n if (element) {\n return {\n element,\n position: recordPosition(element),\n anchors: captureAnchors(element, container),\n };\n }\n // The opener was removed earlier in this commit (a menu item in a popover that closed as this\n // surface opened), or can no longer take focus: use what the tracker recorded while it could.\n const lost = getLostFocus();\n if (!lost || !isCandidate(lost.element)) return null;\n return {\n element: lost.element,\n position: lost.position,\n anchors: lost.anchors.filter((anchor) => !(container && container.contains(anchor.element))),\n };\n}\n\n/** A layer's surface (or its first tabbable element), for the last-resort fallbacks. */\nfunction getLayerTargets(layer: LayerRecord | null): HTMLElement[] {\n if (!layer) return [];\n const targets: HTMLElement[] = [];\n for (const el of layer.getElements()) {\n if (!el) continue;\n targets.push(el);\n const first = getFirstTabbable(el);\n if (first) targets.push(first);\n }\n return targets;\n}\n\nfunction isAfterPoint(el: Element, point: DomPoint): boolean {\n const { ref, placement } = point;\n if (el === ref) return placement === 'before';\n const follows = (ref.compareDocumentPosition(el) & FOLLOWING) !== 0;\n return placement === 'before' ? follows : follows && !ref.contains(el);\n}\n\n/**\n * Where to look once the recorded element is gone (or cannot take focus): its nearest ancestor\n * still in the document, and the point where the element used to be. `null` when its whole overlay\n * (the portal wrapper) was removed: that spot means nothing on the page.\n */\nfunction resolvePoint(position: DomPosition): { root: Element; point: DomPoint } | null {\n const { path } = position;\n const index = path.findIndex((el) => el.isConnected);\n if (index === -1) return null;\n if (index === 0) {\n const root = path[0].parentElement;\n return root ? { root, point: { ref: path[0], placement: 'after' } } : null;\n }\n if (path.slice(0, index).some((el) => el.matches(PORTAL_SELECTOR))) return null;\n const root = path[index];\n const next = position.next[index - 1];\n if (next && next.parentElement === root) {\n return { root, point: { ref: next, placement: 'before' } };\n }\n const previous = position.previous[index - 1];\n if (previous && previous.parentElement === root) {\n return { root, point: { ref: previous, placement: 'after' } };\n }\n return { root, point: { ref: root, placement: 'before' } };\n}\n\n/**\n * Tabbable elements near a recorded position, nearest first. In the innermost surviving ancestor\n * that holds a valid one: the first after the old spot (where Tab would have gone from there),\n * else the last before it; then the same one level up. The search stops at the element's overlay\n * (its portal wrapper) and never reaches behind an open modal.\n */\nfunction getNearbyTargets(\n position: DomPosition,\n container: HTMLElement | null | undefined,\n): HTMLElement[] {\n const resolved = resolvePoint(position);\n if (!resolved) return [];\n const { root, point } = resolved;\n const body = root.ownerDocument.body;\n const levels: Element[] = [];\n for (let level: Element | null = root; level; level = level.parentElement) {\n if (isInsideOtherOpenModal(level)) break;\n levels.push(level);\n if (level === body || level.matches(PORTAL_SELECTOR)) break;\n }\n if (levels.length === 0) return [];\n const candidates = getTabbableElements(levels[levels.length - 1])\n .filter((el) => !(container && container.contains(el)) && isValidTarget(el))\n .sort((a, b) => ((a.compareDocumentPosition(b) & FOLLOWING) !== 0 ? -1 : 1));\n const targets: HTMLElement[] = [];\n for (const level of levels) {\n const inLevel = candidates.filter((el) => level.contains(el) && !targets.includes(el));\n const after = inLevel.find((el) => isAfterPoint(el, point));\n const before = inLevel.filter((el) => !isAfterPoint(el, point)).pop();\n if (after) targets.push(after);\n if (before) targets.push(before);\n }\n return targets;\n}\n\n/**\n * Whether focus was lost to `<body>` from an element inside `container`: the focus tracker's record\n * of the element that lost it ({@link getLostFocus}) lies in the container (its recorded path holds\n * it), also when the element has been removed since.\n */\nfunction isFocusLostFromInside(container: HTMLElement | null | undefined): boolean {\n if (!container) return false;\n const lost = getLostFocus();\n if (!lost) return false;\n if (lost.position.path.includes(container)) return true;\n // Lost from a layer opened from the surface: the overlays that held it are anchored inside.\n return lost.anchors.some((anchor) => anchor.position.path.includes(container));\n}\n\n/**\n * Whether `active` is in a layer opened from the surface (portaled outside it): a descendant layer\n * of the surface's layer (`layerId`), or an open layer whose tree holds it and whose anchor (its\n * trigger) is inside the surface. The toast region counts as inside every layer, never here.\n */\nfunction isInLayerOpenedFrom(\n active: Element,\n container: HTMLElement | null | undefined,\n layerId: string | undefined,\n): boolean {\n if (!container || active.closest(ALLOW_OUTSIDE_SELECTOR)) return false;\n return getOpenLayers().some((layer) => {\n if (layer.id === layerId || !isInsideLayerTree(layer.id, active)) return false;\n if (layerId !== undefined && isDescendantLayer(layer.id, layerId)) return true;\n const anchor = layer.getAnchor();\n return !!anchor && container.contains(anchor);\n });\n}\n\n/**\n * Whether the restore acts for this close: always while focus is inside the surface; otherwise\n * never for a hover close (`isClosingByHover`, asked only then), and with `onlyIfFocusInside` only\n * when focus was lost to `<body>`. With `requireFocusInside`, also while focus is in a layer opened\n * from the surface, from `<body>` only when focus was lost there from inside the surface (or from\n * such a layer), and never from anywhere else.\n */\nfunction shouldRestore(options: UseRestoreFocusOptions, isHoverClose: () => boolean): boolean {\n if (typeof document === 'undefined') return false;\n const active = document.activeElement;\n const onBody = !active || active === document.body || active === document.documentElement;\n if (!onBody && options.container?.contains(active)) return true;\n if (options.requireFocusInside) {\n if (!onBody) return isInLayerOpenedFrom(active, options.container, options.layerId);\n return isFocusLostFromInside(options.container) && !isHoverClose();\n }\n if (!onBody && options.onlyIfFocusInside) return false;\n return !isHoverClose();\n}\n\n/**\n * Where to go when the opener was removed or can no longer take focus, nearest first: the tabbable\n * element next to where it was, else the trigger of the overlay it was in (a menu item's menu\n * button), else the element next to that trigger.\n */\nfunction* getReplacementTargets(\n opener: OpenerRecord,\n container: HTMLElement | null | undefined,\n): Generator<HTMLElement> {\n yield* getNearbyTargets(opener.position, container);\n for (const anchor of opener.anchors) yield anchor.element;\n for (const anchor of opener.anchors) yield* getNearbyTargets(anchor.position, container);\n}\n\n/** Restore targets in order of preference, computed lazily (the later ones cost more). */\nfunction* restoreCandidates(\n latest: Latest,\n opener: OpenerRecord | null,\n): Generator<HTMLElement | null | undefined> {\n const { options, parentLayerId } = latest;\n yield options.finalFocusRef?.current;\n yield opener?.element;\n yield options.triggerRef?.current;\n yield options.fallback?.();\n const replacements = opener ? getReplacementTargets(opener, options.container) : null;\n const parentLayer = parentLayerId === null ? null : getLayer(parentLayerId);\n const outsideParent: HTMLElement[] = [];\n if (parentLayer) {\n // The surface was rendered inside a layer that stays open (a confirm Dialog in a Drawer): the\n // opener's replacement inside that layer (the next row after a delete) comes before the\n // layer's surface, so where the surface sits in the React tree does not change the result.\n for (const target of replacements ?? []) {\n if (isInsideLayerTree(parentLayer.id, target)) yield target;\n else outsideParent.push(target);\n }\n yield* getLayerTargets(parentLayer);\n yield* outsideParent;\n } else if (replacements) {\n yield* replacements;\n }\n // Still nothing: into the modal that stays open, never onto the inert page behind it.\n yield* getLayerTargets(getTopmostLayer((layer) => layer.kind === 'modal'));\n}\n\nfunction restore(latest: Latest, opener: OpenerRecord | null): void {\n const container = latest.options.container;\n for (const candidate of restoreCandidates(latest, opener)) {\n if (container && candidate && container.contains(candidate)) continue;\n if (isValidTarget(candidate) && focusElement(candidate, { preventScroll: true })) return;\n }\n}\n\n/**\n * Returns focus to where it came from when a surface closes (dialogs, drawers, popovers, menus,\n * the DatePicker calendar, TeachingPopover).\n *\n * - **Capture**: when `enabled` flips to `true`, the opener is captured in an insertion effect —\n * before React applies `autoFocus` inside the new surface — preferring `triggerRef.current` and\n * ignoring `<body>` and elements inside `container`. When that finds nothing (a surface that\n * mounts open, before the refs of its commit are attached), it is captured again in the layout\n * phase of the same commit. Its place in the document and the triggers of the overlays it sits\n * in are recorded with it. When focus is already on `<body>` because\n * the focused element was removed earlier in the same commit (a menu item in a popover that\n * closes as the dialog it opens appears, the popover coming first in the tree), a document\n * focus tracker supplies that element with its recorded place and overlay triggers. The tracker\n * runs while any instance of the hook is mounted, and it forgets an element the user moved focus\n * away from on purpose.\n * - **Restore** when `enabled` flips to `false` (layout phase) and when the component unmounts\n * while enabled. The unmount restore runs in a microtask and is cancelled if the same instance\n * mounts again, so React StrictMode's simulated unmount does not pull focus out of a surface\n * that just opened.\n * - **Targets**, first valid wins:\n * 1. `finalFocusRef` → the captured opener → `triggerRef` → `fallback()`.\n * 2. When the opener was removed or cannot take focus, its replacement, nearest first: the\n * tabbable element next to where it was (in the innermost surviving ancestor that holds one,\n * the next one — the next row's action after a delete — else the previous one; then the same\n * one level up), else the trigger of the overlay it was in (a menu item's menu button), else\n * the element next to that trigger. When the surface is rendered inside another open layer\n * (its parent layer, from `DismissLayerContext`: a confirm Dialog in a Drawer's content),\n * only the replacements inside that layer's tree are tried here.\n * 3. The parent layer's surface, then the replacements outside the parent layer.\n * 4. The surface of the modal layer that stays open.\n *\n * So a confirm Dialog rendered in a Drawer's content and one rendered next to the Drawer both\n * return focus to the adjacent row, not to the Drawer's panel. A target is valid when it is\n * connected, focusable, not inside `[inert]` or `[aria-hidden=\"true\"]`, and not cut off behind\n * another open modal layer — so focus never lands on the inert page behind a Drawer that stays\n * open, and is not dropped on `<body>` while a valid target exists. Focus uses `preventScroll`.\n * - `onlyIfFocusInside` (popovers): restores only when focus is inside the surface or was lost to\n * `<body>`.\n * - `requireFocusInside` (surfaces that do not trap focus: a non-modal Dialog or Drawer, an inline\n * Drawer): restores only when focus is inside the surface or in a layer opened from it (a\n * descendant layer of `layerId`, or a layer anchored inside the surface), or was lost to\n * `<body>` from an element in either; a close from code while focus is on `<body>` or on the\n * page moves nothing.\n * - `isHoverClose`: a close by the hover intent restores only when focus is inside the surface, so\n * a hover close never moves focus from `<body>` or from where the user put it. The same holds for\n * a surface opened from inside one that closes by hover (a submenu, a hover card in a hover\n * card): every mounted instance is known to the others through the focus tracker's record.\n */\nexport function useRestoreFocus(options: UseRestoreFocusOptions): void {\n const parentLayerId = React.useContext(DismissLayerContext);\n const latestRef = useRef<Latest>({ options, parentLayerId });\n const capturedRef = useRef<OpenerRecord | null>(null);\n const insertionEnabledRef = useRef(false);\n const layoutEnabledRef = useRef(false);\n const scheduledRef = useRef<object | null>(null);\n const entryRef = useRef<SurfaceEntry | null>(null);\n const { enabled } = options;\n\n // Track focus while mounted, so an opener removed in the commit that opens the surface is known.\n // And be known to the other instances: a surface closing by hover takes along the surfaces opened\n // from inside it, whose closes are then hover closes too.\n useLayoutEffect(() => {\n const release = retainFocusTracker();\n const entry: SurfaceEntry = {\n isHoverClose: () => latestRef.current.options.isHoverClose?.() === true,\n getContainer: () => latestRef.current.options.container ?? null,\n getOpener: () =>\n capturedRef.current?.element ?? latestRef.current.options.triggerRef?.current ?? null,\n };\n entryRef.current = entry;\n const surfaces = getSurfaceEntries();\n surfaces.add(entry);\n return () => {\n release();\n // Kept to the end of the commit: a surface opened from inside this one, closing along with\n // it, still asks about it.\n queueMicrotask(() => surfaces.delete(entry));\n };\n }, []);\n\n // Mutation phase: record the latest options and capture the opener when `enabled` turns on,\n // before autoFocus (layout phase) or a focus trap's initial focus moves focus into the surface.\n useInsertionEffect(() => {\n latestRef.current = { options, parentLayerId };\n const wasEnabled = insertionEnabledRef.current;\n insertionEnabledRef.current = options.enabled;\n if (options.enabled && !wasEnabled) capturedRef.current = captureOpener(options);\n });\n\n // `enabled` false → true with nothing captured: capture again in the layout phase. A surface\n // that mounts open (an inline Drawer with `defaultOpen`) captured before the refs of this commit\n // were attached, so its trigger was not known yet.\n // `enabled` true → false: restore in the layout phase (after every cleanup of this commit, so a\n // modal's isolation is already gone).\n useLayoutEffect(() => {\n const wasEnabled = layoutEnabledRef.current;\n layoutEnabledRef.current = enabled;\n if (enabled && !wasEnabled && !capturedRef.current) {\n capturedRef.current = captureOpener(latestRef.current.options);\n }\n if (!wasEnabled || enabled) return;\n const latest = latestRef.current;\n const captured = capturedRef.current;\n const entry = entryRef.current;\n // Decided before the opener is dropped: a hover close is also recognised through it.\n const acts = shouldRestore(latest.options, () => isHoverCloseOf(entry, latest.options));\n capturedRef.current = null;\n if (acts) restore(latest, captured);\n }, [enabled]);\n\n // Unmount while enabled: restore in a microtask, cancelled by a remount of this instance.\n useLayoutEffect(() => {\n const latest = latestRef;\n const captured = capturedRef;\n const scheduled = scheduledRef;\n const entryHolder = entryRef;\n scheduled.current = null;\n return () => {\n const snapshot = latest.current;\n if (!snapshot.options.enabled) return;\n // Decide now, while the surface is still in the document.\n const entry = entryHolder.current;\n if (!shouldRestore(snapshot.options, () => isHoverCloseOf(entry, snapshot.options))) return;\n const token = {};\n scheduled.current = token;\n const opener = captured.current;\n queueMicrotask(() => {\n if (scheduled.current !== token) return;\n scheduled.current = null;\n const active = typeof document === 'undefined' ? null : document.activeElement;\n const container = snapshot.options.container;\n // Focus placed elsewhere in the meantime (another surface opened) wins.\n if (\n active &&\n active !== document.body &&\n active !== document.documentElement &&\n !(container && container.contains(active))\n ) {\n return;\n }\n restore(snapshot, opener);\n });\n };\n }, []);\n}\n"],"mappings":"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"}
@@ -1,16 +1,16 @@
1
1
  "use client";
2
2
  import { getGlobalRegistry as e } from "../lib/globalRegistry.mjs";
3
3
  import { focusElement as t, getFirstTabbable as n, getTabbableElements as r, isFocusable as i } from "../lib/focus.mjs";
4
- import { compareLayers as a, getLayer as o, getOpenLayers as s, getTopmostLayer as c, isInsideLayerTree as l, isInsideOtherOpenModal as u, subscribeLayers as d } from "../lib/layers.mjs";
5
- import { DismissLayerContext as f } from "./useDismiss.mjs";
6
- import * as p from "react";
7
- import { useInsertionEffect as m, useLayoutEffect as h, useRef as g } from "react";
4
+ import { compareLayers as a, getLayer as o, getOpenLayers as s, getTopmostLayer as c, isDescendantLayer as l, isInsideLayerTree as u, isInsideOtherOpenModal as d, subscribeLayers as f } from "../lib/layers.mjs";
5
+ import { DismissLayerContext as p } from "./useDismiss.mjs";
6
+ import * as m from "react";
7
+ import { useInsertionEffect as h, useLayoutEffect as g, useRef as _ } from "react";
8
8
  //#region src/hooks/useRestoreFocus.ts
9
- var _ = 4, v = "[data-wave-portal]";
10
- function y(e) {
11
- return !e || !e.isConnected || !i(e) || e.closest("[aria-hidden=\"true\"]") ? !1 : !u(e);
12
- }
9
+ var v = 4, y = "[data-wave-portal]";
13
10
  function b(e) {
11
+ return !e || !e.isConnected || !i(e) || e.closest("[aria-hidden=\"true\"]") ? !1 : !d(e);
12
+ }
13
+ function x(e) {
14
14
  let t = {
15
15
  path: [],
16
16
  next: [],
@@ -19,48 +19,48 @@ function b(e) {
19
19
  for (let r = e; r && (t.path.push(r), t.next.push(r.nextElementSibling), t.previous.push(r.previousElementSibling), r !== n); r = r.parentElement);
20
20
  return t;
21
21
  }
22
- function x(e, t) {
22
+ function S(e, t) {
23
23
  if (e.closest("[data-wave-focus-trap-allow]")) return [];
24
- let n = s().filter((t) => l(t.id, e)).sort((e, t) => a(t, e)), r = [];
24
+ let n = s().filter((t) => u(t.id, e)).sort((e, t) => a(t, e)), r = [];
25
25
  for (let i of n) {
26
26
  let n = i.getAnchor();
27
27
  !n || n === e || t && t.contains(n) || r.some((e) => e.element === n) || r.push({
28
28
  element: n,
29
- position: b(n)
29
+ position: x(n)
30
30
  });
31
31
  }
32
32
  return r;
33
33
  }
34
- function S() {
35
- let e = T();
34
+ function C() {
35
+ let e = E();
36
36
  return e.surfaces ??= /* @__PURE__ */ new Set(), e.surfaces;
37
37
  }
38
- function C(e, t = /* @__PURE__ */ new Set()) {
38
+ function w(e, t = /* @__PURE__ */ new Set()) {
39
39
  if (t.has(e)) return !1;
40
40
  if (t.add(e), e.isHoverClose()) return !0;
41
41
  let n = e.getOpener();
42
42
  if (!n) return !1;
43
- for (let r of S()) {
43
+ for (let r of C()) {
44
44
  let i = r === e ? null : r.getContainer();
45
- if (i && i.contains(n) && C(r, t)) return !0;
45
+ if (i && i.contains(n) && w(r, t)) return !0;
46
46
  }
47
47
  return !1;
48
48
  }
49
- function w(e, t) {
50
- return e ? C(e) : t.isHoverClose?.() === !0;
49
+ function T(e, t) {
50
+ return e ? w(e) : t.isHoverClose?.() === !0;
51
51
  }
52
- function T() {
52
+ function E() {
53
53
  return e("restoreFocusTracker", () => ({
54
54
  users: 0,
55
55
  last: null,
56
56
  uninstall: null
57
57
  }));
58
58
  }
59
- var E = 1;
60
- function D(e) {
61
- return !!e && e.nodeType === E;
59
+ var D = 1;
60
+ function O(e) {
61
+ return !!e && e.nodeType === D;
62
62
  }
63
- function O(e, t) {
63
+ function k(e, t) {
64
64
  let n = t.ownerDocument;
65
65
  if (t === n.body || t === n.documentElement) {
66
66
  e.last = null;
@@ -68,36 +68,36 @@ function O(e, t) {
68
68
  }
69
69
  e.last = {
70
70
  element: t,
71
- position: b(t),
72
- anchors: x(t, null)
71
+ position: x(t),
72
+ anchors: S(t, null)
73
73
  };
74
74
  }
75
- function k(e) {
75
+ function A(e) {
76
76
  let t = e.last;
77
77
  if (!t || !t.element.isConnected) return;
78
- let n = x(t.element, null);
78
+ let n = S(t.element, null);
79
79
  for (let e of t.anchors) n.some((t) => t.element === e.element) || n.push(e);
80
80
  e.last = {
81
81
  element: t.element,
82
- position: b(t.element),
82
+ position: x(t.element),
83
83
  anchors: n
84
84
  };
85
85
  }
86
- function A() {
86
+ function j() {
87
87
  if (typeof document > "u") return () => {};
88
- let e = T();
88
+ let e = E();
89
89
  if (e.users += 1, !e.uninstall) {
90
90
  let t = document, n = (t) => {
91
- D(t.target) && O(e, t.target);
91
+ O(t.target) && k(e, t.target);
92
92
  }, r = (t) => {
93
93
  let n = t.target;
94
- !t.relatedTarget && D(n) && queueMicrotask(() => {
94
+ !t.relatedTarget && O(n) && queueMicrotask(() => {
95
95
  e.last?.element === n && n.isConnected && i(n) && n.ownerDocument.activeElement !== n && (e.last = null);
96
96
  });
97
97
  };
98
98
  t.addEventListener("focusin", n, !0), t.addEventListener("focusout", r, !0);
99
- let a = d(() => k(e));
100
- D(t.activeElement) && O(e, t.activeElement), e.uninstall = () => {
99
+ let a = f(() => A(e));
100
+ O(t.activeElement) && k(e, t.activeElement), e.uninstall = () => {
101
101
  t.removeEventListener("focusin", n, !0), t.removeEventListener("focusout", r, !0), a(), e.last = null;
102
102
  };
103
103
  }
@@ -106,28 +106,28 @@ function A() {
106
106
  t && (t = !1, e.users = Math.max(0, e.users - 1), !(e.users > 0) && (e.uninstall?.(), e.uninstall = null));
107
107
  };
108
108
  }
109
- function j() {
110
- let e = T().last;
109
+ function M() {
110
+ let e = E().last;
111
111
  if (!e) return null;
112
112
  let { element: t } = e;
113
113
  return t.ownerDocument.activeElement === t || t.isConnected && i(t) ? null : e;
114
114
  }
115
- function M(e) {
115
+ function N(e) {
116
116
  if (typeof document > "u") return null;
117
117
  let { container: t, triggerRef: n } = e, r = (e) => !!e && e !== e.ownerDocument.body && e !== e.ownerDocument.documentElement && !(t && t.contains(e)), i = n?.current, a = document.activeElement, o = null;
118
118
  if (r(i) ? o = i : r(a) && (o = a), o) return {
119
119
  element: o,
120
- position: b(o),
121
- anchors: x(o, t)
120
+ position: x(o),
121
+ anchors: S(o, t)
122
122
  };
123
- let s = j();
123
+ let s = M();
124
124
  return !s || !r(s.element) ? null : {
125
125
  element: s.element,
126
126
  position: s.position,
127
127
  anchors: s.anchors.filter((e) => !(t && t.contains(e.element)))
128
128
  };
129
129
  }
130
- function N(e) {
130
+ function P(e) {
131
131
  if (!e) return [];
132
132
  let t = [];
133
133
  for (let r of e.getElements()) {
@@ -138,13 +138,13 @@ function N(e) {
138
138
  }
139
139
  return t;
140
140
  }
141
- function P(e, t) {
141
+ function F(e, t) {
142
142
  let { ref: n, placement: r } = t;
143
143
  if (e === n) return r === "before";
144
- let i = (n.compareDocumentPosition(e) & _) !== 0;
144
+ let i = (n.compareDocumentPosition(e) & v) !== 0;
145
145
  return r === "before" ? i : i && !n.contains(e);
146
146
  }
147
- function F(e) {
147
+ function I(e) {
148
148
  let { path: t } = e, n = t.findIndex((e) => e.isConnected);
149
149
  if (n === -1) return null;
150
150
  if (n === 0) {
@@ -157,7 +157,7 @@ function F(e) {
157
157
  }
158
158
  } : null;
159
159
  }
160
- if (t.slice(0, n).some((e) => e.matches(v))) return null;
160
+ if (t.slice(0, n).some((e) => e.matches(y))) return null;
161
161
  let r = t[n], i = e.next[n - 1];
162
162
  if (i && i.parentElement === r) return {
163
163
  root: r,
@@ -181,78 +181,91 @@ function F(e) {
181
181
  }
182
182
  };
183
183
  }
184
- function I(e, t) {
185
- let n = F(e);
184
+ function L(e, t) {
185
+ let n = I(e);
186
186
  if (!n) return [];
187
187
  let { root: i, point: a } = n, o = i.ownerDocument.body, s = [];
188
- for (let e = i; e && !(u(e) || (s.push(e), e === o || e.matches(v))); e = e.parentElement);
188
+ for (let e = i; e && !(d(e) || (s.push(e), e === o || e.matches(y))); e = e.parentElement);
189
189
  if (s.length === 0) return [];
190
- let c = r(s[s.length - 1]).filter((e) => !(t && t.contains(e)) && y(e)).sort((e, t) => (e.compareDocumentPosition(t) & _) === 0 ? 1 : -1), l = [];
190
+ let c = r(s[s.length - 1]).filter((e) => !(t && t.contains(e)) && b(e)).sort((e, t) => (e.compareDocumentPosition(t) & v) === 0 ? 1 : -1), l = [];
191
191
  for (let e of s) {
192
- let t = c.filter((t) => e.contains(t) && !l.includes(t)), n = t.find((e) => P(e, a)), r = t.filter((e) => !P(e, a)).pop();
192
+ let t = c.filter((t) => e.contains(t) && !l.includes(t)), n = t.find((e) => F(e, a)), r = t.filter((e) => !F(e, a)).pop();
193
193
  n && l.push(n), r && l.push(r);
194
194
  }
195
195
  return l;
196
196
  }
197
- function L(e, t) {
197
+ function R(e) {
198
+ if (!e) return !1;
199
+ let t = M();
200
+ return t ? t.position.path.includes(e) ? !0 : t.anchors.some((t) => t.position.path.includes(e)) : !1;
201
+ }
202
+ function z(e, t, n) {
203
+ return !t || e.closest("[data-wave-focus-trap-allow]") ? !1 : s().some((r) => {
204
+ if (r.id === n || !u(r.id, e)) return !1;
205
+ if (n !== void 0 && l(r.id, n)) return !0;
206
+ let i = r.getAnchor();
207
+ return !!i && t.contains(i);
208
+ });
209
+ }
210
+ function B(e, t) {
198
211
  if (typeof document > "u") return !1;
199
212
  let n = document.activeElement, r = !n || n === document.body || n === document.documentElement;
200
- return !r && e.container?.contains(n) ? !0 : !r && e.onlyIfFocusInside ? !1 : !t();
213
+ return !r && e.container?.contains(n) ? !0 : e.requireFocusInside ? r ? R(e.container) && !t() : z(n, e.container, e.layerId) : !r && e.onlyIfFocusInside ? !1 : !t();
201
214
  }
202
- function* R(e, t) {
203
- yield* I(e.position, t);
215
+ function* V(e, t) {
216
+ yield* L(e.position, t);
204
217
  for (let t of e.anchors) yield t.element;
205
- for (let n of e.anchors) yield* I(n.position, t);
218
+ for (let n of e.anchors) yield* L(n.position, t);
206
219
  }
207
- function* z(e, t) {
220
+ function* H(e, t) {
208
221
  let { options: n, parentLayerId: r } = e;
209
222
  yield n.finalFocusRef?.current, yield t?.element, yield n.triggerRef?.current, yield n.fallback?.();
210
- let i = t ? R(t, n.container) : null, a = r === null ? null : o(r), s = [];
223
+ let i = t ? V(t, n.container) : null, a = r === null ? null : o(r), s = [];
211
224
  if (a) {
212
- for (let e of i ?? []) l(a.id, e) ? yield e : s.push(e);
213
- yield* N(a), yield* s;
225
+ for (let e of i ?? []) u(a.id, e) ? yield e : s.push(e);
226
+ yield* P(a), yield* s;
214
227
  } else i && (yield* i);
215
- yield* N(c((e) => e.kind === "modal"));
228
+ yield* P(c((e) => e.kind === "modal"));
216
229
  }
217
- function B(e, n) {
230
+ function U(e, n) {
218
231
  let r = e.options.container;
219
- for (let i of z(e, n)) if (!(r && i && r.contains(i)) && y(i) && t(i, { preventScroll: !0 })) return;
232
+ for (let i of H(e, n)) if (!(r && i && r.contains(i)) && b(i) && t(i, { preventScroll: !0 })) return;
220
233
  }
221
- function V(e) {
222
- let t = p.useContext(f), n = g({
234
+ function W(e) {
235
+ let t = m.useContext(p), n = _({
223
236
  options: e,
224
237
  parentLayerId: t
225
- }), r = g(null), i = g(!1), a = g(!1), o = g(null), s = g(null), { enabled: c } = e;
226
- h(() => {
227
- let e = A(), t = {
238
+ }), r = _(null), i = _(!1), a = _(!1), o = _(null), s = _(null), { enabled: c } = e;
239
+ g(() => {
240
+ let e = j(), t = {
228
241
  isHoverClose: () => n.current.options.isHoverClose?.() === !0,
229
242
  getContainer: () => n.current.options.container ?? null,
230
243
  getOpener: () => r.current?.element ?? n.current.options.triggerRef?.current ?? null
231
244
  };
232
245
  s.current = t;
233
- let i = S();
246
+ let i = C();
234
247
  return i.add(t), () => {
235
248
  e(), queueMicrotask(() => i.delete(t));
236
249
  };
237
- }, []), m(() => {
250
+ }, []), h(() => {
238
251
  n.current = {
239
252
  options: e,
240
253
  parentLayerId: t
241
254
  };
242
255
  let a = i.current;
243
- i.current = e.enabled, e.enabled && !a && (r.current = M(e));
244
- }), h(() => {
256
+ i.current = e.enabled, e.enabled && !a && (r.current = N(e));
257
+ }), g(() => {
245
258
  let e = a.current;
246
- if (a.current = c, !e || c) return;
247
- let t = n.current, i = r.current, o = s.current, l = L(t.options, () => w(o, t.options));
248
- r.current = null, l && B(t, i);
249
- }, [c]), h(() => {
259
+ if (a.current = c, c && !e && !r.current && (r.current = N(n.current.options)), !e || c) return;
260
+ let t = n.current, i = r.current, o = s.current, l = B(t.options, () => T(o, t.options));
261
+ r.current = null, l && U(t, i);
262
+ }, [c]), g(() => {
250
263
  let e = n, t = r, i = o, a = s;
251
264
  return i.current = null, () => {
252
265
  let n = e.current;
253
266
  if (!n.options.enabled) return;
254
267
  let r = a.current;
255
- if (!L(n.options, () => w(r, n.options))) return;
268
+ if (!B(n.options, () => T(r, n.options))) return;
256
269
  let o = {};
257
270
  i.current = o;
258
271
  let s = t.current;
@@ -260,12 +273,12 @@ function V(e) {
260
273
  if (i.current !== o) return;
261
274
  i.current = null;
262
275
  let e = typeof document > "u" ? null : document.activeElement, t = n.options.container;
263
- (!e || e === document.body || e === document.documentElement || t && t.contains(e)) && B(n, s);
276
+ (!e || e === document.body || e === document.documentElement || t && t.contains(e)) && U(n, s);
264
277
  });
265
278
  };
266
279
  }, []);
267
280
  }
268
281
  //#endregion
269
- export { V as useRestoreFocus };
282
+ export { W as useRestoreFocus };
270
283
 
271
284
  //# sourceMappingURL=useRestoreFocus.mjs.map