diff --git a/components/modal/_modal.js b/components/modal/_modal.js new file mode 100644 index 0000000..1ca8d65 --- /dev/null +++ b/components/modal/_modal.js @@ -0,0 +1,110 @@ +import React, { useEffect } from 'react' +import PropTypes from 'prop-types' +import { Flex, Box } from 'rebass/styled-components' +import FocusTrap from 'focus-trap-react' + +const Modal = ({ open, onClose, bgStyles, modalStyles, children }) => { + const closeModal = () => { + if (onClose) { + onClose() + } + } + + const handleScreenLock = (modalIsOpen) => { + const { body } = document + + // TODO inline styles + if (modalIsOpen) { + body.classList.add('disable-scroll') + } else { + body.classList.remove('disable-scroll') + } + } + + const _onKeydown = (event) => { + // TODO keycode deprecated + switch (event.keyCode) { + case 27: + // Escape key + closeModal() + break + default: + break + } + } + + useEffect(() => { + // When the modal is open listen to keyboard events & lock body scroll + if (open) { + handleScreenLock(true) + document.addEventListener('keydown', _onKeydown, false) + } else { + handleScreenLock(false) + document.removeEventListener('keydown', _onKeydown, false) + } + + return () => { + handleScreenLock(false) + document.removeEventListener('keydown', _onKeydown, false) + } + }, [open]) + + // TODO add motionbox to fade in + return ( + <> + {open && ( + + + + + {children} + + + + )} + + ) +} + +Modal.propTypes = { + open: PropTypes.bool, + onClose: PropTypes.func, + bgStyles: PropTypes.object, + modalStyles: PropTypes.object, + children: PropTypes.node, +} + +export default Modal diff --git a/package-lock.json b/package-lock.json index 34648e6..c0a81db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5930,6 +5930,22 @@ "readable-stream": "^2.3.6" } }, + "focus-trap": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.0.1.tgz", + "integrity": "sha512-BOksLMPK/jlXD389jYPlZHAqiDdy9W63EBQfVIouME8s3UZsCEmq3NA53qt30S4i72sRcDjc1FHtast0TmqhRA==", + "requires": { + "tabbable": "^5.0.0" + } + }, + "focus-trap-react": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-8.0.0.tgz", + "integrity": "sha512-wWIfr2vU92YTS5MssxU93/qSKPQImqxQZiBaU6Vfh0QKczJ1C1+hszCPhhj5Pm3k1Gr+fdDlshDw3IAB7wBZXA==", + "requires": { + "focus-trap": "^6.0.1" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -11246,6 +11262,11 @@ "util.promisify": "~1.0.0" } }, + "tabbable": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.0.0.tgz", + "integrity": "sha512-+TJTMpkHRCWkMGczHHVEfzBYCsVOiBjd3vle55AT4H299BhdJDLFqcYmr7S6kt5EGhT8gAywSC5gPUBDNvtl7w==" + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", diff --git a/package.json b/package.json index a87bf0b..6bab12f 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "express-jwt": "^6.0.0", "express-paginate": "^1.0.0", "express-session": "^1.17.1", + "focus-trap-react": "^8.0.0", "framer-motion": "^1.11.0", "next": "^9.4.0", "next-cookies": "^2.0.3", diff --git a/pages/page.js b/pages/page.js index 682c7c9..e3118fb 100644 --- a/pages/page.js +++ b/pages/page.js @@ -1,12 +1,16 @@ +import { useState } from 'react' import PropTypes from 'prop-types' import Link from 'next/link' import { Box, Heading, Text } from 'rebass/styled-components' import { MotionBox } from '../components/motion-box' // import Prismic from 'prismic-javascript' // import { query } from '../utils/prismic' +import Modal from '../components/modal/_modal' const Page = ({ data = {} }) => { const { results } = data + const [isModalOpen, setIsModalOpen] = useState(false) + return ( { About - Getting started with Next Base: - - This is a starter kit for projects that wish to utilize Prismic, NextJS, and Express. Below are the - instructions for getting this base setup correctly: - -
    -
  1. Create or login to your Prismic repo
  2. -
  3. Go to settings and get or generate your API key
  4. -
  5. - Copy the env.sample file and rename it to ".env", and place it in the root of this project: -
      -
    • Add your prismic key there: PRISMIC_ACCESS_TOKEN=MY_KEY_HERE
    • -
    • (optional) Add a username: USERNAME=my_username
    • -
    • (optional) Add a password: PASSWORD=my_password
    • -
    -
  6. + ADA MODAL + + { + setIsModalOpen(true) + }}> + OPEN MODAL + + -
  7. - Go to /constants/prismic.js and update the PRISMIC_API_URL information there to point to your - Prismic repo -
  8. -
  9. Go to /constants/metadata.js and update the DEFAULT_METADATA there
  10. -
  11. Go to /constants/analytics.js and update your GA_TRACKING_ID
  12. -
  13. Update the /public/manifest.json so your app can be accessed offline
  14. -
  15. - Uncomment this getInitialProps function in this file and update as necessary to get data for your - project. Remember to also uncomment the appropriate imports too -
  16. -
  17. - If connected successfully, you will see data below. Then feel free to remove these instructions and - any code that you don’t need (hopefully there’s not too much of that) -
  18. -
- {JSON.stringify(results, null, 2)} + { + setIsModalOpen(false) + }}> + { + setIsModalOpen(false) + }}> + CLOSE + + THIS IS A MODAL +
) }