From 487c3667f684fadf8535eed367a1196e766dd947 Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Fri, 3 Oct 2025 19:30:21 +0200 Subject: [PATCH 1/2] Release Fragment refs to Canary --- packages/shared/ReactFeatureFlags.js | 4 ++-- packages/shared/forks/ReactFeatureFlags.native-oss.js | 2 +- packages/shared/forks/ReactFeatureFlags.test-renderer.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 89095e7318321..351187dc585b0 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -145,8 +145,8 @@ export const transitionLaneExpirationMs = 5000; */ export const enableInfiniteRenderLoopDetection: boolean = false; -export const enableFragmentRefs = __EXPERIMENTAL__; -export const enableFragmentRefsScrollIntoView = __EXPERIMENTAL__; +export const enableFragmentRefs: boolean = true; +export const enableFragmentRefsScrollIntoView: boolean = true; // ----------------------------------------------------------------------------- // Ready for next major. diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 8335ca5857b2d..bd73922b2ce41 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -72,7 +72,7 @@ export const enableHydrationChangeEvent: boolean = false; export const enableDefaultTransitionIndicator: boolean = false; export const ownerStackLimit = 1e4; -export const enableFragmentRefs: boolean = false; +export const enableFragmentRefs: boolean = true; export const enableFragmentRefsScrollIntoView: boolean = false; // Profiling Only diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 865fa139afaf8..9d2e73024d1b6 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -73,8 +73,8 @@ export const enableHydrationChangeEvent: boolean = false; export const enableDefaultTransitionIndicator: boolean = false; export const ownerStackLimit = 1e4; -export const enableFragmentRefs: boolean = false; -export const enableFragmentRefsScrollIntoView: boolean = false; +export const enableFragmentRefs: boolean = true; +export const enableFragmentRefsScrollIntoView: boolean = true; // TODO: This must be in sync with the main ReactFeatureFlags file because // the Test Renderer's value must be the same as the one used by the From ab0cf48d7b5183e19349ffbb1e43789c054734d5 Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Fri, 3 Oct 2025 19:52:46 +0200 Subject: [PATCH 2/2] experimental_scrollIntoView -> scrollIntoView --- .../fragment-refs/ScrollIntoViewCase.js | 4 ++-- .../src/client/ReactFiberConfigDOM.js | 4 ++-- .../__tests__/ReactDOMFragmentRefs-test.js | 24 +++++++++---------- scripts/error-codes/codes.json | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/fixtures/dom/src/components/fixtures/fragment-refs/ScrollIntoViewCase.js b/fixtures/dom/src/components/fixtures/fragment-refs/ScrollIntoViewCase.js index 3b1f21ef686aa..e08b9ec50fe97 100644 --- a/fixtures/dom/src/components/fixtures/fragment-refs/ScrollIntoViewCase.js +++ b/fixtures/dom/src/components/fixtures/fragment-refs/ScrollIntoViewCase.js @@ -55,11 +55,11 @@ export default function ScrollIntoViewCase() { const scrollContainerRef = useRef(null); const scrollVertical = () => { - fragmentRef.current.experimental_scrollIntoView(alignToTop); + fragmentRef.current.scrollIntoView(alignToTop); }; const scrollVerticalNoChildren = () => { - noChildRef.current.experimental_scrollIntoView(alignToTop); + noChildRef.current.scrollIntoView(alignToTop); }; useEffect(() => { diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index 0f75d5f8cd78e..0af810924bbd7 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -3341,13 +3341,13 @@ function validateDocumentPositionWithFiberTree( if (enableFragmentRefsScrollIntoView) { // $FlowFixMe[prop-missing] - FragmentInstance.prototype.experimental_scrollIntoView = function ( + FragmentInstance.prototype.scrollIntoView = function ( this: FragmentInstanceType, alignToTop?: boolean, ): void { if (typeof alignToTop === 'object') { throw new Error( - 'FragmentInstance.experimental_scrollIntoView() does not support ' + + 'FragmentInstance.scrollIntoView() does not support ' + 'scrollIntoViewOptions. Use the alignToTop boolean instead.', ); } diff --git a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js index 26de45076f359..90dfa9d2f307c 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js @@ -1960,9 +1960,9 @@ describe('FragmentRefs', () => { }); expect(() => { - fragmentRef.current.experimental_scrollIntoView({block: 'start'}); + fragmentRef.current.scrollIntoView({block: 'start'}); }).toThrowError( - 'FragmentInstance.experimental_scrollIntoView() does not support ' + + 'FragmentInstance.scrollIntoView() does not support ' + 'scrollIntoViewOptions. Use the alignToTop boolean instead.', ); }); @@ -1996,11 +1996,11 @@ describe('FragmentRefs', () => { }); // Default call - fragmentRef.current.experimental_scrollIntoView(); + fragmentRef.current.scrollIntoView(); expectLast(logs, 'childA'); logs = []; // alignToTop=true - fragmentRef.current.experimental_scrollIntoView(true); + fragmentRef.current.scrollIntoView(true); expectLast(logs, 'childA'); }); @@ -2027,7 +2027,7 @@ describe('FragmentRefs', () => { logs.push('childB'); }); - fragmentRef.current.experimental_scrollIntoView(false); + fragmentRef.current.scrollIntoView(false); expectLast(logs, 'childB'); }); @@ -2068,7 +2068,7 @@ describe('FragmentRefs', () => { }); // Default call - fragmentRef.current.experimental_scrollIntoView(); + fragmentRef.current.scrollIntoView(); expectLast(logs, 'childA'); }); @@ -2157,7 +2157,7 @@ describe('FragmentRefs', () => { }); // Default call - fragmentRef.current.experimental_scrollIntoView(); + fragmentRef.current.scrollIntoView(); expectLast(logs, 'header'); childARef.current.scrollIntoView.mockClear(); @@ -2167,7 +2167,7 @@ describe('FragmentRefs', () => { logs = []; // // alignToTop=false - fragmentRef.current.experimental_scrollIntoView(false); + fragmentRef.current.scrollIntoView(false); expectLast(logs, 'C'); }); }); @@ -2195,14 +2195,14 @@ describe('FragmentRefs', () => { siblingBRef.current.scrollIntoView = jest.fn(); // Default call - fragmentRef.current.experimental_scrollIntoView(); + fragmentRef.current.scrollIntoView(); expect(siblingARef.current.scrollIntoView).toHaveBeenCalledTimes(0); expect(siblingBRef.current.scrollIntoView).toHaveBeenCalledTimes(1); siblingBRef.current.scrollIntoView.mockClear(); // alignToTop=true - fragmentRef.current.experimental_scrollIntoView(true); + fragmentRef.current.scrollIntoView(true); expect(siblingARef.current.scrollIntoView).toHaveBeenCalledTimes(0); expect(siblingBRef.current.scrollIntoView).toHaveBeenCalledTimes(1); }); @@ -2239,7 +2239,7 @@ describe('FragmentRefs', () => { siblingBRef.current.scrollIntoView = jest.fn(); // alignToTop=false - fragmentRef.current.experimental_scrollIntoView(false); + fragmentRef.current.scrollIntoView(false); expect(siblingARef.current.scrollIntoView).toHaveBeenCalledTimes(1); expect(siblingBRef.current.scrollIntoView).toHaveBeenCalledTimes(0); }); @@ -2260,7 +2260,7 @@ describe('FragmentRefs', () => { }); parentRef.current.scrollIntoView = jest.fn(); - fragmentRef.current.experimental_scrollIntoView(); + fragmentRef.current.scrollIntoView(); expect(parentRef.current.scrollIntoView).toHaveBeenCalledTimes(1); }); }); diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index c19b95db788d3..e87d750ecaf8b 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -551,5 +551,5 @@ "563": "This render completed successfully. All cacheSignals are now aborted to allow clean up of any unused resources.", "564": "Unknown command. The debugChannel was not wired up properly.", "565": "resolveDebugMessage/closeDebugChannel should not be called for a Request that wasn't kept alive. This is a bug in React.", - "566": "FragmentInstance.experimental_scrollIntoView() does not support scrollIntoViewOptions. Use the alignToTop boolean instead." + "566": "FragmentInstance.scrollIntoView() does not support scrollIntoViewOptions. Use the alignToTop boolean instead." }