@astryxdesign/core 0.7.6-canary.df8928a → 0.7.6-canary.eaae8e3

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 (143) hide show
  1. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  2. package/dist/ClickableCard/ClickableCard.js +37 -4
  3. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  4. package/dist/DropdownMenu/DropdownMenu.js +3 -2
  5. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +17 -8
  6. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  7. package/dist/DropdownMenu/lazyMenuBottomSheet.js +23 -9
  8. package/dist/Layer/popoverOperations.d.ts +27 -0
  9. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  10. package/dist/Layer/popoverOperations.js +159 -0
  11. package/dist/Layer/useLayer.d.ts +1 -1
  12. package/dist/Layer/useLayer.d.ts.map +1 -1
  13. package/dist/Layer/useLayer.js +93 -59
  14. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
  15. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  16. package/dist/MultiSelector/MultiSelector.js +21 -8
  17. package/dist/Slider/Slider.d.ts.map +1 -1
  18. package/dist/Slider/Slider.js +3 -1
  19. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  20. package/dist/TopNav/TopNavMegaMenu.js +3 -0
  21. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  22. package/dist/TopNav/TopNavMenu.js +1 -0
  23. package/dist/gestures/GestureArena.d.ts +6 -0
  24. package/dist/gestures/GestureArena.d.ts.map +1 -1
  25. package/dist/gestures/GestureArena.js +39 -0
  26. package/dist/gestures/GestureHost.d.ts +352 -0
  27. package/dist/gestures/GestureHost.d.ts.map +1 -0
  28. package/dist/gestures/GestureHost.js +1773 -0
  29. package/dist/gestures/GestureRecognizer.d.ts +10 -0
  30. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  31. package/dist/gestures/GestureRecognizer.js +16 -0
  32. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  33. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  34. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  35. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  36. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  37. package/dist/gestures/PanGestureRecognizer.js +3 -0
  38. package/dist/gestures/PinchGestureRecognizer.d.ts +1 -0
  39. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -1
  40. package/dist/gestures/PinchGestureRecognizer.js +3 -0
  41. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +1 -0
  42. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -1
  43. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +3 -0
  44. package/dist/gestures/SwipeGestureRecognizer.d.ts +1 -0
  45. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -1
  46. package/dist/gestures/SwipeGestureRecognizer.js +3 -0
  47. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  48. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  49. package/dist/gestures/TapGestureRecognizer.js +3 -0
  50. package/dist/gestures/haptics.d.ts +65 -0
  51. package/dist/gestures/haptics.d.ts.map +1 -0
  52. package/dist/gestures/haptics.js +182 -0
  53. package/dist/gestures/nativeScroll.d.ts +42 -0
  54. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  55. package/dist/gestures/nativeScroll.js +228 -0
  56. package/dist/gestures/touchAction.d.ts +60 -0
  57. package/dist/gestures/touchAction.d.ts.map +1 -0
  58. package/dist/gestures/touchAction.js +157 -0
  59. package/dist/gestures/touchActionRule.d.ts +34 -0
  60. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  61. package/dist/gestures/touchActionRule.js +140 -0
  62. package/dist/gestures/types.d.ts +7 -0
  63. package/dist/gestures/types.d.ts.map +1 -1
  64. package/dist/hooks/index.d.ts +1 -1
  65. package/dist/hooks/index.d.ts.map +1 -1
  66. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  67. package/dist/hooks/modalAnnounce.js +107 -61
  68. package/dist/hooks/useAnnounce.d.ts +101 -42
  69. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  70. package/dist/hooks/useAnnounce.js +161 -75
  71. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  72. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  73. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  74. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  75. package/dist/hooks/useBusyAnnouncement.js +6 -12
  76. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  77. package/dist/i18n/generated-locales/en.generated.js +2 -0
  78. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  79. package/dist/i18n/generated-locales/pseudo.generated.js +2 -0
  80. package/dist/utils/primaryClick.d.ts +11 -0
  81. package/dist/utils/primaryClick.d.ts.map +1 -0
  82. package/dist/utils/primaryClick.js +25 -0
  83. package/locales/en.json +8 -0
  84. package/locales/pseudo.json +6 -0
  85. package/package.json +4 -4
  86. package/src/ClickableCard/ClickableCard.test.tsx +96 -0
  87. package/src/ClickableCard/ClickableCard.tsx +48 -4
  88. package/src/DropdownMenu/DropdownMenu.tsx +3 -2
  89. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +16 -9
  90. package/src/DropdownMenu/lazyMenuBottomSheet.ts +21 -9
  91. package/src/Kbd/Kbd.spec.md +81 -38
  92. package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
  93. package/src/Layer/popoverOperations.test.ts +205 -0
  94. package/src/Layer/popoverOperations.ts +172 -0
  95. package/src/Layer/useLayer.test.tsx +348 -1
  96. package/src/Layer/useLayer.tsx +118 -71
  97. package/src/MetadataList/MetadataList.spec.md +187 -0
  98. package/src/MetadataList/MetadataListItem.spec.md +165 -0
  99. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
  100. package/src/MultiSelector/MultiSelector.test.tsx +152 -0
  101. package/src/MultiSelector/MultiSelector.tsx +19 -8
  102. package/src/Slider/Slider.test.tsx +19 -0
  103. package/src/Slider/Slider.tsx +4 -2
  104. package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
  105. package/src/TopNav/TopNavMegaMenu.tsx +4 -1
  106. package/src/TopNav/TopNavMenu.test.tsx +17 -0
  107. package/src/TopNav/TopNavMenu.tsx +1 -0
  108. package/src/gestures/GestureArena.ts +35 -0
  109. package/src/gestures/GestureHost.ts +2065 -0
  110. package/src/gestures/GestureRecognizer.ts +18 -0
  111. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  112. package/src/gestures/PanGestureRecognizer.ts +4 -0
  113. package/src/gestures/PinchGestureRecognizer.ts +4 -0
  114. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +4 -0
  115. package/src/gestures/SwipeGestureRecognizer.ts +4 -0
  116. package/src/gestures/TapGestureRecognizer.ts +4 -0
  117. package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
  118. package/src/gestures/__tests__/arena.test.ts +5 -0
  119. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +5 -0
  120. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  121. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  122. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  123. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  124. package/src/gestures/__tests__/haptics.test.ts +187 -0
  125. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  126. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  127. package/src/gestures/haptics.ts +203 -0
  128. package/src/gestures/nativeScroll.ts +277 -0
  129. package/src/gestures/touchAction.ts +191 -0
  130. package/src/gestures/touchActionRule.ts +157 -0
  131. package/src/gestures/types.ts +7 -0
  132. package/src/hooks/index.ts +5 -1
  133. package/src/hooks/modalAnnounce.ts +129 -72
  134. package/src/hooks/useAnnounce.doc.mjs +35 -3
  135. package/src/hooks/useAnnounce.replace.test.tsx +516 -0
  136. package/src/hooks/useAnnounce.ts +209 -102
  137. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
  138. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  139. package/src/hooks/useBusyAnnouncement.ts +7 -10
  140. package/src/i18n/generated-locales/en.generated.ts +2 -0
  141. package/src/i18n/generated-locales/pseudo.generated.ts +2 -0
  142. package/src/utils/primaryClick.test.ts +38 -0
  143. package/src/utils/primaryClick.ts +28 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ClickableCard.d.ts","sourceRoot":"","sources":["../../src/ClickableCard/ClickableCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAE,KAAK,UAAU,EAAU,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AASxE,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAGtE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAwJ5C,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,yCAAyC;IACzC,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAE1B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,yBAAyB;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,QAAQ,EACR,OAAO,EACP,OAAmB,EACnB,SAAkB,EAClB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,aAAa,EACxB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAyFpB;yBA5Ge,aAAa"}
