Smart wrappers using framer-motion to add transitions to child components.
Basic Usage
The theme defines several preconfigured transitions that will apply the base styles and the exit and enter variants.
Changing the value of isOpen
results in the transition animating. Going from isOpen={true}
to isOpen={false}
will results
in the transition animating to the exit
variant. Going from isOpen={false}
to isOpen={true}
will result in animating to the enter
variant.
Collapse
Collapse will transition the child components from 100% height to 0px.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} collapse><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Fade
To have the child components fade from completely transparent use the fade transition.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} fade><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Nudge
The Nudge transitions (nudgeLeft
, nudgeRight
, nudgeTop
, nudgeBottom
) move the children from 50px away from their target. Alone this might look weird, but when used in conjection with fade it gives the apparence of fading into a closer position.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} nudgeLeft style={{ margin: '0 0 10px 50px' }}><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Rotate
The rotate transitions (rotate45
, rotate90
, rotate180
) will rotate the child components counter-clockwise.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 50px;margin: 0 auto;background: #bada55;`;return (<><TransitionisOpen={isOpen}style={{ width: '250px', height: '250px' }}rotate45><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>rotate</Button></>);}
Scale
The scale transition will scale the child components from 95% to 100%. This alone will not look impressive, but when used with fade
creates a nice transition.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;margin: 0 auto;`;return (<><Transition isOpen={isOpen} style={{ width: '250px' }} scale><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'shrink' : 'grow'}</Button></>);}
Slide
The slide transitions (slideRight
, slideLeft
, slideTop
, slideBottom
) will slide the children to the edge of the screen from outside of view. The slide transitions will always anchor the children to one of the edges of the screen.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 100%;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} slideLeft><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Composition
Transitions can be combined to create more advanced effects.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} nudgeBottom fade><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
unmountOnExit
By default, Transition
will only transition between the two style variants for enter
and exit
but will leave the children in the DOM.
Using the prop unmountOnExit
will remove the children from the DOM completely after they have been animated off the visible screen.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;return (<><Transition isOpen={isOpen} collapse unmountOnExit><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Custom Transition
The magma theme has several sane defaults to create a consistent experience across all apps. But Transition
does allow for customTransition
and style
to be overwritten.
import React from 'react';import styled from '@emotion/styled';import { Button, Transition } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;const customTransition = {exit: {rotate: 360,transition: {rotate: {type: 'inertia',velocity: 500,},},},enter: {rotate: 0,transition: {rotate: {type: 'spring',damping: 10,stiffness: 100,},},},};const baseStyle = {width: '250px',height: '250px',};return (<><Transitionstyle={baseStyle}isOpen={isOpen}customTransition={customTransition}><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>Spin it!</Button></>);}
Kitchen Sink
import React from 'react';import styled from '@emotion/styled';import { Button, Transition, Checkbox } from 'react-magma-dom';export function Example() {const [isOpen, setIsOpen] = React.useState(false);const [properties, setProperties] = React.useState({});const Box = styled('div')`height: 250px;width: 250px;background: #bada55;`;const Preview = () => (<pre>{'<'}Transition{' '}{Object.keys(properties).filter(key => properties[key]).join(' ')}{'>\n'}{' <'}div{'>'}children{'<'}/div{'>\n'}{'<'}/Transition{'>'}</pre>);return (<><CheckboxlabelText="unmountOnExit"checked={properties.unmountOnExit}onChange={() =>setProperties({...properties,unmountOnExit: !properties.unmountOnExit,})}/><CheckboxlabelText="fade"checked={properties.fade}onChange={() =>setProperties({ ...properties, fade: !properties.fade })}/><CheckboxlabelText="scale"checked={properties.scale}onChange={() =>setProperties({ ...properties, scale: !properties.scale })}/><CheckboxlabelText="collapse"checked={properties.collapse}disabled={properties.slideTop |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeTop |properties.nudgeBottom |properties.nudgeLeft |properties.nudgeRight}onChange={() =>setProperties({ ...properties, collapse: !properties.collapse })}/><CheckboxlabelText="slideTop"checked={properties.slideTop}disabled={properties.collapse |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeTop |properties.nudgeBottom |properties.nudgeLeft |properties.nudgeRight}onChange={() =>setProperties({ ...properties, slideTop: !properties.slideTop })}/><CheckboxlabelText="slideBottom"checked={properties.slideBottom}disabled={properties.collapse |properties.slideTop |properties.slideLeft |properties.slideRight |properties.nudgeTop |properties.nudgeBottom |properties.nudgeLeft |properties.nudgeRight}onChange={() =>setProperties({...properties,slideBottom: !properties.slideBottom,})}/><CheckboxlabelText="slideRight"checked={properties.slideRight}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideLeft |properties.nudgeTop |properties.nudgeBottom |properties.nudgeLeft |properties.nudgeRight}onChange={() =>setProperties({...properties,slideRight: !properties.slideRight,})}/><CheckboxlabelText="slideLeft"checked={properties.slideLeft}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideRight |properties.nudgeTop |properties.nudgeBottom |properties.nudgeLeft |properties.nudgeRight}onChange={() =>setProperties({ ...properties, slideLeft: !properties.slideLeft })}/><CheckboxlabelText="nudgeTop"checked={properties.nudgeTop}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeBottom}onChange={() =>setProperties({ ...properties, nudgeTop: !properties.nudgeTop })}/><CheckboxlabelText="nudgeBottom"checked={properties.nudgeBottom}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeTop}onChange={() =>setProperties({...properties,nudgeBottom: !properties.nudgeBottom,})}/><CheckboxlabelText="nudgeRight"checked={properties.nudgeRight}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeLeft}onChange={() =>setProperties({...properties,nudgeRight: !properties.nudgeRight,})}/><CheckboxlabelText="nudgeLeft"checked={properties.nudgeLeft}disabled={properties.collapse |properties.slideTop |properties.slideBottom |properties.slideLeft |properties.slideRight |properties.nudgeRight}onChange={() =>setProperties({ ...properties, nudgeLeft: !properties.nudgeLeft })}/><Preview /><Transition isOpen={isOpen} {...properties}><Box /></Transition><Button onClick={() => setIsOpen(!isOpen)}>{isOpen ? 'hide' : 'show'}</Button></>);}
Transition Props
Any other props supplied will be provided to the wrapping motion.div
element.
collapse
Description
Should children collapse in/out
Type
boolean
Default
false
fade
Description
Should children fade in/out
Type
boolean
Default
false
isOpen
Description
If `true`, the content will animate in
Type
boolean
Default
false
nudgeBottom
Description
Should the children get nudged in 50px from the bottom
Type
boolean
Default
false
nudgeLeft
Description
Should the children get nudged in 50px from the left
Type
boolean
Default
false
nudgeRight
Description
Should the children get nudged in 50px from the right
Type
boolean
Default
false
nudgeTop
Description
Should the children get nudged in 50px from the top
Type
boolean
Default
false
rotate180
Description
Should children rotate 180 degrees
Type
boolean
Default
false
rotate45
Description
Should children rotate 45 degrees
Type
boolean
Default
false
rotate90
Description
Should children rotate 90 degrees
Type
boolean
Default
false
scale
Description
Should children scale in/out
Type
boolean
Default
false
slideBottom
Description
Should children slide in/out from the bottom of the screen
Type
boolean
Default
false
slideLeft
Description
Should children slide in/out from the left of the screen
Type
boolean
Default
false
slideRight
Description
Should children slide in/out from the right of the screen
Type
boolean
Default
false
slideTop
Description
Should children slide in/out from the top of the screen
Type
boolean
Default
false
unmountOnExit
Description
If `true`, the element will unmount when `in={false}` and animation is done
Type
boolean
Default
false
On this page