feat: make the modal more accessible

This commit is contained in:
MAZE 2024-04-22 18:46:51 +03:30
parent 48291a6457
commit 0252fa96ab
3 changed files with 54 additions and 18 deletions

28
package-lock.json generated
View file

@ -17,6 +17,7 @@
"@types/react-dom": "^18.2.10", "@types/react-dom": "^18.2.10",
"astro": "4.0.3", "astro": "4.0.3",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"focus-trap-react": "10.2.3",
"framer-motion": "10.16.4", "framer-motion": "10.16.4",
"howler": "2.2.4", "howler": "2.2.4",
"react": "^18.2.0", "react": "^18.2.0",
@ -8243,6 +8244,28 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/focus-trap": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz",
"integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==",
"dependencies": {
"tabbable": "^6.2.0"
}
},
"node_modules/focus-trap-react": {
"version": "10.2.3",
"resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-10.2.3.tgz",
"integrity": "sha512-YXBpFu/hIeSu6NnmV2xlXzOYxuWkoOtar9jzgp3lOmjWLWY59C/b8DtDHEAV4SPU07Nd/t+nS/SBNGkhUBFmEw==",
"dependencies": {
"focus-trap": "^7.5.4",
"tabbable": "^6.2.0"
},
"peerDependencies": {
"prop-types": "^15.8.1",
"react": ">=16.3.0",
"react-dom": ">=16.3.0"
}
},
"node_modules/for-each": { "node_modules/for-each": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@ -12569,7 +12592,6 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -13434,7 +13456,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@ -13565,8 +13586,7 @@
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
"dev": true
}, },
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.14.0", "version": "0.14.0",

View file

@ -30,6 +30,7 @@
"@types/react-dom": "^18.2.10", "@types/react-dom": "^18.2.10",
"astro": "4.0.3", "astro": "4.0.3",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"focus-trap-react": "10.2.3",
"framer-motion": "10.16.4", "framer-motion": "10.16.4",
"howler": "2.2.4", "howler": "2.2.4",
"react": "^18.2.0", "react": "^18.2.0",

View file

@ -1,6 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { IoClose } from 'react-icons/io5/index'; import { IoClose } from 'react-icons/io5/index';
import FocusTrap from 'focus-trap-react';
import { Portal } from '@/components/portal'; import { Portal } from '@/components/portal';
@ -37,6 +38,18 @@ export function Modal({
} }
}, [show, lockBody]); }, [show, lockBody]);
useEffect(() => {
function keyListener(e) {
if (e.keyCode === 27) {
onClose();
}
}
document.addEventListener('keydown', keyListener);
return () => document.removeEventListener('keydown', keyListener);
});
return ( return (
<Portal> <Portal>
<AnimatePresence> <AnimatePresence>
@ -51,21 +64,23 @@ export function Modal({
onClick={onClose} onClick={onClose}
onKeyDown={onClose} onKeyDown={onClose}
/> />
<div className={styles.modal}> <FocusTrap>
<motion.div <div className={styles.modal}>
animate="show" <motion.div
className={cn(styles.content, wide && styles.wide)} animate="show"
exit="hidden" className={cn(styles.content, wide && styles.wide)}
initial="hidden" exit="hidden"
variants={variants.modal} initial="hidden"
> variants={variants.modal}
<button className={styles.close} onClick={onClose}> >
<IoClose /> <button className={styles.close} onClick={onClose}>
</button> <IoClose />
</button>
{children} {children}
</motion.div> </motion.div>
</div> </div>
</FocusTrap>
</> </>
)} )}
</AnimatePresence> </AnimatePresence>