├── .gitignore ├── README.md ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json ├── src ├── App.css ├── App.js ├── App.test.js ├── examples │ ├── basic │ │ ├── index.css │ │ └── index.js │ ├── children │ │ └── index.js │ ├── match_params │ │ ├── index.css │ │ └── index.js │ └── modal_link │ │ └── index.js ├── home.js ├── index.css ├── index.js ├── not_found.js └── registerServiceWorker.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | /docs 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## react-router-modal-examples 2 | 3 | http://davidmfoley.github.io/react-router-modal-examples/ 4 | 5 | 6 | #### Setup 7 | 8 | 1. Clone this repo 9 | 1. `yarn install` or `npm `start` 10 | 1. `yarn start` or `npm start` 11 | 12 | #### NB 13 | 14 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router-modal-examples", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": "https://davidmfoley.github.io/react-router-modal-examples", 6 | "dependencies": { 7 | "documentation": "^4.0.0-rc.1", 8 | "gh-pages": "^1.0.0", 9 | "react": "^16.2.0", 10 | "react-dom": "^16.2.0", 11 | "react-router-dom": "^4.2.2", 12 | "react-router-modal": "1.3.0" 13 | }, 14 | "devDependencies": { 15 | "react-scripts": "1.0.7" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test --env=jsdom", 21 | "eject": "react-scripts eject", 22 | "deploy": "npm run build && gh-pages -d build" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidmfoley/react-router-modal-examples/bd7a15c1955eb19ddd3b570c0cbcc3fc99d8a8db/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | react-router-modal examples 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #ADF; 12 | padding: 10px; 13 | color: white; 14 | } 15 | 16 | .App-main { 17 | display: flex; 18 | flex-direction: row; 19 | } 20 | 21 | .App-nav { 22 | flex: 1; 23 | height: calc(100vh - 70px); 24 | background-color: #BED; 25 | } 26 | 27 | .App-nav ul li { 28 | list-style-type: none; 29 | } 30 | 31 | .App-content { 32 | flex: 3; 33 | height: calc(100vh - 70px); 34 | overflow: scroll; 35 | } 36 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; 3 | import { ModalContainer } from 'react-router-modal'; 4 | import BasicExample from './examples/basic'; 5 | import ChildrenExample from './examples/children'; 6 | import ModalLinkExample from './examples/modal_link'; 7 | import MatchParamsExample from './examples/match_params'; 8 | import Home from './home'; 9 | import NotFound from './not_found'; 10 | 11 | import './App.css'; 12 | import 'react-router-modal/css/react-router-modal.css'; 13 | 14 | class App extends Component { 15 | render() { 16 | const url = `/react-router-modal-examples`; 17 | return ( 18 |
19 | 20 |
21 |
22 |

react-router-modal

23 |
Example Usage
24 |
25 | 26 |
27 |
28 |

Examples

29 |
    30 |
  • 31 | Basic 32 |
  • 33 |
  • 34 | Children 35 |
  • 36 |
  • 37 | ModalLink 38 |
  • 39 |
  • 40 | Using match.params 41 |
  • 42 |
43 |
44 | 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
55 |
56 | 57 | 58 |
59 | 60 |
61 |
62 | ); 63 | } 64 | } 65 | 66 | export default App; 67 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /src/examples/basic/index.css: -------------------------------------------------------------------------------- 1 | .basic__modal-content { 2 | padding: 20px; 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/basic/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { ModalRoute } from 'react-router-modal'; 4 | import './index.css'; 5 | 6 | function World() { 7 | return ( 8 |
9 |

*/world

10 |

11 | This is shown for any path that ends with /world 12 |

13 |
14 | ); 15 | } 16 | 17 | function Hello({match}) { 18 | return ( 19 |
20 |

./hello

21 |

22 | This modal is shown for any path that starts with {match.url} 23 |

24 |

25 | Other modals with longer routes will appear to be stacked "on top" of this one. This is because they are rendered later in the document order. 26 |

27 | 28 |

29 | Clicking on the backdrop area will navigate to the route specified in its parentPath property. 30 |

31 | 32 | Try {match.url}/world 33 |
34 | ); 35 | } 36 | 37 | export default function BasicExample({match}) { 38 | return ( 39 |
40 |
Basic Example
41 |

42 | View Source 43 |

44 |

45 | In this example, two ModalRoutes are defined, one that matches /hello and another that matches */world. 46 |

47 |

48 | Depending on the route, either or both of the modals is shown. 49 |

50 |

51 | ./hello 52 |

53 |

54 | ./hello/world 55 |

56 |

57 | ./crazy/world 58 |

59 | 60 | 61 | 62 |
63 | ); 64 | } 65 | -------------------------------------------------------------------------------- /src/examples/children/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { Modal, ModalRoute } from 'react-router-modal'; 4 | 5 | export default class ChildrenExample extends React.Component { 6 | state = { show: false } 7 | 8 | render() { 9 | const { match } = this.props; 10 | 11 | return ( 12 |
13 |
Child elements Example
14 | 15 |

16 | View Source 17 |

18 | 19 |

20 | 21 |

22 | Navigate to ModalRoute path 23 | 24 | {this.state.show && ( 25 | this.setState({show: false})}> 26 |

Child elements

27 |

28 | You can also define modal contents as child elements. 29 |

30 |
31 | )} 32 | 33 | 34 |

ModalRoute with child elements

35 |

36 | Children work with ModalRoute as well. 37 |

38 |
39 |
40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/examples/match_params/index.css: -------------------------------------------------------------------------------- 1 | ul.match-params__user-list { 2 | list-style: none 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/match_params/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { ModalRoute } from 'react-router-modal'; 4 | import './index.css'; 5 | 6 | const UserProfile = ({match}) => ( 7 |
8 |

9 | userId: {match.params.userId} 10 |

11 |
12 | ); 13 | 14 | const Example = ({match}) => { 15 | return ( 16 |
17 |
Using match.params
18 | 19 |

20 | View Source 21 |

22 | 23 | 24 |

25 | The current route params are provided to your modal component by the match prop. 26 |

27 | 28 |

29 | For example, if we have a list of users, we may wish to show information about a particular user when clicked: 30 |

31 | 32 |
33 |
    34 |
  • 35 | User 42 36 |
  • 37 | 38 |
  • 39 | User 77 40 |
  • 41 |
42 |
43 | 44 | 45 |
46 | ); 47 | }; 48 | 49 | export default Example; 50 | -------------------------------------------------------------------------------- /src/examples/modal_link/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ModalLink } from 'react-router-modal'; 3 | 4 | function ExampleModalContent() { 5 | return ( 6 |
7 | Hello 8 |
9 | ); 10 | } 11 | export default class ModalLinkExample extends React.Component { 12 | state = { show: false } 13 | 14 | render() { 15 | const { match } = this.props; 16 | 17 | return ( 18 |
19 |
ModalLink example
20 |

21 | View Source 22 |

23 | 24 |

25 | 26 | Basic Modal Link 27 | 28 |

29 |
30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 |
5 |

react-router-modal examples

6 |
7 | ); 8 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import registerServiceWorker from './registerServiceWorker'; 5 | import './index.css'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /src/not_found.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | const NotFound = () => ( 3 |
4 |

Oops.

5 |

6 | There is nothing here. 7 |

8 |
9 | ); 10 | 11 | export default NotFound; 12 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | export default function register() { 12 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 13 | window.addEventListener('load', () => { 14 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 15 | navigator.serviceWorker 16 | .register(swUrl) 17 | .then(registration => { 18 | registration.onupdatefound = () => { 19 | const installingWorker = registration.installing; 20 | installingWorker.onstatechange = () => { 21 | if (installingWorker.state === 'installed') { 22 | if (navigator.serviceWorker.controller) { 23 | // At this point, the old content will have been purged and 24 | // the fresh content will have been added to the cache. 25 | // It's the perfect time to display a "New content is 26 | // available; please refresh." message in your web app. 27 | console.log('New content is available; please refresh.'); 28 | } else { 29 | // At this point, everything has been precached. 30 | // It's the perfect time to display a 31 | // "Content is cached for offline use." message. 32 | console.log('Content is cached for offline use.'); 33 | } 34 | } 35 | }; 36 | }; 37 | }) 38 | .catch(error => { 39 | console.error('Error during service worker registration:', error); 40 | }); 41 | }); 42 | } 43 | } 44 | 45 | export function unregister() { 46 | if ('serviceWorker' in navigator) { 47 | navigator.serviceWorker.ready.then(registration => { 48 | registration.unregister(); 49 | }); 50 | } 51 | } 52 | --------------------------------------------------------------------------------