@koga73/react-overlay
v1.0.7
Published
A simple responsive modal system for the web. Fully accessible. Easy to style.
Downloads
23
Maintainers
Readme
react-overlay
A React implementation of https://github.com/koga73/overlay
- A simple responsive modal system for the web
- Fully accessible
- Easy to style
Accessibility
Overlay has been designed to be completely accessible. Features are as follows:
- Fallback text for "X" icon reads "Close"
- Escape key closes the Overlay
- Focus is given to top-most Overlay shown if there are multiple
- Traps keyboard focus so the user can't tab to the page behind the Overlay
- Focus is restored to original element after Overlay is closed
- Traps screen-reader in Overlay by giving page content z-index="-1" and aria-hidden="true"
- Overlay is announced via "Dialog Start" when shown
- Default aria-label "Overlay" is added unless element has aria-label or aria-labelledby
Install
npm install @koga73/react-overlay
Import
JSX
import ReactOverlay from "@koga73/react-overlay";
SCSS
@import "@koga73/react-overlay";
Usage
This component can be used in a controlled or uncontrolled manner - meaning the parent controls the Overlay open state (controlled) or not (uncontrolled)
Controlled implementation
Use the controlled implementation if you want your parent to maintain the visibility of the Overlay
import React, {useState} from "react";
import ReactOverlay from "@koga73/react-overlay";
//Be sure to import Overlay styles in here: @import "@koga73/react-overlay"
//Or customize, styles can be found here: https://github.com/koga73/overlay/tree/master/css
import "./example.scss";
() => {
const [stateIsOpen, setStateIsOpen] = useState(); //You can pass in an initial value here
return (
<div>
<div data-overlay-page-wrap>
<h1>Page content</h1>
<button onClick={evt => this.setStateIsOpen(true)}>Show Overlay</button>
</div>
<div style={{display: "none"}}>
<ReactOverlay
id="myOverlay"
isOpen={isOpen}
onRequestClose={detail => this.setStateIsOpen(false)}
>
<p>Some content</p>
</ReactOverlay>
</div>
</div>
);
};
Uncontrolled implementation
Use the uncontrolled implementation if you don't care about maintaining the Overlay shown state
import React from "react";
import ReactOverlay from "@koga73/react-overlay";
//Be sure to import Overlay styles in here: @import "@koga73/react-overlay"
//Or customize, styles can be found here: https://github.com/koga73/overlay/tree/master/css
import "./example.scss";
class App extends React.Component {
render() {
return (
<div>
<div data-overlay-page-wrap>
<h1>Page content</h1>
<button onClick={evt => ReactOverlay.show("myOverlay")}>Show Overlay</button>
</div>
<div style={{display: "none"}}>
<ReactOverlay id="myOverlay">
<p>Some content</p>
</ReactOverlay>
</div>
</div>
);
}
}
Props
Instance
The following props are parsed out and any other props get passed-through
- classPrefix | String | Default: "overlay-" | Appended to all generated classes. For example: "overlay-container". If undefined, defaults to ReactOverlay.classPrefix
- container | Node | Default: undefined" | Container to put Overlays in when not shown. If undefined, defaults to ReactOverlay.container
- pageWrap | Node | Default: undefined | Container of main page content to disallow focus when Overlay is shown. If undefined, defaults to ReactOverlay.pageWrap
- isOpen | Boolean | Default: undefined | Sets the Overlay open state (makes component controlled)
- width | String | Default: undefined | Overrides the CSS width of the Overlay. For example: "50vw" or "400px" or "75%"
- height | String | Default: undefined | Overrides the CSS height of the Overlay. For example: "50vh" or "400px" or "75%"
- offsetX | String | Default: undefined | Overrides the CSS left of the Overlay. For example: "200px"
- offsetY | String | Default: undefined | Overrides the CSS top of the Overlay. For example: "200px"
- containerClass | String | Default: undefined | Class to append to the Overlay frame. For example: "slide-down"
- userClosable | Boolean | Default: undefined | Determines whether the user can close the Overlay by clicking outside of it or on the close button
- autoFocus | Boolean | Default: false | Automatically focus on the first focusable element inside the Overlay after shown
- immediate | Boolean | Default false | Fire events immediately, don't wait for transitions
Callbacks
The following callbacks are parsed out and any other callbacks get passed-through
- onRequestClose | Function | Params: (detail) | Fires when the user attempts to close an Overlay
- onBeforeShow | Function | Params: (evt, detail) | Fires when Overlay begins to show but before transitions are complete
- onAfterShow | Function | Params: (evt, detail) | Fires when Overlay is fully shown after transitions are complete
- onBeforeHide | Function | Params: (evt, detail) | Fires when Overlay begins to hide but before transitions are complete
- onAfterHide | Function | Params: (evt, detail) | Fires when Overlay is fully hidden after transitions are complete
- onOverlayChange | Function | Params: (overlay) | Fires when Overlay instance is initialized or destroyed and passes the instance
Static
Static instance
By default a static instance is created on the window named ReactOverlay. You can override the default values below, just call update after. Note, ReactOverlay instances will use these defaults if not defined on the instance.
- classPrefix | String | Default: "overlay-" | Appended to all generated classes. For example: "overlay-container"
- container | Element | Default: undefined | Container to put Overlays in when not shown
- pageWrap | Element | Default: undefined | Container of main page content to disallow focus when Overlay is shown
- requestCloseCallback | Function | Default: undefined | Called when a user attempts to close an Overlay. Return false to cancel
- show | Function | Show an Overlay
- hide | Function | Hide the currently shown Overlay
- update | Function | Update the static instance with new defaults (classPrefix, container, pageWrap, requestCloseCallback)
React-DOM 18
Note that if using React-DOM 18, you should specify the react root as the static container. This is because React-DOM 18 uses portals to render the Overlay outside of the root element.
import React from "react";
import ReactDOM from "react-dom/client";
import ReactOverlay from "@koga73/react-overlay";
const rootEl = document.getElementById("root");
ReactDOM.createRoot(rootEl).render(<Example />);
//Specify the root element as the container when using React-DOM 18
ReactOverlay.update({container: rootEl});