@trackunit/react-modal 2.1.4 → 2.1.6-alpha-ecf53e535f3.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.
package/index.cjs.js CHANGED
@@ -812,6 +812,33 @@ const useModalStack = (isOpen) => {
812
812
  }), [depthFromFront, totalStackSize, stackSizeAtOpen]);
813
813
  };
814
814
 
815
+ /**
816
+ * The close safety timeout is a plain `setTimeout`, so it still fires in
817
+ * environments where the CSS `transitionend` it guards never does — headless
818
+ * Chrome report/screenshot renderers, backgrounded tabs, and anything with
819
+ * motion disabled. In those contexts the timeout firing is expected, not a
820
+ * defect, so reporting it to Sentry is pure noise (it produced 75k+ events
821
+ * with zero users impacted).
822
+ *
823
+ * Only capture when we're confident a real, painting browser was driving the
824
+ * close: the document is visible, the user hasn't asked to reduce motion, and
825
+ * an animation frame can actually run. `closeModal()` still runs regardless, so
826
+ * the modal always closes correctly.
827
+ */
828
+ const getCloseTimeoutReportFrameScheduler = () => {
829
+ if (typeof document !== "undefined" && document.visibilityState !== "visible") {
830
+ return undefined;
831
+ }
832
+ if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
833
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
834
+ return undefined;
835
+ }
836
+ }
837
+ if (typeof window === "undefined" || typeof window.requestAnimationFrame !== "function") {
838
+ return undefined;
839
+ }
840
+ return callback => window.requestAnimationFrame(callback);
841
+ };
815
842
  /**
816
843
  * A hook to handle the state and configuration of Modal components.
817
844
  *
@@ -863,7 +890,14 @@ const useModal = (props) => {
863
890
  if (pendingCloseModalRef.current) {
864
891
  pendingCloseModalRef.current = false;
865
892
  void closeModal();
866
- errorHandling?.captureException(new Error("Modal close animation safety timeout: transitionend callback never fired"), { level: "warning" });
893
+ const scheduleCloseTimeoutReport = getCloseTimeoutReportFrameScheduler();
894
+ if (scheduleCloseTimeoutReport) {
895
+ scheduleCloseTimeoutReport(() => {
896
+ if (getCloseTimeoutReportFrameScheduler()) {
897
+ errorHandling?.captureException(new Error("Modal close animation safety timeout: transitionend callback never fired"), { level: "warning" });
898
+ }
899
+ });
900
+ }
867
901
  }
868
902
  },
869
903
  duration: reactComponents.SHEET_TRANSITION_DURATION_MS + 100,
package/index.esm.js CHANGED
@@ -810,6 +810,33 @@ const useModalStack = (isOpen) => {
810
810
  }), [depthFromFront, totalStackSize, stackSizeAtOpen]);
811
811
  };
812
812
 
813
+ /**
814
+ * The close safety timeout is a plain `setTimeout`, so it still fires in
815
+ * environments where the CSS `transitionend` it guards never does — headless
816
+ * Chrome report/screenshot renderers, backgrounded tabs, and anything with
817
+ * motion disabled. In those contexts the timeout firing is expected, not a
818
+ * defect, so reporting it to Sentry is pure noise (it produced 75k+ events
819
+ * with zero users impacted).
820
+ *
821
+ * Only capture when we're confident a real, painting browser was driving the
822
+ * close: the document is visible, the user hasn't asked to reduce motion, and
823
+ * an animation frame can actually run. `closeModal()` still runs regardless, so
824
+ * the modal always closes correctly.
825
+ */
826
+ const getCloseTimeoutReportFrameScheduler = () => {
827
+ if (typeof document !== "undefined" && document.visibilityState !== "visible") {
828
+ return undefined;
829
+ }
830
+ if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
831
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
832
+ return undefined;
833
+ }
834
+ }
835
+ if (typeof window === "undefined" || typeof window.requestAnimationFrame !== "function") {
836
+ return undefined;
837
+ }
838
+ return callback => window.requestAnimationFrame(callback);
839
+ };
813
840
  /**
814
841
  * A hook to handle the state and configuration of Modal components.
815
842
  *
@@ -861,7 +888,14 @@ const useModal = (props) => {
861
888
  if (pendingCloseModalRef.current) {
862
889
  pendingCloseModalRef.current = false;
863
890
  void closeModal();
864
- errorHandling?.captureException(new Error("Modal close animation safety timeout: transitionend callback never fired"), { level: "warning" });
891
+ const scheduleCloseTimeoutReport = getCloseTimeoutReportFrameScheduler();
892
+ if (scheduleCloseTimeoutReport) {
893
+ scheduleCloseTimeoutReport(() => {
894
+ if (getCloseTimeoutReportFrameScheduler()) {
895
+ errorHandling?.captureException(new Error("Modal close animation safety timeout: transitionend callback never fired"), { level: "warning" });
896
+ }
897
+ });
898
+ }
865
899
  }
866
900
  },
867
901
  duration: SHEET_TRANSITION_DURATION_MS + 100,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-modal",
3
- "version": "2.1.4",
3
+ "version": "2.1.6-alpha-ecf53e535f3.0",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -8,12 +8,12 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@floating-ui/react": "^0.26.25",
11
- "@trackunit/react-components": "2.1.3",
12
- "@trackunit/css-class-variance-utilities": "1.13.13",
13
- "@trackunit/shared-utils": "1.15.13",
11
+ "@trackunit/react-components": "2.1.5-alpha-ecf53e535f3.0",
12
+ "@trackunit/css-class-variance-utilities": "1.13.15-alpha-ecf53e535f3.0",
13
+ "@trackunit/shared-utils": "1.15.15-alpha-ecf53e535f3.0",
14
14
  "@floating-ui/react-dom": "2.1.2",
15
- "@trackunit/react-core-contexts-api": "1.17.13",
16
- "@trackunit/i18n-library-translation": "2.0.5"
15
+ "@trackunit/react-core-contexts-api": "1.17.15-alpha-ecf53e535f3.0",
16
+ "@trackunit/i18n-library-translation": "2.0.7-alpha-ecf53e535f3.0"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "@tanstack/react-router": "^1.114.29",