1
+ {"version":3,"file":"ClickableCard.d.ts","sourceRoot":"","sources":["../../src/ClickableCard/ClickableCard.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EAGf,KAAK,GAAG,EACT,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAGtE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAwJ5C,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,yCAAyC;IACzC,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAE1B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,yBAAyB;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,0BAA0B;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,QAAQ,EACR,OAAO,EACP,OAAmB,EACnB,SAAkB,EAClB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,aAAa,EACxB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,kBAAkB,+BA+HpB;yBAlJe,aAAa"}
@@ -28,7 +28,7 @@
28
28
  * For static display, use Card.
29
29
  * For toggle selection, use SelectableCard.
30
30
  */
31
- import { useRef } from 'react';
31
+ import { useCallback, useRef } from 'react';
32
32
  import * as stylex from '@stylexjs/stylex';
33
33
  import "../theme/tokens.stylex.js";
34
34
  import { borderVars, colorVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
@@ -166,6 +166,36 @@ export function ClickableCard({
166
166
  const pressable = usePressFeedback();
167
167
  const containerRef = useRef(null);
168
168
  const interactiveRef = useRef(null);
169
+ const restoreFocusRef = useRef(false);
170
+ // The isDisabled value of the link that just detached: a link card that
171
+ // flips it replaces its hidden link (router component and plain anchor),
172
+ // and only that replacement takes focus back.
173
+ const detachedDisabledRef = useRef(null);
174
+
175
+ // A focused link remounts when isDisabled changes: the replacement takes
176
+ // focus back, without scrolling, if focus fell to the page. Any other
177
+ // detach and attach (a hidden Activity or Suspense boundary revealed
178
+ // again) leaves focus where the person put it.
179
+ const setInteractiveRef = useCallback(node => {
180
+ if (node == null) {
181
+ const previous = interactiveRef.current;
182
+ restoreFocusRef.current = previous != null && previous === previous.ownerDocument.activeElement;
183
+ detachedDisabledRef.current = isDisabled;
184
+ interactiveRef.current = null;
185
+ return;
186
+ }
187
+ interactiveRef.current = node;
188
+ const isFlip = detachedDisabledRef.current != null && detachedDisabledRef.current !== isDisabled;
189
+ const active = node.ownerDocument.activeElement;
190
+ const hasFallen = active == null || active === node.ownerDocument.body;
191
+ if (restoreFocusRef.current && isFlip && hasFallen) {
192
+ node.focus({
193
+ preventScroll: true
194
+ });
195
+ }
196
+ restoreFocusRef.current = false;
197
+ detachedDisabledRef.current = null;
198
+ }, [isDisabled]);
169
199
  const LinkComponent = useLinkComponent();
170
200
  const {
171
201
  onClick,
@@ -184,6 +214,9 @@ export function ClickableCard({
184
214
  } : onMouseUp;
185
215
  const isLink = href != null;
186
216
 
217
+ // Disabled links have no href, so bypass the router and render an anchor.
218
+ const LinkRoot = isDisabled ? 'a' : LinkComponent;
219
+
187
220
  // Only the `default` variant has a visible border. Card draws a transparent
188
221
  // 1px border on every other variant purely to avoid layout jitter; we drop
189
222
  // it here so the hover overlay covers the full box with no untinted ring.
@@ -207,8 +240,8 @@ export function ClickableCard({
207
240
  onClick: !isDisabled ? onClick : undefined,
208
241
  onMouseUp: !isDisabled ? handleMouseUp : undefined,
209
242
  ...props,
210
- children: [isLink ? /*#__PURE__*/_jsx(LinkComponent, {
211
- ref: interactiveRef,
243
+ children: [isLink ? /*#__PURE__*/_jsx(LinkRoot, {
244
+ ref: setInteractiveRef,
212
245
  href: isDisabled ? undefined : href,
213
246
  target: isDisabled ? undefined : target,
214
247
  role: isDisabled ? 'link' : undefined,
@@ -222,7 +255,7 @@ export function ClickableCard({
222
255
  className: "x10l6tqk x1i1rx1s xjm9jq1 x1717udv xkdpibf xb3r6kr xzpqnlu xuxw1ft xc342km"
223
256
  }
224
257
  }) : /*#__PURE__*/_jsx("button", {
225
- ref: interactiveRef,
258
+ ref: setInteractiveRef,
226
259
  type: "button",
227
260
  "aria-label": label,
228
261
  "aria-disabled": isDisabled || undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
@@ -387,9 +387,10 @@ function DropdownMenuBottomSheet({
387
387
  }
388
388
  }
389
389
  // The closed sheet renders nothing, so load its rows at rest: the first
390
- // open shows the actions at once.
390
+ // open shows the actions at once. The preload's result says whether they
391
+ // loaded; after a failure the first open loads them.
391
392
  useEffect(() => {
392
- preloadMenuBottomSheetActionList();
393
+ void preloadMenuBottomSheetActionList();
393
394
  }, []);
394
395
  const currentSubmenu = submenuPath.at(-1);
395
396
  const currentItems = currentSubmenu?.items ?? items;
@@ -11,10 +11,10 @@
11
11
  * of pages whose dropdowns only open as anchored popovers. Each wrapper keeps
12
12
  * the wrapped component's props and renders nothing until its module loads.
13
13
  *
14
- * The action list preloads at rest; a failed load is not kept, so the next
15
- * preload or open asks the module loader again (a loader that retries then
16
- * loads it; a browser does not fetch a native module again once its import
17
- * failed).
14
+ * The action list preloads at rest, and the preload's result says whether it
15
+ * loaded. A failed load is not kept, so the next preload or open asks the
16
+ * module loader again (a loader that retries then loads it; a browser does not
17
+ * fetch a native module again once its import failed).
18
18
  *
19
19
  * Neither wrapper renders on the server or in the render that hydrates server
20
20
  * HTML (spec:AST-013 FR9): a lazy component that has not loaded yet would
@@ -24,12 +24,21 @@
24
24
  import { type ComponentProps, type ReactElement } from 'react';
25
25
  import type { MenuBottomSheet as EagerMenuBottomSheet } from './MenuBottomSheet.js';
26
26
  import type { MenuBottomSheetActionList as EagerMenuBottomSheetActionList } from './MenuBottomSheetActionList.js';
27
+ /** What a preload of the action list came to: loaded, or failed with the loader's error. */
28
+ export type ActionListPreload = {
29
+ readonly isLoaded: true;
30
+ } | {
31
+ readonly isLoaded: false;
32
+ readonly error: unknown;
33
+ };
27
34
  /**
28
- * Starts loading the action list; a sheet menu calls it at rest. A preload
29
- * that fails is dropped, never an unhandled rejection: the first open asks the
30
- * module loader again.
35
+ * Starts loading the action list; a sheet menu calls it at rest. Its result
36
+ * says whether the list loaded: a failure (a dropped connection) is that
37
+ * result, with the loader's error, and never a rejection. The failed load is
38
+ * not kept, so the first open asks the module loader again, and a load that
39
+ * fails there reaches the menu through lazy().
31
40
  */
32
- export declare function preloadMenuBottomSheetActionList(): void;
41
+ export declare function preloadMenuBottomSheetActionList(): Promise<ActionListPreload>;
33
42
  export declare function MenuBottomSheet(props: ComponentProps<typeof EagerMenuBottomSheet>): ReactElement | null;
34
43
  export declare function MenuBottomSheetActionList(props: ComponentProps<typeof EagerMenuBottomSheetActionList>): ReactElement | null;
35
44
  //# sourceMappingURL=lazyMenuBottomSheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazyMenuBottomSheet.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/lazyMenuBottomSheet.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,eAAe,IAAI,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAC,yBAAyB,IAAI,8BAA8B,EAAC,MAAM,6BAA6B,CAAC;AA+B7G;;;;GAIG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAQD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,GACjD,YAAY,GAAG,IAAI,CASrB;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,cAAc,CAAC,OAAO,8BAA8B,CAAC,GAC3D,YAAY,GAAG,IAAI,CAcrB"}
1
+ {"version":3,"file":"lazyMenuBottomSheet.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/lazyMenuBottomSheet.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,eAAe,IAAI,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAC,yBAAyB,IAAI,8BAA8B,EAAC,MAAM,6BAA6B,CAAC;AA+B7G,4FAA4F;AAC5F,MAAM,MAAM,iBAAiB,GACzB;IAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;CAAC,GACzB;IAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAAC;AAExD;;;;;;GAMG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAOnF;AAQD,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,OAAO,oBAAoB,CAAC,GACjD,YAAY,GAAG,IAAI,CASrB;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,cAAc,CAAC,OAAO,8BAA8B,CAAC,GAC3D,YAAY,GAAG,IAAI,CAcrB"}
@@ -15,10 +15,10 @@
15
15
  * of pages whose dropdowns only open as anchored popovers. Each wrapper keeps
16
16
  * the wrapped component's props and renders nothing until its module loads.
17
17
  *
18
- * The action list preloads at rest; a failed load is not kept, so the next
19
- * preload or open asks the module loader again (a loader that retries then
20
- * loads it; a browser does not fetch a native module again once its import
21
- * failed).
18
+ * The action list preloads at rest, and the preload's result says whether it
19
+ * loaded. A failed load is not kept, so the next preload or open asks the
20
+ * module loader again (a loader that retries then loads it; a browser does not
21
+ * fetch a native module again once its import failed).
22
22
  *
23
23
  * Neither wrapper renders on the server or in the render that hydrates server
24
24
  * HTML (spec:AST-013 FR9): a lazy component that has not loaded yet would
@@ -50,13 +50,27 @@ async function loadActionList() {
50
50
  return actionListLoad;
51
51
  }
52
52
 
53
+ /** What a preload of the action list came to: loaded, or failed with the loader's error. */
54
+
53
55
  /**
54
- * Starts loading the action list; a sheet menu calls it at rest. A preload
55
- * that fails is dropped, never an unhandled rejection: the first open asks the
56
- * module loader again.
56
+ * Starts loading the action list; a sheet menu calls it at rest. Its result
57
+ * says whether the list loaded: a failure (a dropped connection) is that
58
+ * result, with the loader's error, and never a rejection. The failed load is
59
+ * not kept, so the first open asks the module loader again, and a load that
60
+ * fails there reaches the menu through lazy().
57
61
  */
58
- export function preloadMenuBottomSheetActionList() {
59
- loadActionList().catch(() => {});
62
+ export async function preloadMenuBottomSheetActionList() {
63
+ try {
64
+ await loadActionList();
65
+ return {
66
+ isLoaded: true
67
+ };
68
+ } catch (error) {
69
+ return {
70
+ isLoaded: false,
71
+ error
72
+ };
73
+ }
60
74
  }
61
75
  const LazyMenuBottomSheetActionList = /*#__PURE__*/lazy(async () => loadActionList().then(module => ({
62
76
  default: module.MenuBottomSheetActionList
@@ -0,0 +1,27 @@
1
+ /** Runs `operation`, counting it as one of the layers' own popover operations in `doc`. */
2
+ export declare function runPopoverOperation(doc: Document, operation: () => void): void;
3
+ /** Whether one of the layers' own shows or hides is running in `doc`: a show asked now would be refused. */
4
+ export declare function isPopoverOperationInFlight(doc: Document): boolean;
5
+ /**
6
+ * Whether a hide the browser runs itself is counted in `doc`. The count
7
+ * outlasts the engine's own window (it ends at the element's `toggle`, a task
8
+ * later), so a show asked inside it may well succeed; one the browser refuses
9
+ * is deferred to the count's end.
10
+ */
11
+ export declare function isBrowserHideInFlight(doc: Document): boolean;
12
+ /**
13
+ * Counts a hide the browser runs itself. Called as the element's `beforetoggle`
14
+ * fires, which the hide dispatches synchronously as it starts; the count ends
15
+ * at the element's `toggle`, which the browser queues for the task after the
16
+ * hide, and in any case at the next task: the hide is synchronous, so the task
17
+ * after it is past the window even when the element has left the document and
18
+ * its `toggle` never arrives. Calling it again for the same hide is a no-op.
19
+ */
20
+ export declare function observeBrowserHide(popover: HTMLElement): void;
21
+ /**
22
+ * Runs `callback` once no popover operation of either kind is in flight in
23
+ * `doc`: at once when none is, otherwise in its own microtask after the last
24
+ * one has ended and the script that started it has unwound.
25
+ */
26
+ export declare function afterPopoverOperations(doc: Document, callback: () => void): void;
27
+ //# sourceMappingURL=popoverOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popoverOperations.d.ts","sourceRoot":"","sources":["../../src/Layer/popoverOperations.ts"],"names":[],"mappings":"AAoFA,2FAA2F;AAC3F,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,MAAM,IAAI,GACpB,IAAI,CAQN;AAED,4GAA4G;AAC5G,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAEjE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAE5D;AAKD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CA0B7D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,MAAM,IAAI,GACnB,IAAI,CAWN"}
@@ -0,0 +1,159 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file popoverOperations.ts
5
+ * @input Popover API events (`beforetoggle`, `toggle`) and the layers' own show/hide calls
6
+ * @output The per-document ledger of popover operations in flight, and the deferral of a show that arrives inside one
7
+ * @position Internal to the layer runtime; used by useLayer
8
+ *
9
+ * SYNC: When modified, update:
10
+ * - /packages/core/src/Layer/useLayer.tsx
11
+ * - /packages/core/src/Layer/popoverOperations.test.ts
12
+ */
13
+
14
+ /**
15
+ * Popover operations in flight, per document.
16
+ *
17
+ * The Popover API refuses to show a popover while the document is in the
18
+ * middle of showing or hiding ANY popover: `showPopover()` throws an
19
+ * `InvalidStateError` ("Invalid to show a popover during another show
20
+ * operation"; Chromium 150+, where 149 still accepts such a show).
21
+ * Hiding a popover restores focus to the element that had it —
22
+ * synchronously, inside that window — so a focus-driven layer on the element
23
+ * receiving focus (a tooltip on the trigger that just closed a popover) asks
24
+ * to show while the hide is still running.
25
+ *
26
+ * Two kinds of operation are counted:
27
+ *
28
+ * - The layers' own shows and hides pass through `runPopoverOperation`, so
29
+ * their windows are known exactly: a `show()` that arrives inside one is
30
+ * deferred ahead of asking the browser.
31
+ * - A hide the browser runs on its own — an Escape its close watcher answers,
32
+ * a light dismiss, an `auto` popover evicted by another one opening — never
33
+ * passes through here. It is observable from its element's events:
34
+ * `beforetoggle` fires synchronously as the hide starts, and `toggle` in a
35
+ * task once it has ended; `observeBrowserHide` counts it between the two.
36
+ * That window is wider than the engine's, which ends when the hide returns,
37
+ * so a show inside it is asked of the browser first and deferred only when
38
+ * the browser refuses it: a light dismiss at `pointerup` followed by a show
39
+ * at `click` in the same gesture still opens at once.
40
+ *
41
+ * A deferred show waits in `afterPopoverOperations` and replays, one
42
+ * microtask each, once the document's last operation of either kind has
43
+ * ended and the script that started it has unwound.
44
+ */
45
+ const ownOperationsByDocument = new WeakMap();
46
+ const browserHidesByDocument = new WeakMap();
47
+ const settledCallbacksByDocument = new WeakMap();
48
+ function count(map, doc, delta) {
49
+ map.set(doc, Math.max(0, (map.get(doc) ?? 0) + delta));
50
+ }
51
+ function anyInFlight(doc) {
52
+ return (ownOperationsByDocument.get(doc) ?? 0) > 0 || (browserHidesByDocument.get(doc) ?? 0) > 0;
53
+ }
54
+ function ended(doc) {
55
+ if (!anyInFlight(doc) && settledCallbacksByDocument.has(doc)) {
56
+ // The operation's own script is still on the stack (the `finally` of a
57
+ // `runPopoverOperation`, a `toggle` listener): replay once it has unwound.
58
+ queueMicrotask(() => replaySettled(doc));
59
+ }
60
+ }
61
+ function replaySettled(doc) {
62
+ if (anyInFlight(doc)) {
63
+ // Another operation started before the replay ran; its end replays.
64
+ return;
65
+ }
66
+ const callbacks = settledCallbacksByDocument.get(doc);
67
+ if (callbacks == null) {
68
+ return;
69
+ }
70
+ settledCallbacksByDocument.delete(doc);
71
+ // One microtask each: a replay that throws reaches the page on its own and
72
+ // leaves the ones after it to run.
73
+ for (const callback of callbacks) {
74
+ queueMicrotask(callback);
75
+ }
76
+ }
77
+
78
+ /** Runs `operation`, counting it as one of the layers' own popover operations in `doc`. */
79
+ export function runPopoverOperation(doc, operation) {
80
+ count(ownOperationsByDocument, doc, 1);
81
+ try {
82
+ operation();
83
+ } finally {
84
+ count(ownOperationsByDocument, doc, -1);
85
+ ended(doc);
86
+ }
87
+ }
88
+
89
+ /** Whether one of the layers' own shows or hides is running in `doc`: a show asked now would be refused. */
90
+ export function isPopoverOperationInFlight(doc) {
91
+ return (ownOperationsByDocument.get(doc) ?? 0) > 0;
92
+ }
93
+
94
+ /**
95
+ * Whether a hide the browser runs itself is counted in `doc`. The count
96
+ * outlasts the engine's own window (it ends at the element's `toggle`, a task
97
+ * later), so a show asked inside it may well succeed; one the browser refuses
98
+ * is deferred to the count's end.
99
+ */
100
+ export function isBrowserHideInFlight(doc) {
101
+ return (browserHidesByDocument.get(doc) ?? 0) > 0;
102
+ }
103
+
104
+ /** Popovers whose browser-run hide is being counted, so one hide is counted once. */
105
+ const browserHidesInFlight = new WeakSet();
106
+
107
+ /**
108
+ * Counts a hide the browser runs itself. Called as the element's `beforetoggle`
109
+ * fires, which the hide dispatches synchronously as it starts; the count ends
110
+ * at the element's `toggle`, which the browser queues for the task after the
111
+ * hide, and in any case at the next task: the hide is synchronous, so the task
112
+ * after it is past the window even when the element has left the document and
113
+ * its `toggle` never arrives. Calling it again for the same hide is a no-op.
114
+ */
115
+ export function observeBrowserHide(popover) {
116
+ if (browserHidesInFlight.has(popover)) {
117
+ return;
118
+ }
119
+ browserHidesInFlight.add(popover);
120
+ const doc = popover.ownerDocument;
121
+ count(browserHidesByDocument, doc, 1);
122
+ const view = doc.defaultView ?? globalThis;
123
+ let timer = null;
124
+ let done = false;
125
+ const finish = () => {
126
+ if (done) {
127
+ return;
128
+ }
129
+ done = true;
130
+ popover.removeEventListener('toggle', finish);
131
+ if (timer != null) {
132
+ view.clearTimeout(timer);
133
+ timer = null;
134
+ }
135
+ browserHidesInFlight.delete(popover);
136
+ count(browserHidesByDocument, doc, -1);
137
+ ended(doc);
138
+ };
139
+ popover.addEventListener('toggle', finish);
140
+ timer = view.setTimeout(finish, 0);
141
+ }
142
+
143
+ /**
144
+ * Runs `callback` once no popover operation of either kind is in flight in
145
+ * `doc`: at once when none is, otherwise in its own microtask after the last
146
+ * one has ended and the script that started it has unwound.
147
+ */
148
+ export function afterPopoverOperations(doc, callback) {
149
+ if (!anyInFlight(doc)) {
150
+ callback();
151
+ return;
152
+ }
153
+ const callbacks = settledCallbacksByDocument.get(doc);
154
+ if (callbacks == null) {
155
+ settledCallbacksByDocument.set(doc, [callback]);
156
+ } else {
157
+ callbacks.push(callback);
158
+ }
159
+ }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file useLayer.tsx
3
- * @input Uses React hooks, Popover API, CSS anchor positioning, shared text/provider boundaries
3
+ * @input Uses React hooks, Popover API (its `beforetoggle`/`toggle` events through the popoverOperations ledger), CSS anchor positioning, shared text/provider boundaries
4
4
  * @output Exports the public useLayer hook plus internal trigger helpers.
5
5
  * @position Core layer utility; used by useHoverCard, useTooltip, etc.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useLayer.d.ts","sourceRoot":"","sources":["../../src/Layer/useLayer.tsx"],"names":[],"mappings":"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"}