diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSharedStyles.css b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSharedStyles.css
index 978077d2d9a24..413554008fa53 100644
--- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSharedStyles.css
+++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSharedStyles.css
@@ -75,6 +75,10 @@
display: flex;
}
+.CollapsableHeader[data-pending="true"] {
+ cursor: progress;
+}
+
.CollapsableHeaderIcon {
flex: 0 0 1rem;
margin-left: -0.25rem;
diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspendedBy.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspendedBy.js
index a9d22b5a881be..54a1c6c9529bf 100644
--- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspendedBy.js
+++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSuspendedBy.js
@@ -9,7 +9,7 @@
import {copy} from 'clipboard-js';
import * as React from 'react';
-import {useState} from 'react';
+import {useState, useTransition} from 'react';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import KeyValue from './KeyValue';
@@ -101,6 +101,7 @@ function SuspendedByRow({
maxTime,
}: RowProps) {
const [isOpen, setIsOpen] = useState(false);
+ const [openIsPending, startOpenTransition] = useTransition();
const ioInfo = asyncInfo.awaited;
const name = useInferredName(asyncInfo);
const description = ioInfo.description;
@@ -144,7 +145,16 @@ function SuspendedByRow({
)}
-
+
{treeListDisabled ? (
) : (
)}
-
+
-
-
-
-
>
);
}
export default function SuspenseTimeline(): React$Node {
- const store = useContext(StoreContext);
- const {roots, selectedRootID, uniqueSuspendersOnly} = useContext(
- SuspenseTreeStateContext,
- );
- const treeDispatch = useContext(TreeDispatcherContext);
- const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext);
-
- function handleChange(event: SyntheticEvent) {
- const newRootID = +event.currentTarget.value;
- // TODO: scrollIntoView both suspense rects and host instance.
- const nextTimeline = store.getSuspendableDocumentOrderSuspense(
- newRootID,
- uniqueSuspendersOnly,
- );
- suspenseTreeDispatch({
- type: 'SET_SUSPENSE_TIMELINE',
- payload: [nextTimeline, newRootID, uniqueSuspendersOnly],
- });
- if (nextTimeline.length > 0) {
- const milestone = nextTimeline[nextTimeline.length - 1];
- treeDispatch({type: 'SELECT_ELEMENT_BY_ID', payload: milestone});
- }
- }
-
+ const {selectedRootID} = useContext(SuspenseTreeStateContext);
return (
- {roots.length > 0 && (
-
- )}
);
}
diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
index 97869cf0bea28..60154d6118138 100644
--- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
+++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
@@ -3021,7 +3021,8 @@ describe('ReactFlightDOM', () => {
expect(getMeaningfulChildren(container)).toEqual(
loading...
);
});
- // @gate enableHalt
+ // This could be a bug. Discovered while making enableAsyncDebugInfo dynamic for www.
+ // @gate experimental && (enableHalt || (enableAsyncDebugInfo && __DEV__))
it('will leave async iterables in an incomplete state when halting', async () => {
let resolve;
const wait = new Promise(r => (resolve = r));
diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
index 601d3799d145f..674aa5d320187 100644
--- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
@@ -36,6 +36,7 @@ export const enableComponentPerformanceTrack: boolean = __VARIANT__;
export const enableScrollEndPolyfill: boolean = __VARIANT__;
export const enableFragmentRefs: boolean = __VARIANT__;
export const enableFragmentRefsScrollIntoView: boolean = __VARIANT__;
+export const enableAsyncDebugInfo: boolean = __VARIANT__;
// TODO: These flags are hard-coded to the default values used in open source.
// Update the tests so that they pass in either mode, then set these
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 1fa2096e9e2bf..408fc0b62f667 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -34,6 +34,7 @@ export const {
enableScrollEndPolyfill,
enableFragmentRefs,
enableFragmentRefsScrollIntoView,
+ enableAsyncDebugInfo,
} = dynamicFeatureFlags;
// On WWW, __EXPERIMENTAL__ is used for a new modern build.
@@ -94,7 +95,6 @@ export const passChildrenWhenCloningPersistedNodes: boolean = false;
export const enablePersistedModeClonedFlag: boolean = false;
-export const enableAsyncDebugInfo: boolean = false;
export const disableClientCache: boolean = true;
export const enableReactTestRendererWarning: boolean = false;