Skip to content

Commit a55e98f

Browse files
authored
[playground] ViewTransition on internals toggle & tab expansion (#34597)
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn test --debug --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> Added `<ViewTransition>` for when the "Show Internals" button is toggled for a basic fade transition. Additionally added a transition for when tabs are expanded in the advanced view of the Compiler Playground to display a smoother show/hide animation. ## How did you test this change? <!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes the user interface. How exactly did you verify that your PR solves the issue you wanted to solve? If you leave this empty, your PR will very likely be closed. --> https://github.com/user-attachments/assets/c706b337-289e-488d-8cd7-45ff1d27788d
1 parent 063394c commit a55e98f

File tree

5 files changed

+89
-37
lines changed

5 files changed

+89
-37
lines changed

compiler/apps/playground/components/AccordionWindow.tsx

Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@
66
*/
77

88
import {Resizable} from 're-resizable';
9-
import React, {useCallback} from 'react';
9+
import React, {
10+
useCallback,
11+
useId,
12+
unstable_ViewTransition as ViewTransition,
13+
unstable_addTransitionType as addTransitionType,
14+
startTransition,
15+
} from 'react';
16+
import {EXPAND_ACCORDION_TRANSITION} from '../lib/transitionTypes';
1017

1118
type TabsRecord = Map<string, React.ReactNode>;
1219

@@ -50,49 +57,69 @@ function AccordionWindowItem({
5057
setTabsOpen: (newTab: Set<string>) => void;
5158
hasChanged: boolean;
5259
}): React.ReactElement {
60+
const id = useId();
5361
const isShow = tabsOpen.has(name);
5462

55-
const toggleTabs = useCallback(() => {
56-
const nextState = new Set(tabsOpen);
57-
if (nextState.has(name)) {
58-
nextState.delete(name);
59-
} else {
60-
nextState.add(name);
61-
}
62-
setTabsOpen(nextState);
63-
}, [tabsOpen, name, setTabsOpen]);
63+
const transitionName = `accordion-window-item-${id}`;
64+
65+
const toggleTabs = () => {
66+
startTransition(() => {
67+
addTransitionType(EXPAND_ACCORDION_TRANSITION);
68+
const nextState = new Set(tabsOpen);
69+
if (nextState.has(name)) {
70+
nextState.delete(name);
71+
} else {
72+
nextState.add(name);
73+
}
74+
setTabsOpen(nextState);
75+
});
76+
};
6477

6578
// Replace spaces with non-breaking spaces
6679
const displayName = name.replace(/ /g, '\u00A0');
6780

6881
return (
6982
<div key={name} className="flex flex-row">
7083
{isShow ? (
71-
<Resizable className="border-r" minWidth={550} enable={{right: true}}>
72-
<h2
73-
title="Minimize tab"
74-
aria-label="Minimize tab"
75-
onClick={toggleTabs}
76-
className={`p-4 duration-150 ease-in border-b cursor-pointer border-grey-200 ${
77-
hasChanged ? 'font-bold' : 'font-light'
78-
} text-secondary hover:text-link`}>
79-
- {displayName}
80-
</h2>
81-
{tabs.get(name) ?? <div>No output for {name}</div>}
82-
</Resizable>
84+
<ViewTransition
85+
name={transitionName}
86+
update={{
87+
[EXPAND_ACCORDION_TRANSITION]: 'expand-accordion',
88+
default: 'none',
89+
}}>
90+
<Resizable className="border-r" minWidth={550} enable={{right: true}}>
91+
<h2
92+
title="Minimize tab"
93+
aria-label="Minimize tab"
94+
onClick={toggleTabs}
95+
className={`p-4 duration-150 ease-in border-b cursor-pointer border-grey-200 ${
96+
hasChanged ? 'font-bold' : 'font-light'
97+
} text-secondary hover:text-link`}>
98+
- {displayName}
99+
</h2>
100+
{tabs.get(name) ?? <div>No output for {name}</div>}
101+
</Resizable>
102+
</ViewTransition>
83103
) : (
84-
<div className="relative items-center h-full px-1 py-6 align-middle border-r border-grey-200">
85-
<button
86-
title={`Expand compiler tab: ${name}`}
87-
aria-label={`Expand compiler tab: ${name}`}
88-
style={{transform: 'rotate(90deg) translate(-50%)'}}
89-
onClick={toggleTabs}
90-
className={`flex-grow-0 w-5 transition-colors duration-150 ease-in ${
91-
hasChanged ? 'font-bold' : 'font-light'
92-
} text-secondary hover:text-link`}>
93-
{displayName}
94-
</button>
95-
</div>
104+
<ViewTransition
105+
name={transitionName}
106+
update={{
107+
[EXPAND_ACCORDION_TRANSITION]: 'expand-accordion',
108+
default: 'none',
109+
}}>
110+
<div className="relative items-center h-full px-1 py-6 align-middle border-r border-grey-200">
111+
<button
112+
title={`Expand compiler tab: ${name}`}
113+
aria-label={`Expand compiler tab: ${name}`}
114+
style={{transform: 'rotate(90deg) translate(-50%)'}}
115+
onClick={toggleTabs}
116+
className={`flex-grow-0 w-5 transition-colors duration-150 ease-in ${
117+
hasChanged ? 'font-bold' : 'font-light'
118+
} text-secondary hover:text-link`}>
119+
{displayName}
120+
</button>
121+
</div>
122+
</ViewTransition>
96123
)}
97124
</div>
98125
);

compiler/apps/playground/components/Editor/Output.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ import AccordionWindow from '../AccordionWindow';
3232
import TabbedWindow from '../TabbedWindow';
3333
import {monacoOptions} from './monacoOptions';
3434
import {BabelFileResult} from '@babel/core';
35-
import {CONFIG_PANEL_TRANSITION} from '../../lib/transitionTypes';
35+
import {
36+
CONFIG_PANEL_TRANSITION,
37+
TOGGLE_INTERNALS_TRANSITION,
38+
} from '../../lib/transitionTypes';
3639
import {LRUCache} from 'lru-cache';
3740

3841
const MemoizedOutput = memo(Output);
@@ -291,6 +294,7 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element {
291294
<ViewTransition
292295
update={{
293296
[CONFIG_PANEL_TRANSITION]: 'container',
297+
[TOGGLE_INTERNALS_TRANSITION]: '',
294298
default: 'none',
295299
}}>
296300
<TabbedWindow
@@ -306,6 +310,7 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element {
306310
<ViewTransition
307311
update={{
308312
[CONFIG_PANEL_TRANSITION]: 'accordion-container',
313+
[TOGGLE_INTERNALS_TRANSITION]: '',
309314
default: 'none',
310315
}}>
311316
<AccordionWindow

compiler/apps/playground/components/Header.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ import {CheckIcon} from '@heroicons/react/solid';
1010
import clsx from 'clsx';
1111
import Link from 'next/link';
1212
import {useSnackbar} from 'notistack';
13-
import {useState} from 'react';
13+
import {
14+
useState,
15+
startTransition,
16+
unstable_addTransitionType as addTransitionType,
17+
} from 'react';
1418
import {defaultStore} from '../lib/defaultStore';
1519
import {IconGitHub} from './Icons/IconGitHub';
1620
import Logo from './Logo';
1721
import {useStore, useStoreDispatch} from './StoreContext';
22+
import {TOGGLE_INTERNALS_TRANSITION} from '../lib/transitionTypes';
1823

1924
export default function Header(): JSX.Element {
2025
const [showCheck, setShowCheck] = useState(false);
@@ -62,7 +67,12 @@ export default function Header(): JSX.Element {
6267
<input
6368
type="checkbox"
6469
checked={store.showInternals}
65-
onChange={() => dispatchStore({type: 'toggleInternals'})}
70+
onChange={() =>
71+
startTransition(() => {
72+
addTransitionType(TOGGLE_INTERNALS_TRANSITION);
73+
dispatchStore({type: 'toggleInternals'});
74+
})
75+
}
6676
className="absolute opacity-0 cursor-pointer h-full w-full m-0"
6777
/>
6878
<span

compiler/apps/playground/lib/transitionTypes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77

88
export const CONFIG_PANEL_TRANSITION = 'config-panel';
99
export const TOGGLE_TAB_TRANSITION = 'toggle-tab';
10+
export const TOGGLE_INTERNALS_TRANSITION = 'toggle-internals';
11+
export const EXPAND_ACCORDION_TRANSITION = 'open-accordion';

compiler/apps/playground/styles/globals.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,11 @@
116116
::view-transition-group(.tab-text) {
117117
z-index: 1;
118118
}
119+
120+
::view-transition-old(.expand-accordion),
121+
::view-transition-new(.expand-accordion) {
122+
width: auto;
123+
}
124+
::view-transition-group(.expand-accordion) {
125+
overflow: clip;
126+
}

0 commit comments

Comments
 (0)