Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix side panel exit animation #350

Merged
merged 15 commits into from
May 10, 2024
5 changes: 5 additions & 0 deletions .changeset/beige-tips-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'playroom': patch
---

Fix minor issue in the side panel exit animation, preventing the contents from vanishing abruptly.
felixhabib marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions cypress/support/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ export const assertCodePaneLineCount = (lines) => {
getCodeEditor().within(() =>
cy.get('.CodeMirror-line').should('have.length', lines)
);

// Wait after check to ensure original focus is restored
cy.wait(500); // eslint-disable-line @finsit/cypress/no-unnecessary-waiting
felixhabib marked this conversation as resolved.
Show resolved Hide resolved
};

export const assertFramesMatch = (matches) =>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"re-resizable": "^6.9.9",
"react-docgen-typescript": "^2.2.2",
"react-helmet": "^6.1.0",
"react-transition-group": "^4.4.5",
"react-use": "^17.4.0",
"read-pkg-up": "^7.0.1",
"scope-eval": "^1.0.0",
Expand All @@ -114,6 +115,7 @@
"@octokit/rest": "^19.0.5",
"@types/jest": "^29.2.4",
"@types/react-helmet": "^6.1.6",
"@types/react-transition-group": "^4.4.10",
"concurrently": "^7.6.0",
"cypress": "^13.6.6",
"eslint": "^8.44.0",
Expand Down
33 changes: 33 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 36 additions & 8 deletions src/Playroom/Toolbar/Toolbar.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,52 @@ export const panel = style([
position: 'relative',
display: 'flex',
overflow: 'auto',
transition: 'slow',
pointerEvents: 'auto',
}),
{
width: toolbarOpenSize,
backgroundColor: colorPaletteVars.background.surface,
borderLeft: `${toolbarBorderThickness} solid ${colorPaletteVars.border.standard}`,
selectors: {
[`${root}:not(${isOpen}) &`]: {
transform: `translateX(${calc(`${toolbarOpenSize}px`).multiply(0.3)})`,
opacity: 0,
pointerEvents: 'none',
},
},
},
]);

export const preference = sprinkles({
position: 'absolute',
inset: 0,
});

export const transitionStyles = {
enter: style({
opacity: 0,
transform: `translateX(${calc(`${toolbarOpenSize}px`).multiply(0.3)})`,
askoufis marked this conversation as resolved.
Show resolved Hide resolved
}),
enterActive: style([
sprinkles({
transition: 'slow',
}),
{
opacity: 1,
transform: `translateX(0)`,
},
]),
enterDone: style({
opacity: 1,
transform: `translateX(0)`,
}),
exit: style({
opacity: 1,
}),
exitActive: style([
sprinkles({
transition: 'slow',
}),
{
opacity: 0,
transform: `translateX(${calc(`${toolbarOpenSize}px`).multiply(0.3)})`,
},
]),
exitDone: style({
opacity: 0,
transform: `translateX(${calc(`${toolbarOpenSize}px`).multiply(0.3)})`,
}),
};
105 changes: 59 additions & 46 deletions src/Playroom/Toolbar/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ import SettingsPanel from '../SettingsPanel/SettingsPanel';
import SettingsIcon from '../icons/SettingsIcon';
import { isMac } from '../../utils/formatting';

import { CSSTransition } from 'react-transition-group';

interface Props {
themes: PlayroomProps['themes'];
widths: PlayroomProps['widths'];
snippets: PlayroomProps['snippets'];
}

export const toolbarItemCount = 5;
const ANIMATION_TIMEOUT = 300;

export default ({ themes: allThemes, widths: allWidths, snippets }: Props) => {
const [
Expand Down Expand Up @@ -58,6 +61,9 @@ export default ({ themes: allThemes, widths: allWidths, snippets }: Props) => {
const isSettingsOpen = activeToolbarPanel === 'settings';
const isPreviewOpen = activeToolbarPanel === 'preview';

const [lastActivePanel, setLastActivePanel] =
useState<typeof activeToolbarPanel>(undefined);

const hasSnippets = snippets && snippets.length > 0;
const hasFilteredFrames =
visibleThemes.length > 0 || visibleWidths.length > 0;
Expand Down Expand Up @@ -148,58 +154,65 @@ export default ({ themes: allThemes, widths: allWidths, snippets }: Props) => {
</ToolbarItem>
</div>
</div>

<div className={styles.panel}>
{isSnippetsOpen && (
<div
hidden={isSnippetsOpen ? undefined : true}
className={styles.preference}
>
<Snippets
snippets={snippets}
onHighlight={(snippet) => {
dispatch({
type: 'previewSnippet',
payload: { snippet },
});
}}
onClose={(snippet) => {
if (snippet) {
<CSSTransition
in={isOpen}
timeout={ANIMATION_TIMEOUT}
classNames={styles.transitionStyles}
mountOnEnter
unmountOnExit
onEnter={() => setLastActivePanel(activeToolbarPanel)}
onExited={() => setLastActivePanel(undefined)}
>
<div className={styles.panel} id="custom-id">
{lastActivePanel === 'snippets' && (
<div className={styles.preference}>
felixhabib marked this conversation as resolved.
Show resolved Hide resolved
<Snippets
snippets={snippets}
onHighlight={(snippet) => {
dispatch({
type: 'persistSnippet',
type: 'previewSnippet',
payload: { snippet },
});
} else {
dispatch({ type: 'closeToolbar' });
}
}}
/>
</div>
)}
<div
hidden={isFramesOpen ? undefined : true}
className={styles.preference}
>
<FramesPanel
availableWidths={allWidths}
availableThemes={allThemes}
/>
</div>
}}
onClose={(snippet) => {
if (snippet) {
dispatch({
type: 'persistSnippet',
payload: { snippet },
});
} else {
dispatch({ type: 'closeToolbar' });
}
}}
/>
</div>
)}

<div
hidden={isPreviewOpen ? undefined : true}
className={styles.preference}
>
<PreviewPanel themes={allThemes} visibleThemes={visibleThemes} />
</div>
{lastActivePanel === 'frames' && (
<div className={styles.preference}>
<FramesPanel
availableWidths={allWidths}
availableThemes={allThemes}
/>
</div>
)}

<div
hidden={isSettingsOpen ? undefined : true}
className={styles.preference}
>
<SettingsPanel />
{lastActivePanel === 'preview' && (
<div className={styles.preference}>
<PreviewPanel
themes={allThemes}
visibleThemes={visibleThemes}
/>
</div>
)}

{lastActivePanel === 'settings' && (
<div className={styles.preference}>
<SettingsPanel />
</div>
)}
</div>
</div>
</CSSTransition>
</div>
</div>
);
Expand Down