Skip to content

Instantly share code, notes, and snippets.

@oncomouse
Last active April 15, 2021 05:24
Show Gist options
  • Save oncomouse/08b1920f6b42d90a01a0e296980386a4 to your computer and use it in GitHub Desktop.
Save oncomouse/08b1920f6b42d90a01a0e296980386a4 to your computer and use it in GitHub Desktop.
Using CSSTransitionGroup with Emotion.js
/** @jsx jsx */
import { jsx, css } from '@emotion/core';
import ReactDOM from 'react-dom';
import styled from '@emotion/styled';
import { useState } from 'react';
import StyledTransition from './StyledTransition';
const TransitionBox = styled(StyledTransition)`
display: block;
width: 150px;
height: 150px;
border-radius: 3px;
margin: 2px;
background: ${props => props.background};
`;
const Example = () => {
const [active, setIn] = useState(false);
return (
<div css={css`display: flex;`}>
<TransitionBox
transitions={{
enter: css`
opacity: 1.0;
`,
enterActive: css`
opacity: 0.0;
transition: opacity 250ms ease-in;
`,
enterDone: css`
opacity: 0.0;
`,
exit: css`
opacity: 0;
`,
exitActive: css`
opacity: 1.0;
transition: opacity 250ms ease-in;
`
}}
timeout={250}
background="rgb(192,53,70)"
in={active}
onClick={() => setIn(active => !active)}
>
<div>Hello</div>
</TransitionBox>
<TransitionBox
transitions={{
enter: css`
opacity: 1.0;
transform: rotate(0deg);
`,
enterActive: css`
opacity: 0;
transform: rotate(720deg);
transition: opacity 500ms ease-in, transform 500ms ease-in;
`,
enterDone: css`
opacity: 0;
`,
exit: css`
opacity: 0;
`,
exitActive: css`
opacity: 1.0;
transform: rotate(-720deg);
transition: opacity 500ms ease-in, transform 500ms ease-in;
`
}}
timeout={500}
background="rgb(192,53,70)"
in={active}
onClick={() => setIn(active => !active)}
>
<div>Hello</div>
</TransitionBox>
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
import React from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import { CSSTransition } from 'react-transition-group';
const has = (key, obj) => Object.prototype.hasOwnProperty.call(obj, key);
const keyframes = [
'appear',
'enter',
'exit',
'appear-active',
'enter-active',
'exit-active',
'appear-done',
'enter-done',
'exit-done',
]
const StyledTransition = styled(({ transitions, className, ...props }) => <CSSTransition className={className} classNames={className} {...props} />)`
${({transitions}) => keyframes.map(keyframe => {
const objectKey = keyframe.replace(/(-[a-z])/, v => v.slice(1).toUpperCase());
if (has(objectKey, transitions)) {
return css`
&-${keyframe} {
${transitions[objectKey]}
}
`;
}
return null;
}).filter(x => x !== null)}
`;
export default StyledTransition;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment