react-one-modal
v0.1.0
Published
Animated modal with advanced functionality for React framework
Downloads
2
Readme
React One Modal
Animated modal with advanced functionality for React framework
Getting Started
npm install --save react-one-modal
Then..
Create new instance of Modal
on any component. This Modal
instance will appear on the bottom of body
element by default, and it preserves the React Context of its contents to where it has been defined.
import Modal, { bindModal } from 'react-one-modal'
const App = () => {
const [modal, modalRef] = bindModal('my-modal')
...
return (
<>
<button onClick={() => modal.show(<MyComponent />)}>
Show floating modal
</button>
...
<Modal ref={modalRef} />
</>
)
}
By using bindModal
, you can bind this Modal
instance to the given key in its argument (eg. my-modal
) using the returned ref
object. Then you can use modal
to access the the functionality of the bounded Modal
directly in this component.
To facilitate accessing your defined modals, One Modal does manage its own state. Calling getModal(key)
on any component, gives access the bounded of Modal
instance with the given key.
import { useModal } from 'react-one-modal'
const MyComponent = () => {
const modal = getModal('my-modal')
...
return (
<>
...
<button onClick={() => { modal.push(<MyComponentStep2 />) }}>
Next Step
</button>
<button onClick={() => { modal.empty() }}>
Close
</button>
</>
)
}
For use cases where a modal is needed for one-time use, an anonymous modal can be defined and used directly via useModal
hook without binding it to any key.
import Modal, { useModal } from 'react-one-modal'
const MyComponent = () => {
const modal = getModal()
const [confirmModal, confirmModalRef] = useModal()
...
return (
<>
...
<Modal ref={confirmModalRef} >
<p> Are you sure </p>
<button onClick={() => {
// do some action!
confirmModal.hide()
}}>
Confirm
</button>
<button onClick={() => { confirmModal.empty() }}>
Close
</button>
</Modal>
</>
)
}
Why One Modal?
TL;DR: The only modal you will ever need, truly the one modal for all your user cases!
- Accessibility out-of-the-box, with progressive enhancement like no other modals!
- Feature rich, while having small package size
- Awesome animation with high reliability!
- Bottom-Sheet mode!
- Dialog mode
- First modal with stacking context: add as many step (modal-sheets) to your modal with ease, and awesome transitions!
Nested modals!? but..
Nested modals aren’t supported as we believe them to be poor user experiences.
source: Bootstrap modal
One Modal takes different approach by making nested modal accessible and awesome user experience! While being in a stacked context by itself!
Accessibility (A11y)
One Modal follow the guidelines defined by Web Accessibility Initiative - WAI as part of ARIA - W3C specification for an accessible modal, and state-of-the-art practices that has been used by newly introduced <dialog>
element.
It uses it own progressively enhanced focus management solution and helper attribute aria-modal="true"
and role="dialog"
to hide element from Accessibility DOM tree.
On Dialog mode: aria-modal="false
and interaction with page elements is allowed, following the semantic that has been used by <dialog>
element through dialog.showModal()
and dialog.show()
Ability to pass aria-x
(eg. aria-labelledby
, aria-describedby
, aria-label
) attributes for modal-sheet html on push
/transit
/show
. This can be added for all modal-sheets within a Modal
instance by defining them in attributesSheet
prop, or for a specific modal-sheet through passing attributes
option when calling push
/transit
/show
.
For more detail, please read One Modal - Focus Management.
What is new?
- [x] Auto load css when importing component, no need to import stylesheet separably
- [x] All control functions (push/pop/close/show/hide) are using promises and resolve when animation is done
- [x] handle all errors using
setModalErrorHandler
- [x] Enhanced accessibility!
- [x] handle concurrent push/pop (Promise chaining)
- [x] Move to TypeScript
- [x] Disable page scroll when modal is open
- [x] Add
back
,next
control functions to traverse the stack while keeping all components live - [x] Add
silent
option topush
, to not update the active sheet when appending the given sheet - [x] Add
last
option topush
, to always append the given modal-sheet to last position insilent
mode - [x] Add
last
option topop
, to always pop the last sheet in stack - [x] Close using ESC or clicking outside the modal (Optionally)
- [ ] Local modal, for part of the DOM tree [WIP]
- [ ] Dialog mode [WIP]
API
See One Modal - API
Examples
Roadmap
One Modal and <dialog>
element
One Modal should be a replacement for <dialog>
html element with regards to behavior and not API, it should mimic <dialog>
even in edge cases or add statement otherwise. Please find the known differences in behavior here.
Made with ❤️ at Schuttelaar & Partners
MIT License © MahmoudRe @ Schuttelaar & Partners