diff --git a/compiler/apps/playground/components/AccordionWindow.tsx b/compiler/apps/playground/components/AccordionWindow.tsx index db12e76670a91..09614bd505b04 100644 --- a/compiler/apps/playground/components/AccordionWindow.tsx +++ b/compiler/apps/playground/components/AccordionWindow.tsx @@ -23,6 +23,7 @@ export default function AccordionWindow(props: { tabsOpen: Set; setTabsOpen: (newTab: Set) => void; changedPasses: Set; + isFailure: boolean; }): React.ReactElement { return (
@@ -36,6 +37,7 @@ export default function AccordionWindow(props: { tabsOpen={props.tabsOpen} setTabsOpen={props.setTabsOpen} hasChanged={props.changedPasses.has(name)} + isFailure={props.isFailure} /> ); })} @@ -50,15 +52,17 @@ function AccordionWindowItem({ tabsOpen, setTabsOpen, hasChanged, + isFailure, }: { name: string; tabs: TabsRecord; tabsOpen: Set; setTabsOpen: (newTab: Set) => void; hasChanged: boolean; + isFailure: boolean; }): React.ReactElement { const id = useId(); - const isShow = tabsOpen.has(name); + const isShow = isFailure ? name === 'Output' : tabsOpen.has(name); const transitionName = `accordion-window-item-${id}`; diff --git a/compiler/apps/playground/components/Editor/Output.tsx b/compiler/apps/playground/components/Editor/Output.tsx index a54cc3c3d78fa..17da512e80fa0 100644 --- a/compiler/apps/playground/components/Editor/Output.tsx +++ b/compiler/apps/playground/components/Editor/Output.tsx @@ -265,14 +265,8 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element { * Update the active tab back to the output or errors tab when the compilation state * changes between success/failure. */ - const [previousOutputKind, setPreviousOutputKind] = useState( - compilerOutput.kind, - ); - if (compilerOutput.kind !== previousOutputKind) { - setPreviousOutputKind(compilerOutput.kind); - setTabsOpen(new Set(['Output'])); - setActiveTab('Output'); - } + + const isFailure = compilerOutput.kind !== 'ok'; const changedPasses: Set = new Set(['Output', 'HIR']); // Initial and final passes should always be bold let lastResult: string = ''; for (const [passName, results] of compilerOutput.results) { @@ -301,6 +295,8 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element { tabs={tabs} activeTab={activeTab} onTabChange={setActiveTab} + // Display the Output tab on compilation failure + activeTabOverride={isFailure ? 'Output' : undefined} /> ); @@ -319,6 +315,7 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element { tabsOpen={tabsOpen} tabs={tabs} changedPasses={changedPasses} + isFailure={isFailure} /> ); diff --git a/compiler/apps/playground/components/TabbedWindow.tsx b/compiler/apps/playground/components/TabbedWindow.tsx index c324e3ce4505a..ceeb122dd33c5 100644 --- a/compiler/apps/playground/components/TabbedWindow.tsx +++ b/compiler/apps/playground/components/TabbedWindow.tsx @@ -17,11 +17,15 @@ export default function TabbedWindow({ tabs, activeTab, onTabChange, + activeTabOverride, }: { tabs: Map; activeTab: string; onTabChange: (tab: string) => void; + activeTabOverride?: string; }): React.ReactElement { + const currentActiveTab = activeTabOverride ? activeTabOverride : activeTab; + const id = useId(); const transitionName = `tab-highlight-${id}`; @@ -37,7 +41,7 @@ export default function TabbedWindow({
{Array.from(tabs.keys()).map(tab => { - const isActive = activeTab === tab; + const isActive = currentActiveTab === tab; return (
diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index 7d28dc43ca569..0f75d5f8cd78e 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -2279,6 +2279,11 @@ export function startViewTransition( spawnedWorkCallback(); }; const handleError = (error: mixed) => { + // $FlowFixMe[prop-missing] + if (ownerDocument.__reactViewTransition === transition) { + // $FlowFixMe[prop-missing] + ownerDocument.__reactViewTransition = null; + } try { error = customizeViewTransitionError(error, false); if (error !== null) { @@ -2293,6 +2298,9 @@ export function startViewTransition( layoutCallback(); // Skip afterMutationCallback() since we're not animating. spawnedWorkCallback(); + if (enableProfilerTimer) { + finishedAnimation(); + } } }; transition.ready.then(readyCallback, handleError); @@ -2699,6 +2707,11 @@ export function startGestureTransition( ? () => requestAnimationFrame(readyCallback) : readyCallback; const handleError = (error: mixed) => { + // $FlowFixMe[prop-missing] + if (ownerDocument.__reactViewTransition === transition) { + // $FlowFixMe[prop-missing] + ownerDocument.__reactViewTransition = null; + } try { error = customizeViewTransitionError(error, true); if (error !== null) { @@ -2713,6 +2726,9 @@ export function startGestureTransition( // Skip readyCallback() and go straight to animateCallbck() since we're not animating. // animateCallback() is still required to restore states. animateCallback(); + if (enableProfilerTimer) { + finishedAnimation(); + } } }; transition.ready.then(readyForAnimations, handleError);