{"id":13436294,"url":"https://github.com/cloudflare/react-modal2","last_synced_at":"2025-04-14T15:53:53.060Z","repository":{"id":57334731,"uuid":"45524478","full_name":"cloudflare/react-modal2","owner":"cloudflare","description":":thought_balloon: Simple modal component for React.","archived":false,"fork":false,"pushed_at":"2024-10-16T22:47:48.000Z","size":50,"stargazers_count":276,"open_issues_count":9,"forks_count":16,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-07T08:12:46.279Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudflare.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-04T08:13:02.000Z","updated_at":"2025-03-18T21:49:02.000Z","dependencies_parsed_at":"2024-10-19T03:32:04.824Z","dependency_job_id":null,"html_url":"https://github.com/cloudflare/react-modal2","commit_stats":{"total_commits":40,"total_committers":8,"mean_commits":5.0,"dds":0.375,"last_synced_commit":"dbd7541ad02019898d56f02ed266512c181dc7d2"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Freact-modal2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Freact-modal2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Freact-modal2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Freact-modal2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudflare","download_url":"https://codeload.github.com/cloudflare/react-modal2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248911674,"owners_count":21182134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T03:00:46.311Z","updated_at":"2025-04-14T15:53:53.032Z","avatar_url":"https://github.com/cloudflare.png","language":"JavaScript","funding_links":[],"categories":["Uncategorized","UI Components","Demos"],"sub_categories":["Uncategorized","Overlay","JBoss Data Virtualization"],"readme":"# react-modal2\n\n\u003e Simple modal component for React.\n\n- Unopionated\n- Stateless (dumb component)\n- Accessible\n- Universal/Isomorphic\n- Built via [reusable](https://github.com/cloudflare/react-gateway) [collection](https://github.com/cloudflare/a11y-focus-scope) of [modules](https://github.com/cloudflare/a11y-focus-store)\n\n## Installation\n\n```js\n$ npm install --save react-modal2\n```\n\n## Usage\n\nReactModal2 tries to be as minimal as possible. This means it requires a little\nbit of setup, but gives you complete flexibility to do what you want.\n\nLet's start off with the actual API of ReactModal2:\n\n```js\n\u003cReactModal2\n  // A callback that gets called whenever the `esc` key is pressed, or the\n  // backdrop is clicked.\n  onClose={this.handleClose.bind(this)}\n\n  // Enable/Disable calling `onClose` when the `esc` key is pressed.\n  closeOnEsc={true}\n\n  // Enable/Disable calling `onClose` when the backdrop is clicked.\n  closeOnBackdropClick={true}\n\n  // Add a className to either the backdrop or modal element.\n  backdropClassName='my-custom-backdrop-class'\n  modalClassName='my-custom-modal-class'\n\n  // Add styles to either the backdrop or modal element.\n  backdropStyles={{ my: 'custom', backdrop: 'styles' }}\n  modalStyles={{ my: 'custom', modal: 'styles' }}\u003e\n  ...\n\u003c/ReactModal2\u003e\n```\n\nIf we use it like this it will simply render those two elements in the dom like\nthis:\n\n```html\n\u003cdiv\u003e \u003c!-- Backdrop --\u003e\n  \u003cdiv\u003e...\u003c/div\u003e \u003c!-- Modal --\u003e\n\u003c/div\u003e\n```\n\nHowever, you likely want to render the modal somewhere else in the DOM (in most\ncases at the end of the `document.body`.\n\nFor this there is a separate library called\n[React Gateway](https://github.com/cloudflare/react-gateway). You can use it\nlike this:\n\n```js\nimport {\n  Gateway,\n  GatewayDest,\n  GatewayProvider\n} from 'react-gateway';\nimport ReactModal2 from 'react-modal2';\n\nclass Application extends React.Component {\n  render() {\n    return (\n      \u003cGatewayProvider\u003e\n        \u003cdiv className=\"app\"\u003e\n          \u003cdiv className=\"app-content\"\u003e\n            \u003ch1\u003eMy Application\u003c/h1\u003e\n            \u003cGateway into=\"modal\"\u003e\n              \u003cReactModal2 backdropClassName=\"modal-backdrop\" modalClassName=\"modal\"\u003e\n                ...\n              \u003c/ReactModal2\u003e\n            \u003c/Gateway\u003e\n          \u003c/div\u003e\n          \u003cGatewayDest name=\"modal\" className=\"modal-container\"/\u003e\n        \u003c/div\u003e\n      \u003c/GatewayProvider\u003e\n    );\n  }\n}\n```\n\nWhich will render as:\n\n```html\n\u003cdiv class=\"app\"\u003e\n  \u003cdiv class=\"app-content\"\u003e\n    \u003ch1\u003eMy Application\u003c/h1\u003e\n    \u003cnoscript/\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"modal-container\"\u003e\n    \u003cdiv class=\"modal-backdrop\"\u003e\n      \u003cdiv class=\"modal\"\u003e...\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\nNow this might seem like a lot to do every time you want to render a modal, but\nthis is by design. You are meant to wrap ReactModal2 with your own component\nthat you use everywhere. Your component can add it's own DOM, styles,\nanimations, and behavior.\n\n```js\nimport React from 'react';\nimport {Gateway} from 'react-gateway';\nimport ReactModal2 from 'react-modal2';\n\nexport default class MyCustomModal extends React.Component {\n  static propTypes = {\n    onClose: React.PropTypes.func.isRequired,\n    closeOnEsc: React.PropTypes.bool,\n    closeOnBackdropClick: React.PropTypes.bool\n  };\n\n  getDefaultProps() {\n    return {\n      closeOnEsc: true,\n      closeOnBackdropClick: true\n    };\n  }\n\n  render() {\n    return (\n      \u003cGateway into=\"modal\"\u003e\n        \u003cReactModal2\n          onClose={this.props.onClose}\n          closeOnEsc={this.props.closeOnEsc}\n          closeOnBackdropClick={this.props.closeOnEsc}\n          backdropClassName='my-custom-backdrop-class'\n          modalClassName='my-custom-modal-class'\u003e\n          {this.props.children}\n        \u003c/ReactModal2\u003e\n      \u003c/Gateway\u003e\n    );\n  }\n}\n```\n\nThen simply setup your application once:\n\n```js\nimport {\n  GatewayDest,\n  GatewayProvider\n} from 'react-gateway';\n\nexport default class Application extends React.Component {\n  render() {\n    return (\n      \u003cGatewayProvider\u003e\n        \u003cdiv className=\"app\"\u003e\n          \u003cdiv className=\"app-content\"\u003e\n            ...\n          \u003c/div\u003e\n          \u003cGatewayDest name=\"modal\" className=\"modal-container\"/\u003e\n        \u003c/div\u003e\n      \u003c/GatewayProvider\u003e\n    );\n  }\n}\n```\n\nThen you have your own ideal API for working with modals in any of your\ncomponents.\n\n```js\nimport MyCustomModal from './my-custom-modal';\n\nexport default class MyComponent extends React.Component {\n  state = {\n    isModalOpen: false\n  };\n\n  handleOpen() {\n    this.setState({ isModalOpen: true });\n  }\n\n  handleClose() {\n    this.setState({ isModalOpen: false });\n  }\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton onClick={this.handleOpen.bind(this)}\u003eOpen\u003c/button\u003e\n        {this.state.isModalOpen \u0026\u0026 (\n          \u003cMyCustomModal onClose={this.handleClose.bind(this)}\u003e\n            \u003ch1\u003eHello from Modal\u003c/h1\u003e\n            \u003cbutton onClick={this.handleClose.bind(this)}\u003eClose\u003c/button\u003e\n          \u003c/MyCustomModal\u003e\n        )}\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n## Props\n| Name | Type | Description |\n| --- | --- | --- |\n| `onClose` | `Function` | **Required.** A callback to handle an event that is attempting to close the modal. |\n| `closeOnEsc` | `Boolean` | Should this modal call `onClose` when the `esc` key is pressed? |\n| `closeOnBackdropClick` | `Boolean` | Should this modal call `onClose` when the backdrop is clicked? |\n| `backdropClassName` | `String` | An optional `className` for the backdrop element. |\n| `modalClassName` | `String` | An optional `className` for the modal element. |\n| `backdropStyles` | `Object` | Optional `style` for the backdrop element. |\n| `modalStyles` | `Object` | Optional `style` for the modal element. |\n\n\n\n## Accessibility\n\nOne of ReactModal2's opinions is that modals should be as accessible as\npossible. It does much of the work for you, but there's one little thing you\nneed to help it with.\n\nIn order to \"hide\" your application from screenreaders while a modal is open\nyou need to let ReactModal2 what the root element for your application is.\n\n\u003e **Note:** The root element should not contain the `GatewayDest` or whereever\n\u003e the modal is getting rendered. This will break all the things.\n\n```js\nimport ReactModal2 from 'react-modal2';\n\nReactModal2.getApplicationElement = () =\u003e document.getElementById('application');\n```\n\n## FAQ\n\n#### How do I close the modal?\n\nReactModal2 is designed to have no state, if you put it in the DOM then it will\nrender. So if you don't want to show it then simply do not render it in your\nparent component. For this reason there is no `isOpen` property to pass.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudflare%2Freact-modal2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudflare%2Freact-modal2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudflare%2Freact-modal2/lists"}