This release migrates from being an entirely custom modal library with animations to using @reach/dialog
under the hood. This change should mean better accessibility, a bit more thought-out API for the modals, and a whole community behind their implementation.
With this, I had to rewrite the entire package from scratch after writing multiple differing iterations. Here are the differences the new 2.x version has from 1.x versions:
- You don't need
<div id="modal-root"></div>
anymore since@reach/dialog
handles that for us. <ModalPortal>
no longer exists.<ModalBackdrop>
and<BaseModal>
have become one. More info on this below.- All CSS is grouped together in one file called
styles.css
.
import 'react-spring-modal/styles.css'
- The prop to close the modal is now called
onDismiss
instead ofonRequestClose
. - Added two helper components:
<ModalTitle>
and<ModalCloseTarget>
<ModalTitle>
is anh1
with anas
prop to change it to something else. It gives yourh1
anid
and assigns that to the modal'saria-labelledby
attribute to improve accessibility.<ModalCloseTarget>
wraps around your elements and makes it so that when you click on one of those elements it will fireonDismiss
. You can put as many elements inside it as you want. It also does not create it's own HTML element, it uses React Fragments (<></>
).- Alongside
CenterModal
andBottomModal
, we now haveExpandModal
. This modal simply let's you animate theclip-path
CSS property to have your element appear as if it was a growing circle. You get to choose where the center of this circle is with thex
andy
props (these are percentages).
For a full look at what accepts what properties, you can look at the new README, look at the source code, or pull it up in an editor with the TypeScript service enabled.
How <BaseModal>
works now
First, let's talk about how it worked before. In the 1.x
versions, you would simply apply the animations to an <animated.div>
, or similar, element via useTransition
and transition.map
. In the 2.x
version, you no longer manually handle the creation or application of your transition. You only provide the values to create the transition. There are two elements that you can apply transitions to, the overlay and the content. You can also apply any other props you want to these elements. The props these elements accept come from @reach/dialog
's DialogOverlay
and DialogContent
— both of these elements have been passed through react-spring
's animated()
as well. You can further configure your transition with the transitionConfig
prop which simply allows you to pass anything else allowed in useTransition
that isn't from
, enter
, or leave
.
import { config } from 'react-spring'
import { BaseModal } from 'react-spring-modal'
<BaseModal
isOpen={/* ... */}
onDismiss={() => /* ... */}
contentTransition={{ // place your 'from', 'enter', and 'leave' transitions for the content here.
from: { transform: 'scale(0)' },
enter: { transform: 'scale(1)' },
leave: { transform: 'scale(0)' }
}}
contentProps={{ className: 'MyModal w-100 h-100' }},
transitionConfig={{ config: config.stiff }}
>
{/* Content goes here */}
</BaseModal>