{"_id":"react-modal-global","_rev":"91-812999c590e0fe2ad56c5a98cd8fe1da","name":"react-modal-global","dist-tags":{"experimental":"0.0.0-experimental-2023-03-12","latest":"2.3.7"},"versions":{"0.9.0":{"name":"react-modal-global","version":"0.9.0","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-plugin-popup.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-plugin-popup/issues"},"homepage":"https://github.com/FrameMuse/react-plugin-popup#readme","gitHead":"724ebfea2a8a0448fe039b1103a9bec829faa3ec","_id":"react-modal-global@0.9.0","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-9YH7diJwFJ26hpZiskI6kSbBRPRH100rlOPXDfUoECUwqWKFGF98jL13bkcIzPwGdIiMdPxwVN2AVDs2w2WiCQ==","shasum":"042dbe87b6c233854f05bbab86cc9110189ddecf","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.0.tgz","fileCount":4,"unpackedSize":10842,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqx0AzktcLE2qj2Jc6r18HNZHz8nniHzHy56/3pzmWXAIgEnP8VZ0RvCVDEcZKBCUIQBRaRFw4zySYq+ywuP2JAAE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2ZoIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp6/Q/9E5gyesb4urASpJbYfrphT+MSe8r2cBwWhFM26/SGFeciyAL8\r\np6JJfdwJbov5jSwRpbq/UOTGyrtYSDknW+6S8Kgu8itA2dcNOeQ2NfoHGSQJ\r\nuDsQi5A7E1ejUQgIEsye7QKHIJZpp2B1UQ3LEv77X49F8Wjv+d7wCGibU9hj\r\nR3km3rShwbE4FWqdFMbD1F5YQky9hAx7YX2WPttpG6aPa81p0vbtzJaXvYNF\r\n/LUMtUiutwdWMnwtJziZZY+pM8lp1sE/32SGOmZXwhLUj2LFYn5V/4qlm4UZ\r\n0gmzXF8eYTT404Nz2Ewp/VRZBTvenEFXibSqzgvucSPaLc20gVewYPDFyAol\r\nBW0b9MgamqbJq7hKKSCkcqGdUVdPBk24umDGwrBGTI7affYid9ScKKwXmy7y\r\nXrnmmC3R5kFX7evCo8z5QEpLUO4ZIaeDqEX0UDBw2u0i8Q1WP8eiXAQecmkf\r\nMgL3dJyu3biIWDxlu475s/sKvzlcJetV1gt5dmPzFj0klOEiczBlm1Hesbux\r\nMdwacdM+DMKfy5vHd3Xu96/aApDwokOCWYEPrWqcN1CUOpDal0ILAn2+qf0R\r\nqQvII4iBM3dANYiNcBvxSLFRmNVoHuATHYSKsMyFS1Em77LPGr48SEcY7ke4\r\nrbBzTZgRflfcyt01y6PcSG391LEElv40uxs=\r\n=DEur\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.0_1658427912239_0.7237179489221146"},"_hasShrinkwrap":false},"0.9.1":{"name":"react-modal-global","version":"0.9.1","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-plugin-popup.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-plugin-popup/issues"},"homepage":"https://github.com/FrameMuse/react-plugin-popup#readme","gitHead":"72eb1cc97b162ce5ce452a428a37de3a21e8336e","_id":"react-modal-global@0.9.1","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-6FjD+Xw/Zn6Pv4fV0O1KC94mGarM5LQWvqU1yA4XUjvvIbx4azheZ2cwO1cImNF4RzBaj4EvE4MklCgd7tX0dg==","shasum":"71e91e07fd163d76ec3f546ef7dc2fbd35c4baf7","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.1.tgz","fileCount":5,"unpackedSize":12934,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF/nDZHI1i48ZWyStckXMATpAAuygP71DUbfFDa906bfAiEAxzFqQ4SftrJPZSlaa2hH6rrrTufhUxVI+mOqDtYaHGA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2ZqdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrH5BAAhPoTM3EfH/WhuhVVmVzEURvYHerTWz88WGCFKmvvpmWfOG4U\r\nG2TQp2PrF7bylcwJGz32G57smb3EDY6zur1WJ6jREqpBrs2xuEHimzKZdk6s\r\nj1Kucm4Tk4LEfw+fMLnE5AgH4SDCm31SLNIYM7AU2N3oQCxOL+Aw/2IOrRE+\r\nv9otKJxYPsng5h4qpAoTfur4ufpuFTvPO2a1xyi7rHD4vtdeRVVcfUBCiTsZ\r\ndtJnGvHyWsHMc3oO7wD7ytdrWnwUKM4/kVnyDjeMWrsfVyZrTQhApwdJPB47\r\n/Seu78xY/o75q3sg2CIOGzL5O0nBxIhOc+xYJo2wBh6JKsxW2qLqoBCjoepV\r\nDn5vD8mRpwKowSTsqCyzyZHjcJGWKHXizxLfXSCHkwXUxPej/M141SxPJn5t\r\nibqLdN9gxao1FJ1tl4XkHGCgAatP1FakkAFx38a8Ac2QvDaoqzEKtwk5Xfme\r\nIX+h4D5Go5HwxR0lYuVVivcVuxWO3wjEfgD2G8WeGN6vSH0dN8pV4/Q6ULbx\r\nv+02dzRJMdx+K2fqSnHtWAdc27WNzaRXslqCv23kAkK1cEgD5p75XpOKRjAx\r\niHmAuVvVQlqJI8C5IUQz4odKIXY7tE+Y9QHntlYHk+FoHHjVVdguq01RXjY0\r\nui6M2tWUu0e6X6LRmYVL/AKCTJTdAb4zqEc=\r\n=NSKq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.1_1658428060792_0.08533290618440414"},"_hasShrinkwrap":false},"0.9.2":{"name":"react-modal-global","version":"0.9.2","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"92e09bd7ba764214a496e0967897c998707dd2ad","_id":"react-modal-global@0.9.2","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-f5dRgGiIGkmzFEGe/WAyNjPJhUkLIyHtbmgNiVMDWSrOP0pO/DD2Wx4fzhE5p/XVEjPuM83eiquWd8hu/J9hJg==","shasum":"c25fb89560274a62ad4d43d000440177ae625c37","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.2.tgz","fileCount":5,"unpackedSize":12934,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF/BU7cBawYf7QuELyHWFaICN8pnxiRTe+OL3ZmTxlndAiBGEoqfiXvlA4UEL06LCRksfQ7VcwUAfFaTGAFoPY4cCg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2ZuQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoA2w//VXDbv9dv5dj1YCbHyGwcLQOVvlmsAmGLbeY5vLxD7CscoB39\r\nUtS88UFvvHk1n1sZAtpfOJfVlJmgaqTzsSGzt0yiYwPh48huAYSJScTsyCr1\r\nHWi1+6ZVEtU2Lj/14P7+qQ43OEjGnUjG+Z5j/gLyl7OsGuCsjVjlEYcFAnXM\r\nRlAjcWLfFfvTEZvFQKArN8dz84FuOemdCEP1GaaopbEJ26K9Ci9VZfFOtPSG\r\nqGKcNBqMZdlIxHE4+ZHWnFygi5nK8lAGuwyAJZyO+sx+rdFr/azprgdBPVaH\r\nrnCPDL1j+3zuyspUeNjEd+bR+IA6BA3CMcHm89mlAoFlT4o6vvi+IU6wWSTk\r\nXMC3Ns9dyHkBMJK5t1dGRk+KRIfounv2jvhSd1e6lh1l90fThh5ULU1zeTPF\r\n553mRpZvQNSsHd8ZvjI4DvPh+wn8aS2g58sfhNAEgC4FllbeVevRUyrZhKH0\r\n2CnHVM4eKYnOp5n6asKhTz9U4M04HBZWZwy/20RicUNRWewFvTVJ9oY5OQZj\r\nbCic4a1FZWaDO3dPtdBaKOzjZwaa5V2iNMKUPaydG8L3KmKwcRCkRrAmRVTA\r\n6m1e/OEP18aH3xiC82Ge2Ur+SQuvxaXz05K/MX28B+jZN16LgRMIZCiDLk8V\r\n6rSMFCRh5MSaBlcMYWONaJa40Lz9kVdrZ6Y=\r\n=GylZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.2_1658428304049_0.26813341371917"},"_hasShrinkwrap":false},"0.9.3":{"name":"react-modal-global","version":"0.9.3","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"14d191920c30a212ba19e5cdab5e3d72ae97fda4","_id":"react-modal-global@0.9.3","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-kMPLjn50EayMGj/7pJnd4zUWFdDXJGfN5qRJDFezyTVJozT7GKJ0mSU5tnKFx/Sz+s3iIY0hsCgvF8npZryJWw==","shasum":"74ed5c7a445bde94436f7bfaf2ef3a8af584a599","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.3.tgz","fileCount":5,"unpackedSize":13341,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiROQjLiBuaojt6uUlXT78R6wRuJCcKvFBauaWVbFDtwIhAMoN9sjfK+YzaKlJixprLs5GipZMJxjQ7nHPK7g5oW7v"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2Z9OACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWPA/9GaWIb/38g70IuDXnaEwwq9E2145isQkhLIMrlsG7KOymBwc2\r\nQn7SZff8VXR4KnCw7IZvYBrXn+mC4VLyCJLRNpqOk1cjNpoGPTiHVbD27iwG\r\nD4Mo8TsMzgIc8FbY0GRXhvYpWimrChWZYfuI4sFEaCjZl+laRlkM3/F2bQP3\r\nba/Jog9URZJl/gwlDz2ZdzPBhywDEVg90ZLfrYqVlqEXYSS7+sWqhnV8Drvm\r\nW7nUyCBFzPVc3IAB/EB+/T1EZqXSjlEP+vcgKwbOngmg/UE4F7JngfjNXIuY\r\n2ErAOxof5PdgCWKGMqfup4a94FhNfyKDuXteZREqP1uFfSS2uSjxe/S/DxMH\r\nh7N+oiPWzAQZNy57d/8xL9UVpe5hu1erTmPpfgkqYlFXCf60d6OFm/v8Kb+O\r\n2yA249iaZm1npn9JW5p34+0LzsPbdLnaiVh3UIUsVkHg5AE+X7wX47/OnsjB\r\n8dpTG972AwCh5/X7ddcUjTDMr9qdbKaN23BOnHypUldEE+0/mIu/okPK4Co0\r\nwcEZZp+g9lDcVoWvuf0AXmwyIMCiiq1exElIyoxLC9OkehurFXBiPvHAIsjp\r\n+hZkp0eW+ir8U/Oq7k2RZVneK7ETVqimKuvkzzZYN58N3kesCUBfHxdMk1Jh\r\naP3k9JLoFAYsoLjfs+UlxCN90dniJzbpYEU=\r\n=2MrH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.3_1658429262767_0.3228289025769613"},"_hasShrinkwrap":false},"0.9.4":{"name":"react-modal-global","version":"0.9.4","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"8289f44018dda14bf7f0db63d974ab0450cb4a37","_id":"react-modal-global@0.9.4","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-jAKbcvMSIYATMKKiEkKK5X+kakxfqabNTbnoKhykuyfWVxZXd+C2+IobNd+1WyeXY6vMpcJ7eHFiN13/b9NsnQ==","shasum":"0f6815535a93b102b8595fcfc3e45e04e7a0afec","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.4.tgz","fileCount":5,"unpackedSize":13453,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICOicW5Wh4z3OZ4W0RCuEpg5OJwSY5ykdX38x+JhHY2RAiEA9Y6D2gpTRmnTasDI35ql7AKG8geoGaLYpoxuO8SWtl8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2aBXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr9vRAAhdLd6Zyi+PHVjTDfh44rwsurWiNmY6g0Xw7+Jr3CVu3I8XTq\r\nCWRB5XbJa19mq0OdGBhMK5hoQFQ61vMpW2DpJOrQK1Hu+tqVmNqwbrnkV/9P\r\n2JNSG61JlWy3OlFoIXvMkwSlykXmC6PpCt/0qXBH1TSYs9kzOy7mn0m2mv3g\r\nntFcvx9xtGVTGzO977docyHOLQl98xNyU0lWhGB+55PohlJgoghBeopHsJ+9\r\nQ7Ma9++fHOvv/lBy5L9F2CUKGSah0SKyPW1EOySycx2ja/MJDbmfkP6/1EWI\r\ndBi/dNQwSlGma+uChInGNAvtE1LqBtNQ50WVKs2UNLd9xFCq2QqUzcrPaum8\r\nL6YkdTX3hkd4zHRHE0xoYpxzBFH4LWPN2Zmq2ziSFOsFv1Q5A1nQIuLcpTsZ\r\nXuLqpDAIMrZqezlXtw+YKNX4K5vmCpQWeiZycPedHSusnk91I31kCoMIYKOp\r\nRMsFd/BYU0X/yCYc2i2lkrQJac+8xERGG42Kk2qJgbfTWQdLmxhfbf0AtBqw\r\n5xOar5j2t5PJIKIw0Ij6c4CwiqFziIRUzQ2Hyyn+y/rCPNTBivFRxRR21HBJ\r\nzD4kEf8l/LxLNOsBSujkVnKUnSCQN2pOSzcdP0zOO8aDA/oamhtyxsfmSwOO\r\nkmHs/tpxIFM/lhhRZY4OpG7/MtQIp590agw=\r\n=dziY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.4_1658429527447_0.34489046711901894"},"_hasShrinkwrap":false},"0.9.5":{"name":"react-modal-global","version":"0.9.5","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"13643804536aa8b464860835e19eae88f1b43448","_id":"react-modal-global@0.9.5","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-353nIrAL8UifSvthJUORV4CBLmo1boXkXC1380JFn2wKw9VzoSt9hgcoGHmRyhW69LWmYn9CMr+4RiYZu4b0qg==","shasum":"7dc2f25af1da19703e2e1caf34c7508ab93b7c0a","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.5.tgz","fileCount":6,"unpackedSize":14524,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCaYAL+g11EpqJGBoFOABHleFWjRHb6xZy5GD3iBLoe8QIhAP+2msLbkGrRZ1bijpSUiq/Oe9kkMboJIZFwp+OSc4qA"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2aQVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp6EQ//U6ko3yv6Y5BttaOy0+iQVa5yDvC07ij4Ez6BaevL6Nfg0yZ4\r\nFP70XmE/Tt7EkY/UIc7b270O0nuOG3eZDBHVbW+1XP781Rj7uQp7+x23pdJr\r\npt2XFRiLnCS7Mc30zZBeQUrNPvU46a1L0uv3RfwbhVGGPiGFhh5ENdw0IFUT\r\nNdghAAX8ON9yi8Hr1eDlK/im1B/j8F3OC37uszY5VK/QDEKhr0I4uZ4YWGMe\r\nr03La0wY/P9VujVaFmWa2rZBxz3wITBEf/wfLBq5dviEERsaGhUjt7lTMJkm\r\nxq7ogGJrw6O1fa1ayLoHqfQhGZ0g8RgxfVviTfjXGckYS5Bceu98M9vzp9tx\r\n5qdEriUZYhkNJYH+IC4RJT9iswupFUfULRXjrPvoCrKIDphUbwht2R/dchK/\r\nlsF9keWV2M0T+lNbscAS3X7bBeR6ix5wdx1iahT03iJzGW6isslYaJfE1/MT\r\nDhZmhJ+gjJgaOzB9rgyHUtgprQ3FUTi0+VgdefAKlPjpKaoAzTrP/V1b7Dup\r\nuCysKuDZp+RbZgUHFpsSxzJyku/96w4AkmsuHJS6+6U43B/SROR99hAKPxfn\r\nDv3vPqP9Me4WnaCW317j5UYayRlmIzbaybd7imh+V308acj/saBFPKbSem7O\r\nJxt09uJZit6iw43QxbQe0/IKhKu87za0I1s=\r\n=3eeh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.5_1658430484810_0.7618512434635232"},"_hasShrinkwrap":false},"0.9.6":{"name":"react-modal-global","version":"0.9.6","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"d535868d6788a6ceb20eaf86338b7aafb848b7d5","_id":"react-modal-global@0.9.6","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-DbHSr78iltEK920F1Q4BM50lSxPHrll/kPkHsfMjuRa3ZvL+1aEp0Hpm/IHcc/U6+/zP27DjCspBtiSrSWjf6Q==","shasum":"f7c86833916ebaf3a6defdf171e065abf6f91fc6","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.6.tgz","fileCount":6,"unpackedSize":14524,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHoHSGA6lvmzD1N5Z+HE/hDNSM01EzYuo/4sZy8kixcRAiA2tN+qeC7+hH7gNFMWwjvCkbtZ81d9NFhMRG4MaheWQQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2aWXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq+Mw/+JpkH2dyxVtzlhjNJQXfG4bBmdBYCIiU9emVHJBf+7lpwq3qp\r\nO+FMqP0Gnbg+frkrY4VS4gPqhw2KdvgA7jmfg2FfLpO0fFrC+XAcjLVt2GjA\r\nrNiF+CZLzNhcW+IqP4yZ4oGFV/d3/ZuyL2GcUSuxDWeZm4WehJUL4AM+koBE\r\nnIjZ4DAY/0nEVZiPtu/sZKC/JTxnW/7mfeH2LWsDbu1nh0NeHHhn5prpN8MN\r\nHVCZXtMh4YNf52G/yl59y+Of7YNo8YklnaoMMwleEPaXCEv1i2kFxCKsw1Oj\r\n/yPNkjVnpS/UEhBEf463o376ltM+5npXK1CGCUSz3Vmwq4n2TS6LM/Fy5aqp\r\nbwf0EYCy49B34d4+aMd3lqr1EGZyra0nyOGH2NRkMqnk7YUHCLwZ00QhVsF5\r\neTnrY/MMAj8j9FZYFILWSd0EZotdEIZMbvRHYrZUNUGEKbM4gLnyX65AKkqI\r\nc3g0cU1KXDxIGwyUBDlv7IxbeA0y4EMLWvYJqaFchvA3pmUaVOlgimTGXa5u\r\nBDuC9zB1115LipN0+AD6enNl8T8s29oBgKUe1vKf+0Lcv8yd+hPN+WiaXN6P\r\nqw3JAPJfLtwJj9YZxklB7du90zpui+gXcuS6x18+YZ9ZTgAjgbC/ubuToaMD\r\nXtsmjywA8RV+kPzuTAQDfMgQiZ6h8vyGIBo=\r\n=9Eud\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.6_1658430871123_0.0852171327290776"},"_hasShrinkwrap":false},"0.9.7":{"name":"react-modal-global","version":"0.9.7","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"acbd2e09e6003a349077546997aec293d451b2c7","_id":"react-modal-global@0.9.7","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-eq+Qz9jr/bXRuIpVdrSc1bNwFTNwLw07Elj74V1rfb5MR34Qt2Ja12R43QxSSRo6Vap3iSWNuMMHpV+704qBYA==","shasum":"048a707d00adabda0e0dea08bc9cc2e726b1308d","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.7.tgz","fileCount":6,"unpackedSize":14529,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDVEeSX3OSeUONLqGUQ31INOM+SRHA+vqPPzX0Th/kukAIgD9JUk8jOtq5Cav2IqG/7lrHkJh/Hg3m1/Rj2DaNHXFo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2aZHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqq6hAAkmPkGUgCp6lfJfbEFCV/4xt+8Hg8go8UZDThlvI3gK61XsJE\r\njgHC37knXBM0LMnNNrnTWn60ZFl/plqDQEvwehZteu2aQxp1+eNSmPM5hBgX\r\nD9TZrAuXw/FR1/jqiKXD409yc1oJk9bVIyIFK3X2W88eOFDtbfQ+6XkbdfdW\r\ntcp35Ms5cz9XListSx1AKLnEVuZ0fNOkGpVS9VYU72OcTvXZ74ClI/SPn04Q\r\nac3TiygYJVpdGae0r0QSer1bqt6fiambLheUIY8blgzQEPq7qB3zQTFSdqCP\r\nslxOuzbgjVKGPtWpZQcjXc1sM3hSI3sAk6+Ly3giVHoFxSvJovg/5AGfh5jJ\r\nTXckacF4OC8QzKWQ4hj/WWMbe5KB5I1r4huBH3KBH6Qs2BUBQw1+KcR7+oI1\r\nsaSVsVWUFAlYMhbAUH5fPD8y7s0YGxkQfaAxBELG9QwfVz0cBttHQuX6zYTi\r\ncQKUJpNoXWqvT1ufm55tbip+Nw/w0Ol8YR7v4Kfki/Swc0FL8aO1NEeIV3Ch\r\ntO3/ltqbfWHDgvjiU1rtbExx4ppnbGSnSPBWQ6dOZ1PDIoHy1gezZrFK/+/D\r\ncQOP0U88AjB0knc85qZouBhSGRZZU6if1j/rolygcgzJPjlGBpeVBTQAZGV4\r\np8UU2B9Av9lmyFRbWi16zOdpwCXAA9bbQ+4=\r\n=fFnn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.7_1658431046999_0.4181675078005338"},"_hasShrinkwrap":false},"0.9.8":{"name":"react-modal-global","version":"0.9.8","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"fe82e58186b48537e1da8e4fd7432e9df78eb8f3","_id":"react-modal-global@0.9.8","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-aD4tjF1yKseuKRw26SaUgcVNEfWj30l45u2yW8lJ0sBhd6aWJqzUtHzOzId5hDJuB8qwytuy0ydnpclsxBvilA==","shasum":"a292125ac9a5e6ac2189aba7505fd173138cd643","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.8.tgz","fileCount":6,"unpackedSize":14529,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD5Be3NEuM0v9sq9TwcrNXZ1U3GAYNBp1KJ+4qCzLXw5wIgYdreCu6QtwRJpiCxwXFpoJB7ekao0IzJ5JPBZABB7s4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2aZkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr5sw//eCyA08t/SCEQLlwMZK+sw0ndN0iipYvi8PoLqpZiXyWvuSEU\r\nGiRTuBPuZwKCXOow5aeenogHmZ86lcqoQHExZ12k0w6qIHsXYw8XxCob5L1a\r\nmAGZ9jYRMsqa9Sa7sI1OVj8qfMOQsZ2N0Qv3Yek2uQ0/+tccpii2ZR70UN/N\r\nFfHiaKcflUpEZHZNt5bzHxY8xq81UUOq9ZE9e/8UkTxv19pPP6zpJASvSE0I\r\nZVNxwLe2n/STReoc9GKColh1QXSXqFg0b/BzUxBTkcAM7WaU7crjome0YdGx\r\nS5F6R8D7tsSutTHsJ5121UlpEQRClChW9BIUBuHeATNR3i7F0tC8Gro4pjag\r\nnmfHmsgtBP93LG+EUt9eyTr0SjXeI3716FlK63LOoZRCLTHiCm8Zbz8kRQo8\r\n5oESZ10N1NcFnBJiAOr7yxeUM61bAbqpPrzoJwzElfzrazQnvVHDg7muQK8L\r\n1TtJaWhc5xD0U/UcECOx9qnXvlEYLudcYkgGrDEM5YOB1ekI+uEr9xotsAPP\r\nnBUgVG6Ng55T5kIcRJmmFKUlncVWD8n5pT24Um5sy5OhDdXp37ZIcu+/YBnM\r\nbUrbmovdi3taPML7/Jv6p74oE/EnAsZumW6gOT96gSZ0EdgNw1Kii5hoi6Ee\r\nyCU+j1USFIfbPGnXQVPBWQps+pwIhefgtLY=\r\n=A7/O\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.8_1658431075938_0.2458813434184195"},"_hasShrinkwrap":false},"0.9.9":{"name":"react-modal-global","version":"0.9.9","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"77de5e2ffd22c7d5e5e072ce9671cff896fd56b1","_id":"react-modal-global@0.9.9","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-wIRoevht4s0ZytMm5tGtgiJWszonmairjODUg+Q9fpV2tD/JyioOrMMPlpXd4xi+yNXbBD2DWM8VAm4GQkbJXw==","shasum":"7ca6276ca4f1dd48081fa9285bc1e42111cdcae5","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.9.tgz","fileCount":6,"unpackedSize":15936,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICmND2izi033LgY7znIjM6BPECa/Ph258le8pJ3KL1ikAiAGtLvNXyDXFhvG5KQoUNamVIp4wT4CqBCpxDXxvcpxbg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2nfkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrguQ/9EIBfkCI+LbmB4uZbHvRqX3sIfIF4mXpeGC+QbhURTuv2Hu43\r\nQy8GRo9HRJ0weANJoMJ/S8aYBokX9BxxyUbUB6u/7PfiOLLt52gUo/Jqjzzi\r\n3OE7iXjZYqGesXzDKYQ55cvGvjEhme/Zg1ATK+xps6dIn1tTXiZkNQ3xNzuP\r\nlCODb9LfKbzMhfXlUPjos3LacyeNhDzLT6JPOaVm7hRudaS/dKRuO9d0LdLO\r\nuDIIOrArC24C7hNxDBNsZf2TlWZ6MIFdgFC4si/wsNoj99pPyZrQWXpcgy5Y\r\nneIlJ92MCrx7fG1nyMtwWHVtXi+tC43eIbGgimUKb8lXW2BOj/vibuzzVlGE\r\nsnv6NVNoSe1JUDzz3qoKnxL35M6PN+zZm8UDAFmndHXN2y2Bdk5o14rVGD5E\r\nkZV+FaZcbESUJbk8PSVTYPOoUqjaeKJNm5y/b0qXuH/CKBx3S/a8SjGwOmJU\r\nTQce9P/vqqxthaC5LB7+28PyOxVKu99aQXCZLw7U7bTfQqJGzsOMvfgh2Yxn\r\nQBQVEOkU/ExACZYWW/YfRXASp4q+eXethax6FeVtL8Nh/a3N1roaMqeY1iLF\r\nDe6QwL8M2p1mvpqGnG07NWqZzx6eQqrFW39VEwjTu1uwXNuC36GKTvWRYSey\r\nPfJXeCY/pii3eMVGKfVyTUJRa/oxyNXk9Vw=\r\n=30la\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.9_1658484708271_0.8164901493277439"},"_hasShrinkwrap":false},"0.9.10":{"name":"react-modal-global","version":"0.9.10","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"621738ee3d4bc957c7004b4c3b482387adb54f82","_id":"react-modal-global@0.9.10","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-B8b5XAfFberRlrrpvgCTJWoE41BW+OkxTWV/4Cjtte2SLQ6slVD/hlDhkmKQPVPgT2De+VgxVqGthPwjvoAy3A==","shasum":"ff8eacf1968bb5678f4a2dba7f7e9f24ab8b7461","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.10.tgz","fileCount":6,"unpackedSize":15942,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+lge8Irf/s7Zv3ri74DWVJkISQgdTHiBDZ1vpESK43AIgT0K5DeUza7DnV4eVOXxtCK4f/daPqUlHxFVwMQPHOTU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3AC+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrEsg//UYmRPWJ1wTR4g/I048/eW4xZoCkDC/J/uKikDwnewTj0Uya4\r\npc06O3kkdT2tgj8ket8mPCLAxyqHhOrT4iCAWFCXaDfSJ5ojN7L1U2ZT2K/m\r\nq6poGOMoZSXmVvgemrYoxL5eb4ifOm0VBMbVKv07Fk8mWdE3bBt54qjnjmQ6\r\noJ3ztU6UB89B0n5BxXkNOMnBjwDyEC+KYQjlJG3yyEJXA0m3LnHIJSZ/hgBx\r\n+F74feuptih0Ooxw1ekfQtWcnCZ/ftwx4EM7Uu80PVsMZ2EwtWl8RgjDQZT9\r\nMg80n5I64eoUkCO3te+pp3eyB7ohSfPst1TuQaB45xBNMh9R6sign1vlNSFT\r\nWJzcSg1id6mW7m5c8IO3NY43P36Jhm9UrGOps/GWg/jYkuOZVDcjmnS2ApWx\r\nAQpqbEedneHoEtCdoA1fXHuXpKChFjzZ3gsQJ+uZqPLNptCgw5BxBRGDpyoA\r\nehRKlUoHDMAdJSnHOFM0nmSQuQMkZ+VxSZPiwbxz/XDzdWHozDaiBnS4O681\r\ng6meAsxT7Kv1bxX+C7cg+91PKAW53RoHIMwTqOgey0tiHZi+xCZbnwpyW0UM\r\np729PrAPe4RemZCNSbpEv3HZX/vYdR/6JxJmAXgRxOsowG31aYB+nRNDyLD/\r\nQJEzTEz8atjxqetvjHrl8sM14Rhh7KB8gnY=\r\n=5jVR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.10_1658585277804_0.20676437591718777"},"_hasShrinkwrap":false},"0.9.11":{"name":"react-modal-global","version":"0.9.11","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"1c91c48e35436fab41f92d44934b2568dba21355","_id":"react-modal-global@0.9.11","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-aaXZyNaELpouHV88dcnSQAc+dfut4pl1BYpENokPH46Pv2ROGG6Hpp44WmQ8EYu8XuDWSmBzyhhgpVlfzsMjjg==","shasum":"d400159365050c6e1d5c2bb2ead639b8ef223836","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.11.tgz","fileCount":6,"unpackedSize":15936,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICDQVk9d3xzcQVEmdAh6MupZZvTPj9ZohptHn/MCqAMiAiAgHhrMn6kb9g6wGeAFTc4+qmTqHRhS9xIHtwGiJekwzQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3AE0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpxdQ//TZIeJhO8kr6inUFHKJ/fwBB7aTmFL1peRfWa8yn9e/TIpxR1\r\nI/jEv6M48ZWqFyoRdcVaqN4ER4+l72wEJqAIUb0yiIvWb0c833T+J8QCaBPj\r\nq7krPHBKe2mtay8GewnZ5porUzGxfvyqOUY86YQXCgVDmEGcGhq1qWIGC327\r\nW1haEMWLGtZnPMfVR25J15U1i8/N6lcPMrWY0KgnlXsYJcr2uWDuUACR9k+9\r\nCsECpUhw/Ok6nKxuO+4KFabk1SkvJVPCCv9SOkBPTrO5fvdBgxxRO61lpzTg\r\nWf6G7MzBDXnkM7Cn1VEx9Muv+5779jJx+hcKoh3y7HbxnU7mtDTot62hoLgN\r\nyNB9Yvj6psdRqp/EjB0xSFkgQ9+axORSeYTu1Ch7S+x1d2WwZCh1hXAt2SeF\r\nCvU2OwG2MMccJT+h24j+vDlawuAy/bYupfs2vH7jwo9HI2GP15ShI8pUHoVM\r\nzHkueyj6IY9vsRyfVlC7O4c4TiUFHinoeg614/moRfutF9BAkjD/rebuVD+K\r\nn5sGZ0OBm5ton6sBvp5CRhYU226zKK3Y+Od0Ezo1A1o4w9SdQ3l0KrX+MdoF\r\nJZY5pF8Vs0ATuPfyagt5P4pY/xpFUTerRoiFb6CF7I8RqbuyMQIkQVxiQS3b\r\nLVtPWisBk9U4UKjT7iZ9MiFbb+ENRAODfKk=\r\n=hvQ6\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.11_1658585396656_0.9052878136575131"},"_hasShrinkwrap":false},"0.9.12":{"name":"react-modal-global","version":"0.9.12","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"6f9536eccc6efdb61a69f15ce1d48ddc1ad0fc69","_id":"react-modal-global@0.9.12","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-aOreu+9ebvNWfxYDhhTcs6e7sZMSUTzNUSxYM0kF+ezDTkqHtPIL22KKfchvLarmObItzgx8O/hLbmgg7tQ1iA==","shasum":"8d74f417c9841a9a5e19ae189293163885f5797e","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.12.tgz","fileCount":6,"unpackedSize":15938,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF5M8aGPYb2DKVrm4vHNZZLV926syTaqpjbhhXokuj4+AiAnuIbPoiTZCNeV/NKU8clGj6zzQzavp9kkU80wnfWn5w=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3AGUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWPBAAhGtVHVVlRAYHxxfSTz5Ic6A5VWNcGFE1cTviCKQSan8CZBva\r\nCzOumNM80BNrx1cLUMQZmYbunCUrOzM8aUZpbEgKMFJN28uEv5SaF6u7rMIW\r\nhmdJPwfveiriWXV69sesW/dXnvEaO22wNtxWuphoFDMbOAtMwvzQiRTFLeLW\r\nWu3TWh+lqkngPkzCvLYzzwKwycMbijKTyzqrbo4OD1C4sRgAZJJD2azkkM7i\r\nl+m93vRVTE8XyaPh+yJtKx2K67NLBezd54vSuPCkLeDx5bU/Dxqtm4OMJ+4i\r\n/kpxF/vNnvIgp9fxvZCLZZ/Ll3/MLHZHPkkMXq7AMIcVEvCWuyu2tFKvPA7k\r\nScUA7h+jCVtJcTpcp6Z8IAlOPl1UJlclMSlNIgOwfQP5N3b8Q3mF8x0tnENj\r\nrM5HL/bjOO3GqWomuKtvIDURZwid+d4AquSRBEZHS3LPTirOjmUYQT5WTOQn\r\n049evHNIaWsU38WbC61r+O0hHsDVf56oHLzhrt78v2zWnju5wWBxjOh+taP+\r\nTLdWhaowvVn9UWAUZ33nr4fDyfrXu/gfeqmHwb1F21kSuL5XVfhxVAP9Gpez\r\nnKHvpJ08rYBHaFRZrNqzxZY4T6eWoD5mfkl7utY/9T5VMMRWkaSjQqT4YJBt\r\nbi2tRyj6QpIM09JVurCAELYwYbYtjrqRX8M=\r\n=6jja\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.12_1658585491899_0.22794509102219607"},"_hasShrinkwrap":false},"0.9.13":{"name":"react-modal-global","version":"0.9.13","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"26979eccb4cc9759b7beba56ed88b7a8ec0b8bd9","_id":"react-modal-global@0.9.13","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-EDS1uch4AgKuofKGUlVGQky1OQrcuz9FkJjc1L2fKPZRkwvpBVSc9qlh7V58qORhRuVF1XVu2+80gJ0HoFiAVA==","shasum":"fcf72e24081c7053e88e95f9ba740b93d6948362","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.13.tgz","fileCount":6,"unpackedSize":15938,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCY2o7fZJzoBkdjedFkvc1jbOs3ihdmSnXKrPiKIExr8gIhAMZeFJJbvoRjv0ELyXBPuL0RowNORSn91N9gP0fOZ7yW"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3AT8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq3CA/8CAUtYnxurdoGOjQBSU6ho7GjRgrnO3pcij+Yili3VELs87nU\r\nyfM5Rx6KfYdBwj0hYXlbCg2MWYPgS9qjgPN9QXtCBSoLN81nacozvY70HPbb\r\nAgTALVMh6Zd6C+mSUcCbqak+6nwzO1gGIK1YYV0b39vFCkWdf9ozV3mNyW4W\r\npoo/s+o79bkg3nKKB5Q442ifgYmnMZeDKnfggAjdRDjhyRHX6+9LN7OLJuB3\r\n5C6B9NczfyNX7KZxPOAhQ+BT7sU3MET+qlouXzxR0aa9dCUJKoIPUgvV2Y6K\r\nGcB6iqpj+lzn/srAlWlTOeTQWxCJsPp/Kkcz74k+/fXLbtanD224OrFeW4bR\r\ndWVipOevTYkw71I5w8upHkCfdodcPkmjyEqHq+1+sEt72RG1F7UkIJrMk36p\r\nRDnppDa62hmmIZ0+Hb2YNwQsVTe1T+L5ZN0oWjSDi9pMebwU3En75RMZ+F26\r\ncapGoipMSMQB4j3lPWuR/DOvmQBCkWA2+w3ppHfq6yYoaRW8Qiyxn+udQBNW\r\n0fVmpiOWTOEcHvLB4gjv4B2Lpe0giOkFWpX9rJTh+3rqxTGHmzdQanU/DRc/\r\nzmVpZyt9Z1HMzQ2HUhkhZuiBW7MldSmm8skJ1x1C1L0fwdxvCzyGpGt5Fob4\r\nCzAva+7FShDZfchYMugg0bOoW//EdrLxnAk=\r\n=o76U\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.13_1658586364054_0.016168041270459677"},"_hasShrinkwrap":false},"0.9.14":{"name":"react-modal-global","version":"0.9.14","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"d879fbce1dac28227a91385953bf19790e94082f","_id":"react-modal-global@0.9.14","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-NZ9OZxsIH+j7OpCeFgMEGb//QPXuf13no/v4FJ2V+Y/tVkhVm668uJnOo1JFBCYs2thN1KEkIp9cIHQ3kvbcoA==","shasum":"8dad8aad12bcc464e3535f2d91ee0ab1b8844a64","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.14.tgz","fileCount":6,"unpackedSize":15940,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEHuzvoqgykklcXM9q30Cg8ynxELiT1sexW73FAnkW99AiBlVz94MPLH1MUCBuxDFSq3+n6Kf+/9zA9RI+GIXOOAPw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3uu2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqbyw//c+BNFQTROymUx5ddw40//XvpBsmN1M4D59crUljpml5g5o6j\r\nZpA6pqgQEe7xrG5fTJ7bOu0FSl0y7+XXCQQSWCtNPVYWv3Ka/ZcZr9C0bFhJ\r\n6yAFWETjiW4SYPrcAMrGa+prsyiPF/5NMl8PntRu/N2Pd2Hg6EWLu4Kz6K6j\r\njKbg8TssENNZiD30J3srYvNIX/ALfJn6cMEr7IR6w3pYCFRnkPXDyag7xDfA\r\nfs8Rj6xq2r5p4lP4AikfzMhrYcJTn+w9gRP6K63r+RIsJsDVcua5TzXtiiEL\r\nXwrqlcPIkS2MnjKjkLF+K3Sal0RRLM73k8d0jDmb9XHw4ETGHUFuSjictfvk\r\n0gB/LtAocPJN+OUCTIsld5LydGvNGHXzvp0zmOF755H8hen0qEizQyN293/e\r\nXdTxHcqhVak+Ln60En2xY3mZHDUw9rJfcAsIXRE+QuVjI7GIcWleDtT6Ji5z\r\nZKuUaeqrj01Woam6yldd7S71o/MSq9fCT3lPOl/oyaDnThzKmT/7/5Sh3pym\r\nLbOGaqLqSg0Wh4asB88hglY8FNZSrB3hiHo4dcjW826+aUMuF3GjJHldu02e\r\n3uasWcHhdfGnspCK91dD3BUtykW0BRM5Ru1698Bq7auTvYk4efAHQ9hbyQOV\r\nxUvSCU3bl/9PYLpFvaWMBLDDTcrDKK1Yfg0=\r\n=elD0\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.14_1658776501950_0.6594128083064619"},"_hasShrinkwrap":false},"0.9.15":{"name":"react-modal-global","version":"0.9.15","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"73695b21fa1f51ebe401be93876406204533185a","_id":"react-modal-global@0.9.15","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-+mgk57H1ZLDnidmBgSRKRupQDJhCFqxyueorJ3qfhFg7YZTustr73G90GwjjPKDkC6Je4KmST8gfz+J8UWVsVQ==","shasum":"d50736d8aaba41640fe3c11deeefd58958414bfc","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.15.tgz","fileCount":6,"unpackedSize":15940,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFZ8fxpdJ6+gj0LjTCAOi9LeC1WXJHJ2MAAZuS9XlBCeAiEA5ELZnAhVPGYELagW2tmgrtXVCC4pq3l59To87658pT4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3uw0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqSWxAAlJoodAvfjb1Gr8XklJ8dvoWFt2gLeUSDSBQNYd4sp+XDPY1H\r\n5ooyrxcZ+WrBxcK4/rDUK3QhxNl4Bi/Q8pbwPjUP8gEpWngMch9wU0Vjxdvr\r\ntpb9jPCDa25rXaGb459VA1noTHA0Z/l8RmO+gl79XrvaCJhn5E8MUQ1nqhBQ\r\nrczxu8ZOpYLc2ocZiF3lX7GoUQVRujG5Vtb2kqH2NVPOEfhaq+6LCX7rNHnO\r\nw3XqFUDFBRDkJSBHpQcjx2ZwTrMhBvlKuQdIItvP+GPJBy4LNsyxq27NLPWm\r\nqHgmhgaqvL+RfJzAC8O7EWJOZaA2DxrH6LE+C3mNRrpphYO5D9Z3ok3WWGx0\r\ngT8b1/zDBPys5awAz1DbJgaq2DMXZONfbg9ZaBLOOT2MaQTuvJ6a31peiYSg\r\nXV6tAHJfgqNrGWhgv/ckXHhVKS+1tRomFLL6yRMYqZfDoyfCJgEEmrqhkQff\r\nGfPu8oods6QoIpHcw0NPSyeuaIjjZIdlsw9cKGF3UrnYJECPHTX763LpaDFO\r\n3c9SOu7AlmiNR/yHeMdgSSB/wqFc3M6JyAar6neLOmotnaZDbly4y7r5mqN3\r\nNGDAYRGdcGn2gC7bDGB3zfkTVM8jgDeK9+KtpOYUea4FhmwXVH3HfmPNrBk5\r\n9t38L4N1sjq8Ul+2mx1c2QYX66VUA8ylFS0=\r\n=Mwcv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.15_1658776628227_0.3464948361081768"},"_hasShrinkwrap":false},"0.9.16":{"name":"react-modal-global","version":"0.9.16","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"f736dcb000b59b3a9c33c62e3429ce708e08649b","_id":"react-modal-global@0.9.16","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-o9udB/cpba2HLP6ubjmgHSIqEXDMci+UAGPGyDh4D892sW1AfY6GY5c/LJFQQoWwnNtTAe+a7vsj1VRHBNvzUQ==","shasum":"3848bfb45bcdde996588345bccecd8f84bb3db17","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.16.tgz","fileCount":6,"unpackedSize":15940,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCOAqwF9qabLr31+6rZul2uQ1BPwVTcIS31YbCxAs2zOAIhAIA8RxSdD7meAUrKOoeBduxK3P+J3AUlMMxepUrN7sSl"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3u7/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq1Bw//ZZ1oNEf7Gry/+byFpaETo1JGNsaLmbR9rXEVADdgSIzY80CX\r\naNCz+0gJYfZLr6gEDKwhl8MMv7tW0EcINq4p2aY5r8ZWmQaIXv3lIPUt08I5\r\na52rSeM6SLnpcgYyy0R4UdWQf2lQZ9/TssX5EQD5Khp4Fk44quIMoEZxQqnb\r\nkNrO+FBj68bTJO7RsNRd7Yh9fkwEUBq413un8a8j4Gl4LnigPm3ZNlVS7Oyk\r\nGpsue9rVdf0ONQ1UvZHwGXnbvM2MqPLwetif1NPiLu5HYHD+r9a4JWL7D/Qq\r\nDGrrKpJFq3kkHIofnvJ7F9vYgEXgaJYkXjJ9IwcV3MU9jRHtRKZvNcTRNZHt\r\nyN04r2d6SIM6GVvnd0luUsVctj8Q8lJ0Uqip7erLB1uWcTkhJ4TOlaAwGToD\r\ne7PdKWvkTrIn8CcuJrL5dLr20uSudPSaSuCTxmJW8lBlhD7CKpF2yW5GhsCM\r\nqxprL9OQa+5ynjxcR63VP/aeSmumm7nXnv7+/1D2nvFdj4ftmOGL/m4FP1lA\r\nKlOXozHJeicepSFxP97ML+Qg/YgyA4W8d3JflVe+ZxBagP2Z27/5/3C2HpUz\r\nwPKCuFqVNTdzXRS6yO6AVRTTFbu1L6zOHMFXigbaVWfJl35Mnxk+7VqfaBHD\r\nuTqPnMA4RWzjxzy+du30Y2/ZGoCGRqmMyg8=\r\n=wTpV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.16_1658777342924_0.4236297242874365"},"_hasShrinkwrap":false},"0.9.17":{"name":"react-modal-global","version":"0.9.17","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"84c9ea9812957843ac45a16dd3054d02875ea2ad","_id":"react-modal-global@0.9.17","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-224ukQag6YzG44CBXv8ej7QnyqwIPfO499/D5PFK9la9mvj6v8uEm5t6CSXxyGb6y01SXuR7r5V1sLsUmUVRbQ==","shasum":"07d8b67cde496ab5bb0a598c25eedc158698f978","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.17.tgz","fileCount":6,"unpackedSize":15951,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE9CyMj/F2T0KGvNrWCha11CQR4C5i/YkcrabkM4Xq11AiBpnwBS2ZTozqv5U8uGDDezcptthLAel6WrLsjrzvjolQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4qdyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqveg//QXofz3elkC9ibrF9JkBqPpqh8dYDqmKoqbTj79BUHHe8cXDG\r\nSooW3f0m96jK0y/pwcNQz4oNbhicTT9eSOJgdriuEVTpcZxe2ktuk2EeAvkZ\r\nGiDCpOvAKtamjU7XZM1/pNHt1ErRStWc4oZBKGvBcgFX82l0tG8I+s+7AsOP\r\nbOlfzLhwJ0kh36TmCNmxBSNDlq8cxe/WOZXDREzD4P2jcAm7AmaizJCH3wHB\r\nhnSI3Fuu6wcTOES1oqALcudw+kHQ4IP/fCPmDzSsAND/5PYtMh3jDCrw3LDA\r\nl0WTfTOrzyDl5nhaNxQwzi8m5dGSG9J0oKfxRVHDa67aeznN79biv7CX8Y9x\r\n+8BUKpprht/2hFf6xd+sZbGy71JhCW/gffBpBJI9vAebIb4AaqGRsHQvuvCx\r\nl7n4SWFdbcX4mKnHg31r8esBSB/5VlbvHgaikBxuHbBgI27yKTop0tYbD2oH\r\nNb9DffTcn32T4MfSEIs14H+9DtQIwYdvFSFY+3jy9DSl7E3yStRJP687XunG\r\nAAZk3IzZDUGvNPhSLMYWYloa3YQw4rvDiDXi7Yn4G6pzM+LH/vLUHxM8Rq36\r\nSdYRV48qus14rt9SeZFf/PuZIEw4/PhJNA8BpPalyYxuGzhl2m/YihGirJdl\r\nwBLwciFQVDjfd1Uvr6qqhXEbkzXaJpPLGXM=\r\n=zD6X\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.17_1659021170466_0.5914700344532529"},"_hasShrinkwrap":false},"0.9.18":{"name":"react-modal-global","version":"0.9.18","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"9502fef07a16a65d916a3ad34c435218be2b39a9","_id":"react-modal-global@0.9.18","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-7Bqrc9lBviyMR0910patu+aZa9WtD+p3h9MiBRHW8zPyLkhYeL2f1/BODsYbpCCfGLzcv3hdoxNJXsbrvp9rFw==","shasum":"f99dcb5bb44f4c99f84f2d29ced03609ed4f61f0","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.18.tgz","fileCount":6,"unpackedSize":16078,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICJXPOxtvW/PD8vGC7K3by2cKogs4KJJ9la61U98x4X7AiBbBN2G/176AB+zZqdSq7MVdLhg0uh2AZg8d7HN9GtxaQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi482WACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqxkRAAkKc1mDZSugAg7vl6vBIzvyJ3s2HA2TB2ZsVx+yxMc3uZ/LMK\r\n0g3azigWUTZvF4WAvkzJuC2J7DNaSOZ8waP5kOaSzLK40A3arE4h1E217Cod\r\ndV89qM4vfZtZp50k3E+Uvg2fGUuT/ClfAR76mRCydURgynPPNZAMJT7Is5zl\r\nIldVBHhuJsNEhmO7UvMqn6olkz3y+uQvu3sG8PegaK181nfxXlQGigxh/9Xg\r\nHyGyYaDVRcEeIvBpUFddo6BI3LEoPEtJ8aB0lEVB6oj8lIwvTy32SKNu2Fhe\r\nv+JFl0EDnZV088ijU1amcZRabuh+/kxtnorgZmhFGip+u5IcmAOft3a59Eu+\r\n50AUghKuboUV3obGEicOxULvdoRFOVM19siiq4h051Tq4jnJhpPcg8Z7Ff0k\r\nbFicu+mLv3ivfR0P0Gc49i51Uk+LILuEOXRsM5t13pl2MiyTZeFXsRo8Z1t1\r\ng02p6p8U9vXeXLhJLh7mZI7hS7cXjb/rXUgrC7Id/2S/Nw0F3AjnsaL523Qk\r\nQzD8rGHfOinAO0l7Tk9WTJxrDkU/poNZPAgSUFFNpWN3Qdbuwbi/CmJwi4kf\r\nQ9xVveM48CDpv5Nc640IJfMRlbJz/B2SKw9+RZUx8zW4KXMzWMDoTxSxGiKv\r\n9Sn3OmsEX+jxlAU+4FdeWqZve1toqaU5ksY=\r\n=+2cK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.18_1659096470408_0.8213543765473943"},"_hasShrinkwrap":false},"0.9.19":{"name":"react-modal-global","version":"0.9.19","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"98f4d393c47d563f917bc11dd8d57443a59120d7","_id":"react-modal-global@0.9.19","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-lDjsGGQ9dfW1z0FpA6b6Lb6W3yXSBj/9AEuv5kvSYMEK3LJWHxALXzZz/S4wDLW90jelkcLS9WfTSsDVQmiGLA==","shasum":"08f4bfd0a71c0ad6fb72a1c984e0c72037997850","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.19.tgz","fileCount":6,"unpackedSize":16080,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG4Sn/vdD4HRl1S4qI2R2ScPWQSdR4utzr7laIsKm8QwAiEAp5Wms2z1owlj8MAaeW16+H7hzbkqNA3ZPCE6xj1dkUo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi483SACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqLRA/+Jt9z3+IHSyFSioDKCuaV30vIcmn6nKW7RiRBIhdGeTWSyu7v\r\nxz26p7EER41qUpnwQRdgI4ou8/1E9Z5p05Nr7LqeJq7eFqaFLXhrEWJKlTgc\r\nq6K+0MsDFxUE9Iqsev8OnEhx/m9RK4UaXkleYlFpbdjSh3DGl55lcdH89DAU\r\noRTdydPm03a+IEmeUuAw+ZGk6pDUButB3UxKr2e4VCXs1WozSQRLwVnF/gee\r\nwp6HImw9xJEpTJoOQJRKOUfZX76T/rkvkQxUOkmUSRdvhkHMbRsNRMPHXuFK\r\nvuQtHGtCyh6yHBlVPLq07QuX9mEy04pF9Ny7Qg65LRID3Xd3g1mee7/2vMow\r\naa3r8hCo2T6A8cgvtl9W5rEtMTzwuDTQTIBq0rIoN6+jLCaUQszoT8hP+zER\r\nWrp5uglgi1G1RsYyY86N46h3RyIerB/cfEAOF+jL9r27UpcG9blUJufBeT/d\r\nZte23POs6V/xfcLxN2IAFZQGJmw/lqcVtY8wAWbjsaEObti6LbyPYH+4rw98\r\n6Aa89F5/eqjKOgfzJnDo9IdDIOVdVCqytYBVGN6naOrSyV91DYrNNM09Agnq\r\noyDjUsTq/paz3eHSxtxyL4UvPoq5+DavjKfKaSvT0JW777Hsq0Env4h+ulRv\r\n2f7upWBRelfcMahMwkZtrmwnhZZgD7soarg=\r\n=hbz/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.19_1659096530080_0.8046220113505502"},"_hasShrinkwrap":false},"0.9.20":{"name":"react-modal-global","version":"0.9.20","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"572251714a2a7540e322cca9b7fe387a25b2c731","_id":"react-modal-global@0.9.20","_nodeVersion":"14.18.1","_npmVersion":"8.5.3","dist":{"integrity":"sha512-6qj00sq4vBecZlfgyxUEvAbpjGXl7+84IffHiaCpk48iBDDCdYhAXT1nIOy/k2vH9lVwTFajLIdRqJGUCK0Iog==","shasum":"734fd3420c16fc95cd1af491c47c8812982af4ab","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.20.tgz","fileCount":6,"unpackedSize":16160,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfg2siWImCr32Nw+HbPBt/T1zoiH+YVGTIlq9DRQXwpgIhAMfmlnq8YcC45BSfKNhBZi/fMRqbwDWK6zYfjC2oSgol"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi7Cb3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNHxAAhvV3o2bR6uoM782A6cJQA+LeMCuqlYhaq5yctQO+XebD5KZL\r\nbuYiGca9CDTpw/N/kkIiTl+1ZYHxou9IMnAd6DdjzqkdGHQZjZ5JJE9m9Lko\r\nFNaYWrrmTtpkFjNqM1tMXX+lM3jWNmxx3enVgi+x++Cg8S7mTb575e3tYeYW\r\n3WOZXGWHK5fh0oVNd7wcn8JALq2HgWUAHSfolSaH9otIHKKwFf7cBKviwoMv\r\nV0gM9CRRvu2ucib0XUWdbUhx6kFIrovigBEWA0smjqxdyUWC3e50rIrsecSS\r\nU3d2G/wyA1WDQCxHXljonY5NxaeZhuvc/7WD7M68fktS22BeocSwt8mQF5Zs\r\nqn/Rpptrgm54ffRsFEZxQRSRzfsmTjsL3WwhaWU/HcWd1YowSWu9hjRIILDW\r\nOrPMoDCA6NhathxFhQh9ybFkRbyUoSqJozd+CIQ26uLu4ZPTrVyfrkHO++D+\r\nyvwDfvsyXNR5puUtrm56jQByu0rqlhD8cv5E2NtIjIx1gywgADl9Pp2S8Phy\r\nusiL0WBzvR7phKCglKuuEOiYr8NdQQZYaXcYu6h7sAhX8FR1YE/pTNenQ7gi\r\njrGxpnrRmlUHg06b6yNL69yu4zBVo7VAE5QoyTYacneFYBYIkKb4GvegPt3u\r\n63OwcWC9X26S/SziEnnVowLZClVCeDwVvf8=\r\n=jnkb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.20_1659643639200_0.9659030761856247"},"_hasShrinkwrap":false},"0.9.22":{"name":"react-modal-global","version":"0.9.22","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"ncc build src/index.ts","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"e1d4f6c2a0893a26175760aa404d4bdd01d0a2a2","_id":"react-modal-global@0.9.22","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-3rGjOeFb8ecTl/CGPCW4kcSBWZQmqZDDTjIrqWPJeRoWS7d61rtDpVJFBttRi2SpR4UWpIzi9p17VCRYcF0e9A==","shasum":"cc7983ab538d554d827c6816255a0af04f77fbd0","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.22.tgz","fileCount":5,"unpackedSize":179378,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEsL1XDTVPDpYb3Cd3Botadk4bteQmLZdcNgcHW10INTAiA5ThrVqFOA/Aso9pMkQ0WHUWg7zWnrzYnrm2pfgdnkpA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWDmLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoBCQ/8CxRP9BxTwQmND6lNmauo9lEPkb9nm5qNOxJdOr6poYcRvYIj\r\nnSTbKnY2JV4hAk6d0jU5NkaBMm77Bb4khra9JchlLP4QkkAz2W+IW1rKeXwa\r\nGAHxMOdPqPof3l//GC4vCIZI8XGgY1yyAWqnodCOju7CLDVQ4fhxSk+oXTxj\r\n+36YC7tf6xTTro+rIO7Vvc+EbafakwvtD8kVioVfd4KE0QIEYtADtao1Anw4\r\nPqrjr+wpvwX1iSVkWSCTrlNqMSUs7bMjl+jNdDWS0CoH27Xl8VloN+7BbVfx\r\nfDgQiLAgVSJfQHaQTzeIURTayy9JrzFpe34eOCjsC1YqOxRRKb0OI/0hMiXs\r\n+bBLvXG5slE7fv/f7ZodfMfS9dM4sJKGi1AN6BErHTyNUJbsaYQxq5bHdV+N\r\nVkQjEaYm96ae2PnAFUaiKj9WIg47PgLyDoUIMuxTUlBaR0fM5MarsCTO3UH7\r\n1nG9o/z/l74FvvV3ggcN7YJlt3/aeuG0kTYRqFDVSSiGCoJdXZOJXBkO6G1F\r\nOV/4NN9YX/yNfuKBE+CQiNQesFn1xPxkl4z634ZMsEQ9qN6xzFvg2ywmtKxY\r\nVXn7OLigFNk3InJ6XJ+k3zIUO5WKX6bXU5AgWAUsKdGcvdFF1p//5f7KRIww\r\n0SDk8tRg5boZtODWxWb4mKNiWho2TTYqZvE=\r\n=grIf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.22_1666726283324_0.9001346738501255"},"_hasShrinkwrap":false},"0.9.23":{"name":"react-modal-global","version":"0.9.23","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"81ed3af7e1967411b045ff2f1c2035fd1d8e8340","_id":"react-modal-global@0.9.23","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-cCILRnt4UdlGDLL4jje1qgtrRw2CO05KpsgAR2I3K/TLBImXBCHa3mOXe2d0m4U5Z9AL/pgyO/WC2YNN6iERzQ==","shasum":"c5ed7aa1940acedd8e9db6765a209cd80d75eb1f","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.23.tgz","fileCount":7,"unpackedSize":187601,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG/8Ph7OdOslxseZCk4g4a80kOVvPge0JAODmY3VbuYKAiEA9mkPqHVKK70swigwJqekPpqt7MetcPELE5mhveJ3LOM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWDoqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqhAg/+NUsYlcrJJ9CE1v+gSxMVahGn7mSJAA6BOroz1WkBbgm9CgRS\r\nYRW2l6Mz0hdCiNEGrt8swpBqKpetKJxmcTdojdzH4WwzVfV3T1J6wD8gI3Cv\r\n/OWUft6mmQCk/K+khOFowAEPzIWQ9pLMqjAWABgnskuwRDplwPfTmcOcxERe\r\nOBFzyO6FYb6qTyxuN7wjTvGnHdnb7xJieGRgABRDsQ0lIlrAwat+iD4EM0/I\r\nImr90yYtHh7j9Sz52x9yLgSDr+D3UGuWGra6wjWk3utyzzlKBL961MLdWXnb\r\n5m304EImZPBpwTmIK2xT8/Z8Rf+0iutNL3cobN+cgwtJ+KjaD0gXBLdm/s3u\r\nyCsiIcCiUMbSc1lsF7KSudS8O/sFl6iD85MbQLzSWtcfNewLNXTP+4Xfp0BE\r\nwqr3TL1iMTNCXg+VagOzWot9tNyE/++AVJh4IRRvQ5nNTLymajDbwUfLG92L\r\nOW1NPVTySQL8cHzt9oR7I0dkEAKdnqnOuNNeXNZmeHVeQolYAcWXafu0PVIJ\r\nJ/lV8P6PyPLF2YByyUPnKBWT4yCVCqS9y5gmOXpXkmOFi6EGxzDxbLE1r5Ky\r\nqRy//dUTiir5aIZN3g86fD/MAmfuRtTe5nH1xONOI89OVJCxsEce4yUVzemw\r\nKXzHPBJ4K3jEUSmW6diP+Ri+zolcAFLvr1g=\r\n=yjgq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.23_1666726442160_0.3739935462107282"},"_hasShrinkwrap":false},"0.9.24":{"name":"react-modal-global","version":"0.9.24","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"2b08a0aabafd41d83a641092126789bd68527219","_id":"react-modal-global@0.9.24","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-rAz+4GinE0CqB+Yyi/oJrl7Bt2XY5H48Q38cy+E7jWZ129cHqXCYATT24borug7+PtQJHPLWY8Hvv04mW9Sj4w==","shasum":"eadc2be541ec34e7c516ca3f15bc8a0dc264ba87","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.24.tgz","fileCount":6,"unpackedSize":16378,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAPkrk5BK1AoYbY74nrdYFedt3ec6WXZqa/0zFnfy/kKAiEAifvRoi8daun+RPjEqBG+hHrOm0325inMH5Ef6paUkjM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWDxvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoRYBAAhTqiAL8c0aozZ0dWhNwuFP7ekWMQgNLGs3dsc28vsoHWHBmf\r\n/r2KNeqDqqtJVJ7sF14Kk41+CWI2K1CPqCMoL8t2MavWC/qarJBDmz+yeiFa\r\nCp4cCGcjEPx3MkkTZyUsP3N4qZ61cPWsRpUDw78Au7UO9O8FGky8pPuiLRue\r\n4425QzuC5pkP8Mo6KnmwkWxIZmLhRTjoGyIxUIi1l6eld4/4OBvt+vM3EPDs\r\noYBHe1IpA8ei2swQav92/pWaaoqtJ1RCK0VwuJ/jJCn2rxaf/GSNTJGnLlA/\r\nFZASr+teJjTrBNeRJq5bJo6ObUv8waeARqbjmN4utrOcx7L9N8t8pHQdVOZj\r\nZnlW0Lmt6Dgo2z/iOGMZRmVxuKJcAXQacOnPeRjlAI7ZPdWQqowFj1G1OJ7O\r\nNoR2M1REKQHZT+qG3/zaRQ1eKGtiH0y266nqYoG+4+dnGwx7FxPB7Dalnx2N\r\nkLtKkC0FRiEO7lrBqfrwZjF7M+/jimz7NCn41Dt5u8nTbd55Z+iXaZedQnBB\r\n8gRHJ/a7LZuKHglxnVJjGj2ZnkxOqRk0aWLBxUacOG0r/cnra5QPZ35Lx8mT\r\nqf+JAYK7ahTOle6qbvD3LL/knTUXoh38EomVlALrpfgFmHSDoH6dtayFD8ps\r\nlcK/jMYXPXs4uQcKqVrnrjgVMXMZNAmNR28=\r\n=vC3b\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.24_1666727022985_0.2534625985398442"},"_hasShrinkwrap":false},"0.9.25":{"name":"react-modal-global","version":"0.9.25","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"3293355f4437fb3204364db9ceed929737dab516","_id":"react-modal-global@0.9.25","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-w9NTbOiyAJfVA3TiuNaWGFTf70Ia0pkzyqM4sOyBmbOB4AJQoYjywfzuJbixw7RMW2pE+nYvtzP1JTfUkL7C2g==","shasum":"6a1abcebaf607f9ad2e87816953d6c8b0eaf68dc","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.25.tgz","fileCount":6,"unpackedSize":16414,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8CbFUVt7WVuRpYsnJLnEJtmg/i5nDvi4xfyPKhairTQIhAJoGmROAiJ4/vAQukRk/7HFGyIzqIdsDbo3ug83EPrIS"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWPwRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqN7g//dhmeESCu5eir0eRD63Lli3Si9lVEwsrRYheZk90grbIalFwC\r\nu/V+quYUa7mxE9Y0ocInPMBTEGz3rlTmJEDNuYTW1p3zDGuU8xNDDkAca29T\r\nzBkT7DW8Bz8mLczUMQHtyOcCLoMaKcFd0xyuLKUJPIgnQBn4K7Ih8Jeif10/\r\n4urednrQsqS2iT3LTJFOe3553e854xPHSrpWrcwNci8OL0nwyxnK6x/vBbOD\r\nucPHF2RXGUE3GMdoKoJfy8Ng6VsanNyVHvfLgkjK2Ghx7d2zOJKsomMJCaUK\r\n5bT7uMUKqV8wrJZA6EnVeQOOHc+66GTJU6bXJogPqIJpa/kJEZMWFssb9PYN\r\nSRJo8u0RpTcrDymKtc3BI8znb/mlbaFWbM3TNmncPkr+IwCwHZUTJxXv11KU\r\nCRpA5DtE2mk2cVs02qFk7/VQx+TELvv0FA6CC8czdqMP608uu+4FDp99pbay\r\nHWzekWVGsHgOwuZVocCsX9sAgJoyuyBGsha6JduUqu/iAo0ZTqVtm4K24pLX\r\nYv9F7ot9oD+9ke/CNtTtz8i+UUKd2CNkXan3BD7eN6H6c5kwaMLpxuy7QREt\r\n7Aj6PZ68WN0IfGXbOWM5ExVXC91KI/wmODbX/U65DzxpqwFB34DjRzXzG/vM\r\nXTI5hQADKYY5mIoNZlMOehx0EaAHpTRBY2s=\r\n=NWZx\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.25_1666776081623_0.3942658355671145"},"_hasShrinkwrap":false},"0.9.26":{"name":"react-modal-global","version":"0.9.26","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"cd6f243685c5c9eb8ed111c5c80c940ab019e5b0","_id":"react-modal-global@0.9.26","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-q9OVrLJq3QgttFym62PT1kh5LjmJUNhlDi/lWzVrxvZ0g1PFvndtgx8FFWApQrD0Tk7mLgEkRxlQk5E80+/dAA==","shasum":"7f3b243c7b26e9388ed1b7d71e97c719f7a1fb7c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.26.tgz","fileCount":6,"unpackedSize":16405,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDRucFHidMh8e2soY4t+cETO7i/8z0bm4K2z/dZnyzaYQIgXa52gheJEIFA7p/G8Qu6x89bxa9ECdpMQFxJ+AyhsAg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWREIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrBRQ/6AzWeOKlUNVWdVKynY3kugySHTxzNJOoPJ8ldRMNvDZOrL/F2\r\nJ1PeVS9o8vEmesCsniBJuBqZZnAMBYlksRlX6FBRQ4g1P1K6k9MJEw58eBp2\r\ncZa/A6tZCtY/nuQPkx2R+EXeIlPcaAJxmOCPJoHD2HG7qHh5jz3lufhYt69i\r\nYzX0JLRHTH8tWUdzRhdxB1747OqRhqo3Dr2p/jTdc7Un0e8ouLe6a4MPilEb\r\nzzHibs7R/mut8Adg99/IL+Ky7EVqG6vRAQsAgVC9f3yxtCO7Rird2kLmFPaA\r\n3xgkv2QSbYOqzficYEF5usAy5QZg1g7s5s9Zm16plHO2Fud721GCrebxH1/O\r\nIsEKXUzORFixSlJbJK13HpCh4hmqs/x9NGv2oJQDwvd3KShzIeTO8IjVhbl0\r\nyxbRqPcBWDXI88h9gDNTBbOq/mx4NI5OWY6dRiPPHfnexXskminJa5+xpsmW\r\n2m24rJsM7k/vMgEGGUI3AraTYGPT7uV9+D7I4YjTwBj5vk0A5IrWDgOauUkZ\r\nHYQRD0QW0yujTeTf/6vdMJQQU2gkspkmISzvtKrNW2v4G7+hf4OsqJzOHQLW\r\ndXASC/R+UsHYat1OO1MOPLZrc2vc8KP0/9Ugu8Lg4qE1qFO1Bmwvwp04d9sw\r\nTWSqKAbFOz0GDCADsav3ay1QKBmLaPD7SLs=\r\n=Ex0F\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.26_1666781447995_0.3558719807324151"},"_hasShrinkwrap":false},"0.9.27":{"name":"react-modal-global","version":"0.9.27","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"b78d16c9a85b3f54392484d07182ca9c6b0fab47","_id":"react-modal-global@0.9.27","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-HHpZPc+NCk6rkNb+9Zo8HnH2aS3QyPkCJ5164vU16tJoU5Sx6cHGweDuoD4ZHNrafOb9WvuHJi9yY3v0tF+uOQ==","shasum":"360d904acfa4e14a14e0668d02cf5d1c3e87566a","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.27.tgz","fileCount":6,"unpackedSize":16379,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTeVMbFaRNdtyqxZI+nfg4Wekc0Z0VPn2i5wbEE8oCTgIhAMEOGVZAU0OwX9TJbxBMWzxefvxJI8glWaXCoiKnazYX"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWRJDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqd8w//YEigjEAY2k6joBgCTgyeluMmO5qdqITwZsE5CjlTQUwswtUx\r\nvN+6HTp5usu8NrGoSrah62s2FVzuDaZVap1nzrzJ/RwvOYgrwrdVkYD4gHru\r\nwK8x5St7Tf1x4v3wnwJXdUx9glkufxvI4HJLbevKR2OgQiMOMydf3qGXlQ6b\r\nymnW1hXl0QOjpnilKB+veL95J/kTsOnbqjsIqmJv5d0zs3EA3+k4EOWWCo09\r\nzPa5d7yer04jd3CfyZXVQwQ+DJIr73K7jYvtnvslQB2TCaxFSYOFimQnxewQ\r\nO0nYc+cWQlCSNAeyoQr3eXh+FSo07gb28O/gD18cmvWpmfVROnWnET8SY+dR\r\nz0HTNQ23A0v3BxyMpULMx6xJWjxK9RdLu2lwIm3ohUGaSI7ujAqnN73WmjrQ\r\nZT7AjB2QsgxaV1Wjb2yFcJ+omacc6Gkprnj582IfZ6YZg1ozGc+bLmVg5kGa\r\n/OSvRrOHXl1eT0jY/X3Hrn+b2X86gDINhFlsV+NVtkwfxqTnJQVyVRfxV64t\r\nP3BpW1MYftnIvUjNzkmKX1Qj8E0xuVTW4jyHxVuokDcIHJT8RuCmULf4Xvpx\r\nsWVySdSqKrCSz/E/V6LpQFktRBBFGChSpts1x/8Ro7FPzMSjfYS8Qz/cxQW1\r\njy3uCU0Pcw8TJO8RaoJQQIf5NkSxiYASc4Y=\r\n=5zLn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.27_1666781763302_0.7716895955293737"},"_hasShrinkwrap":false},"0.9.28":{"name":"react-modal-global","version":"0.9.28","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"027e36db9da6f1b3d88b2b3766107a190e9652bb","_id":"react-modal-global@0.9.28","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-WkpYyBDQXndqP8DoRVIG8Io85uXUl+4M/M6f4KaMWrRtaEZZNi91fv+ljKriD8eiN7iUbv9JOqI6YFpG6p8yyg==","shasum":"b1f34fbe17d74a51ebddea76ae8b2847285d2d60","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.28.tgz","fileCount":6,"unpackedSize":16414,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChL9H6o5Bue0WzyWKuHQH7+l+SYLKPCRLcOpk4rnpIPAIgQc8Ay5YoxkyWmji/Qq+2K9JH8vH1nMHEXxgh9ipE1AM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWRLfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrQuQ/9HefTDRt3cgDXb7fslGw+CCAtbhdVCGwsVW17th+0ws50sF/P\r\nXLpN5pp/X4E3m1oR6JEOhD0GLAj4aFUo/naod12UhvRNbYOsGM0vCQsVLKS8\r\nSofvGq/LxROOF8AjFO8BwxT1FfLYdIH/LrbD7vvsqbKn3vrJzWsJCD17NkNB\r\n9Wg30RvK1YNMKc7ojEHxdyqnTzFLUXtDFmuDjMb5J0vZSrFaRAT5F9Fnxz7J\r\nlydcb3oic4u+Tna6WiNZcIsCVKa/qmZ7Fy+Z+tMErjHlmuS1sxb/wrSZ4lor\r\n7I/4KxOheG7PekIn4QQfnd/foBz0jZe/LRliCJYV7XeeQid5ts7Jv9r2ycIv\r\nwwL6c0wnvlrqqPF6Fdo6oRTNirA85E/XAi2RPK6Rs+oDSjhBv2lExhpehtAy\r\nsPsyoXfKcyHuBb9Ew5baWSCqQF2vW9imUVKn+DxTtlni6QnjCH3xEe1OpLWf\r\npmpE/GMYiltGdPHTdH+pJSdDIe5E2mp0ioUpzJfBvJoPzZ6ipiFaaPOVcB7Q\r\nHSiy/qKavN2PqYWjOkmCPAaWRUYloWkb2V34Wz5HJB9IhoQkzdFG6viQh5cZ\r\nZHfqrJzHl1yYXHH0ALbta1ep7sHk0ROx7GX92RnLAnWVBIWJMAF2MpL2hfnn\r\n85reI2tj57DMMlpS1ALKEQrlo9dur9ga+CU=\r\n=d9j1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.28_1666781919284_0.052413743439826854"},"_hasShrinkwrap":false},"0.9.29":{"name":"react-modal-global","version":"0.9.29","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"4201b7090b0930c3f8628a80fab70af5d2587bf9","_id":"react-modal-global@0.9.29","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-nZV+hg+EwVwNGlPA3y891xu7y9OrVPV3xKyPEVXhIC6acMaIEwAcrf4et1kXXq/fMgyZK90ytZfI8aMcO7bV4g==","shasum":"6680b71e9bb829e5713cfd52bc41aeae36070d12","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.29.tgz","fileCount":6,"unpackedSize":16414,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQe/Fx8TF8IWwx4d8j80LGgSS7drOrVjIhQkx6ffzotQIhAKhyXn4uzwvbbDtpQX8myCT2LqTLpEowJGclNjro9sbs"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWRMVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpZ2hAAgjaEPsZd1e5fHJdmejp/nyCQBPA5ZTIyizJxdfKaX+V39cPm\r\n4s3DgSkir1BYtGffiyxMXfh7oM3H9sJl2w41jaumVUYhUdRuhlTQkjFN7Y92\r\nXbKhQ0JGbqZHIJcy7iN4/hNQ5pKiA/1vjaVWH6WFx/OciKmt2JFy8QONuC0V\r\nw9V/R1pIAP/CNijpLyP4Tchn2QWJUy6is6WLXq6BxGgyHvf7TDD9/fMCjH60\r\nn5fL6Qnq4S3k3qv2IoPWTQZVhhKoztuXnh8MlEGRyXYuIZ8dBb9rxOJP5sm3\r\nBlns/Rw/p+uLE7GbviRRlZAVlrgNL09k7pA6wStVR4EpNMlDn3CMeYxBXavN\r\n/UTOEaM5BMNJHJfU9xs2L15n6NlJ8BQfOQ1tajK3YHx2WspAlujeymk7v3bv\r\npGY4FAz1EnCgxl8X8BLXOF/HE7Czo66ss413BzdpX3Lxh5tn0seR6cjZyynP\r\ngRMa0YCjXj8AbZFYtxvypcJQcbXtfFw7N8liqeEeqzIPwrLgCjTTiCZWxh5Z\r\nBSptC+l54UuZRiMRMlobla0EMi3DlrnNw2eqjUni/T6OHBPSZUE8xcLGIK66\r\nPws0bEVeZd3fQc4dXVKxKHSdln8+UJf/AoQQKVlQjoaG4x/+QvbwYEwSihBq\r\nj7CE82vpooePRBBFBkblCQHRlbDkk4o+7aw=\r\n=t8RU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.29_1666781973760_0.782159917326694"},"_hasShrinkwrap":false},"0.9.30":{"name":"react-modal-global","version":"0.9.30","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"d9bb5c5d3811a2797b3f1262f05a426ebda32a16","_id":"react-modal-global@0.9.30","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-JIaCRRhBdGvGBQVP8yPMZ9B8z1Dcg+bYKo63wWfNdXeg6Hg7dwDJpg0BorTtVa+BK7jpabxXnSwVIbJBabDaZg==","shasum":"1e015c84c4efcec1724e594cfadfd9817c0f749d","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.30.tgz","fileCount":6,"unpackedSize":16443,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHnN/Dqf9OFicfrFK8Ip2gEtue8G1BBI7eTu3K7DaqW4AiEAvaj0fI6thdtRUbJlYpECt5MCMf7bwIp8w3zl0yAk+ww="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWRUGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpZcg//XHaZIivjvIlWJ34rQshlEDxg5quaAghhY9FaxkqK7hFqQ5cx\r\njaf2/1DaEGTYBb+Wdl9vTO3F59mzKrfmMDeiJVcmU+bT1v752jOnG0GXfd+u\r\nHpBQ0pPEEKgay4oTGMeGhq8CCUcjHL5ls6CNKXfHLOk9ZvA3nG+1B88vVyVu\r\nW/Gp7bqG1Y3eYwaIvB8Emh2auhWaoETyXo5PZwXJQgJlYhfWDIGWDiURWDdb\r\nWA4A8e3Y2QLBHT3v5gqwNyDjphHS8p/QQJ4hmuG190ri/kzEcBKUXJBR6LHf\r\n1XYyHk/t7grIRmQNRcxD1K8H4N2+2MZDAMJu6oTOifd6bbvr31OnmPn/Wm2B\r\nXjTkC6ifcaLzg8SXUYFx0+2P25Ej6J9CHD3TEjPwyHs/flIZifHqBazhMPbG\r\nuBxhxFiAxqwlFF0NytOGfBgUH5rjuyfBmGvkcTqHZXM8Re2PgjAXHVq3K2l8\r\nBJmFGCpf0B4RCLJYQj7cl/DjKgeWsn9Bsy//OAxyofUB2L7hrz/op7aP9Zm6\r\nrFkR4d7OVh9krinAXmAsv2j+eSfhDfg0eH4/8DkRwR6iTz1qla6mxhzaj+Sx\r\nq0rjCP976QU+6Iwos1G1LPwr5jKs7EHywHARh6tzC0jNvsvFbCTne1O9+zYx\r\nvTcXF8Q/0YrGXl1UEZjWNNLl95W+KhbuTIQ=\r\n=h2rJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.30_1666782470321_0.4660916593030884"},"_hasShrinkwrap":false},"0.9.31":{"name":"react-modal-global","version":"0.9.31","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"4384c6226774ae79a6d9f92c32a72836bb932967","_id":"react-modal-global@0.9.31","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-oCzLGD1bgz2klSbXs6eFtWEtXNwquAaS/0ia+TRSmMAED2L0Xh0aRkRNMwzlBckAWEPq8jHz/75wl8Iet5bwag==","shasum":"67008bc71f158481318c89c1c00e532930db2e87","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.31.tgz","fileCount":6,"unpackedSize":16446,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvWy8R5R9m9UsLzfmgZ6B10JMVC6WhC+4M3/RNvWZ7ZAIhANyXixF6Il9fRU/0WVGCMg9d0sr+55B2IihkaTBypiKP"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjXuKJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo39RAAoFdt0a50zWFZxvrXNi7WvetX1CAEQmxbgafcantcfQKRh0em\r\nVVUP9jjJDw5Ktj4rGf1Pg0rVgwfDZ4oz3PELFOUtbuUKVk+s2wzZ6sNCsyZ+\r\now3vrGFD2GTxPbLAUE4icjTWwmLIsMMuj9o8Y/AiHTuSoVDFPHHkWbfyxxa6\r\nuwv3DFhOj9V8S+gboe65q8RcPYiDZZEgfJdIFiY6bIIxDx2Kvw/QPrI7lkhm\r\nIrghVf6VHWxCE5bDSME5jGxEqofeI306AaDVnv+synKjCEs6WXrNdnmx1FcZ\r\ntSRRTUdlnLxrUGRGa/Dy/c39MJsXXMmORdJvu6CDfjMz/kdRfih3KPQFWM6d\r\nBB6VIsakCUEGNBtPYrh1S32d+WMdoWbfONqNkZiDjd0ZHbb++3DAN9GKy6Wi\r\njBjcUOTsM86VZnpeGfjCaEgtByRtKdTObHw4LRaiO+IMQ5I69DGzdTV2C9DX\r\nmQiuQnhKTkKbmWP3IwtH412/4HrX81BXJB1ip01Qfezh6MlttTCtRg8ShXbi\r\nkRKAGdXses6OVL4cYwBO+qSb5Q90iqQ+k1c/7r+UcWfcIUNkin6foT5VTfvj\r\nBlmaERpEc/xRinizV1FJUAdhffIna+57GrU88iIAh4y5qEAjD8rx8WkRco+B\r\nnGKjtUuqaj+2RqnY0LxyT/vaNBdCgfDbZW0=\r\n=RfFE\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.31_1667162761135_0.20074528540262415"},"_hasShrinkwrap":false},"0.9.32":{"name":"react-modal-global","version":"0.9.32","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"@vercel/ncc":"^0.34.0","react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","popup","ts"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"6a262671d2a142ae4424c57c8e72722f9f802783","_id":"react-modal-global@0.9.32","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-Q9Ngrr1KJAHPyG4j7fjMhiWGWdjQ2IPmKo1MrVho48ZnVpEY/fLhUyPt2tmZEZqldei8jbQAeeo7ZRbRjbGULA==","shasum":"a88ff5ff9739555ffa323e9090c7be9ec2bba452","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.32.tgz","fileCount":6,"unpackedSize":16440,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICPfCmW8UfyKCl4sO59aQEfngGsDaxNxi4AeF3te2EbUAiB8yf+DxCASWEnJqaThQtpwav9J8Rolnu3ed83LkDLUfw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjl2JKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmorqxAAhNVyYQ/dyJjNhRowlmHNWW/zcpAixmVuN3KD74CpKq8hyvei\r\nOcuTcWnm1K1qPJ1HVI7PY8W5O6gLiNPHJeA/3LNQar+0cZXS+VqGGP19Qd6Y\r\n4k3FxxwftZkeUoQ27DjkLtw347KeyUGiZ18U/Yv52a0hO4StxXCSKRjdlzDb\r\n5Aw59B3exu/nZ8T2XKEfoF/4s1ZBRV3GCiRqBA9OmBqpHcF34jNjpoVV3tzM\r\nIcP6OxsuZETHW+ChUmJWf/1etZAZ+JeaXYuC50JOKf9c21Tu31lo4+XA5xcH\r\nrEGcaCYJoaeA/sEy7XkXeVE/e32vDEN+yXIJkiBLJK64Yl0ZMh8LamAvo+Iz\r\nDIvi2y3zyitfHoM85YSkNZImw876dEQ+S5G8SK1oFY4+XqKvtQMQew7u7EFZ\r\njQutNaG1IKkr+gZiM4drErSv7yiemkZhpADuoSas9wB60gDhnjNmbvNSzUty\r\nXgzfVTcGTRun4Be7Gs5/tqTerK3r5Ru7nXSpRg+BEPYteaSYeBDUgdcpVXl8\r\nCZLnKwrCK643OEh3bBDLz2NvbwZhyhx+9zX4XjgJ1BI/gFz/VkNEvFo0wIth\r\nhDCpXoQWKUksDJFnzbBYUIbOYp1MRRXmkNcGCu5qizW26v9yuZPgdX2oKqd2\r\nu2o6VyHxyARSf+HrSQGnB+6ZoeY6BjjEXhQ=\r\n=gLo6\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.32_1670865482211_0.6697273060113986"},"_hasShrinkwrap":false},"0.9.33":{"name":"react-modal-global","version":"0.9.33","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","dependencies":{"react":"^18.2.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","gitHead":"19bcde166f3841f131825cfe3ef2ff7e35362bdd","_id":"react-modal-global@0.9.33","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-cRL+vBeSK2GCzbM4p4n3Z5Sbx58R+3XbinThmmCUUwDGnAFGqdw/Y0uK5R+dRKREllJywHOMg5P+KPExv6n1dw==","shasum":"5e98aa68a84624b46162a3a74c99bb8d31f76c15","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.9.33.tgz","fileCount":6,"unpackedSize":16928,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICxePbYxmv1KzAsdIKZOZ78ZEQ9SdhNQDx+xaarJqwnhAiEAnaOp7m2DVk1nvKIzi7WiJ6SN79z4iMo2evQ4Ifr0ghk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjrN7LACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoAUw//XZrFwQGRH+s8H+cMVnrnrMERsLmAgDxHBtO4KM1/ljQMTUrJ\r\n/Tc6HT3Wox+akaDPQ/7ZZoa/1T4GfuIAbM5+StmgaC410NEHWK/vkH2Z+VoB\r\nIwPz0Bv+tnefdQEJ8V5rTobxCgXeG6x6p8CBwe2HnoajGZx9uHQTJuJjSkxh\r\nfRqst6i8aOALijR85QLD0MQhmng/1qKk693c5mvAtXHf7rYlhKQG3P7UHb9H\r\noS427UXZQggBHCfdsHBUlF7xjKRklTkoFCx4x4lBXodelx7dTtXOpPhf/TwT\r\nYZsu9bp2oZ7q2iTwzl1Fvg5/Z6gupeADwrhGrFkn3/3Bz7MuYydqN8Hua/MH\r\nIEThmiQztqyYRhK4I7EfMRdeEQXXWHPZyY8yINwFqJuFpAtNwbHHj4y5j265\r\ns2kW8Q6tZh9SfZzZF8+a2S8hrCX++1xMQuGdMEGKpx82wkHjrcK0EXEgQKWm\r\ny3iBjjh3/BURo5KcLpvtUAFM4WDkiMpV28OTgYjNPLAjQ0pt+xG4imjny0Pc\r\nrHg2WHpBQng2z50mDo6T5m7111aKzKVsvqrDZGwFEb/TZGIqiOcaRBhyDymY\r\nPbMC1FDqV3bu4Gx7yIEJbB3u/Z1O7/AG2FdMPIOzSlYHRmxcJyb1YseI1iH7\r\nLhWNA6SzIteDxipiUt5B0tdMVurjXWbSMTM=\r\n=8y7/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.9.33_1672273611268_0.6580645403687693"},"_hasShrinkwrap":false},"1.0.0":{"name":"react-modal-global","version":"1.0.0","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"363e5f4a754665077109433b607c160a3e5f51d4","_id":"react-modal-global@1.0.0","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-hljbj7eTdfzBq1dMZ9N2TtYgSZDGup2MGENqhi2oRPsZHv1LxTz1iEXqCY4/k6ETwG7WRAaJLiJFpNFeGNsYUw==","shasum":"38a83a55850bd26b6c91a611e7b5c22336cb1b5c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.0.0.tgz","fileCount":6,"unpackedSize":25189,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG4PxsQVoSEnvBHV8U8RERa0FlU5ZB1JKoUHF0bfaZWAAiEAp7cMNYsmzoNn2Husy8xvzk+d+E0rsp2e1u7V3iKscoU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj6C5oACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpywBAAlp75WK5dl2pN3SqdaQNShDONNS+JCQ5xAwwxEyPoVKJ0e6kw\r\nEiJ1dDCBrK/qR1h+3mmHluH2DHcEGZ7iSUh8Wjt7a0q0EcSJT5e0tTJ8mm4h\r\nMS7D7pN2mK2CK06k3V5c3Y1Uw3u0726EYKTFn7M+pc9T99bTspX4lcYh2tKB\r\nPB5lIKWRyYKCB7uJfUwcQ/f+V3FRkxuQRLPcQkK56KdBuUKfNAqjlwdylXkQ\r\n+Dv5I8U5HAetBGMvT5Zk3dh/bmX2HOzvPzhcVs1uD4FBamUl/0qZHHauHiQu\r\nkGPdS91glf5MHljMLmK2DWYQidXPtUBnJfGQK9avFs3NfaMSKFTHzqobFt4U\r\nMLY1MfzNhhlULxJ5SCCDbSk+uos8hc0GXYnR77HnT+9f//b7gfltXAL90NSK\r\nqVux1EWJYIDt54ItXlQpWRt7Fzq9pcOUXHVXI6nSGBOepJq/rgSqbzqf0yZT\r\nTXnp3x+LvPQH3St7apVuMY7+r0+IhhVy3K6MUtd1FWvV5Ypr46Q+ATpxtJ1Y\r\nB0JmtsWygZNv5X7pYxmqbcrtm77qngZ/ilyQKnKjSsnv4KXmgA6zpSzR/w2Y\r\nbJIyO0eCLg+4rzRmc75EEOFadyWNfLE83zTM+FBwX4gUIYW1jwOF6f35rzgP\r\nnOTZRufHthhdmP1AG3FOswl6IEYwH3EL5Rw=\r\n=quvz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.0.0_1676160616464_0.33879117717576346"},"_hasShrinkwrap":false},"1.0.1":{"name":"react-modal-global","version":"1.0.1","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"a2a51f0c2618409c4460bb52ce919f3e15f34b62","_id":"react-modal-global@1.0.1","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-ZL9opzrvwdZkQZxFRcq3qsIjp34dpcpY6gj4xRsq7ph6c9KQPoGloDYYrVgVLmn3Wl7n9dRwTaP7KpHJCpy53w==","shasum":"1f8b0d6cc1ac23982f17a9f6279e55b00ce73b97","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.0.1.tgz","fileCount":6,"unpackedSize":25267,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG+vQWpnX65Gr+Z54wzEMDfK5gGVs4eSTlZdeFvwkwqoAiEAuZwC/aA8GEq5sipmQV+LNHxz1fWky01d/c6c86vrRUU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj6sUPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp19BAAj8s2gCBjM11N9WWqcVMCyX752SIKYGEzyn1sYFOISJrtbEN2\r\nz60NkghIcITU9vA0O8gJZbKBc5iDD6n8ehLk1dxsb4gxxAfoRhxEM7D+eE6m\r\nfiGGcQ0gB5Cwx23CBdNvSqj/03IoUeGF1yfmhnLl+K64zmifJHgRQWCCov59\r\nQFV8bAXrKZFOwiutXfVMKebT1V3H43hCkBq4O9+5cPGOw9HhWBhciFQm2jyv\r\n84F00vd2TCeaGv56Xcn7s/N4lxiHFF3IUTyFGRcV/X6ws7qRCZIF6cCVtYo7\r\nN4Rykvx7eoxaA1/knAoAzzhcmwhUasV6/U7wg0k1kmQI7H9DqpsAHE0rCn5B\r\nNg4BToFs+0s8zjMH4YLFpZ/fASdxDfMiJFqCYjcQmUeKOsg13VQx5zPpcOHe\r\nOH7nu1i4qC0kT3NcUunVXuLOKaN5bfVKWx4EaBmn6DGSufWlV/u0OrSIzkGo\r\nuPupPmqPVAUZ/HkEtULzBJcA17IF45TPZnP+U9ZvE2eCbkVynzEmCaM8r4ft\r\nWJTMGMDRSJsubZzDO1FFClTM2LC6Bo56xrNyZr97q9/2sOnOipEsNvDBNAuO\r\nYFupPJR+l+PQG4nX9XqiT6bffSmdenRFSp9IwvCGdd7jHvb7jY1LP6KxL4i0\r\nLHzU/dSkKMykaryyUeAZqbN2JqITa8lkKHc=\r\n=esLM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.0.1_1676330255634_0.218146414356148"},"_hasShrinkwrap":false},"1.0.2-rc1":{"name":"react-modal-global","version":"1.0.2-rc1","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"4.7.4"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute in GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Add container](#add-container)\n      - [Show `ModalContainer` usage example](#show-modalcontainer-usage-example)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\nUsage may seem a bit complicated but it's actually very simple, please, be patient and read all the thing through.\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n#### Show `ModalContainer` usage example\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating such is a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of current component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if should\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nOr using `Modal.closeBy` methods.\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description |\n| ---------- | ----------  |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"b85c29645d904a4214fa166cc54d26555b72620f","_id":"react-modal-global@1.0.2-rc1","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-WWV5dHC3SGP3QHiK4e5GfyLhdx5QlXHo5M8h+s9/39Y45wvQI04kCzrL4X8HTICV7gSTWIkXRx3CInlSDXaK3g==","shasum":"e7d69f4339c2510599ea63906dbbe037ca228278","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.0.2-rc1.tgz","fileCount":6,"unpackedSize":25271,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDrJO8JpTpB/rucwmRluxa3Gbtk55/kn0BAvTuHfYExoAIgM0RHJobF/7kvaEnCV7707LGVhpEKXleYVdMA9VKNRCY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj73thACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRuxAAjwOIq9pZhpRkz4X0a/VleWVx69fOHoC2B4KeZBfhGo+yQIg0\r\n6oX9rV1Gdl8t/rVz8dfIic4JgOOUJM9VQhcJmfLqqqm10qJaE9q2lLbVqZCT\r\ncbbLKONeE9EvxKpANWusitG7OCeYA/38xirjYFEJSgXCWdHJsE/kde6DT7Hp\r\nsA5Qdap1EgIBeNbWn6kN3Gd4mLUekitmotm0M5lJVARxNWxEPBne3cCFW0xv\r\ngb8X4S0OImhGYhKqVlQUCXM+QOhgiSEnWuFC2NYCgyCg0QePTbsnh9Thn4z/\r\n+5WHgMqrFrjs7pseMsYmRHVyu0RUVBUbagFakAmNUciGDyhy5g5KqFIe1tId\r\n0qnaP3YikdhZZRyjXi0sIElQli63s0q9IWQf6WgbxEzHcOJ3SfsccwMtUFxZ\r\nQJiJaLgA5+oavz4H8HSKEP6qckDe9PeG5Q8znAp4h7eYYLnj/8++E8ZiLB0n\r\njxRgFm/ys3kBvl1C/vh9NXzpshS/GWxhEev3EixL/xia1qdIppFLkbIVJ7yu\r\nQqlFg6HwBwzAl/jWL7+DEphNpZ874NeDZZwVYLOzjYswqI17usKUYSaAo3O5\r\nrfFNBV531qZ6Bw/ECvI4f8SfuPUyRgvFdnxe2iERtetHHlMkR1+fX19JHzqF\r\n5nxEt8NcjtTbUs5rHjQMOAK/ljwXMYrX2zw=\r\n=PHue\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.0.2-rc1_1676639073048_0.2464986747512694"},"_hasShrinkwrap":false},"1.0.2-rc2":{"name":"react-modal-global","version":"1.0.2-rc2","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute in GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Add container](#add-container)\n      - [Show `ModalContainer` usage example](#show-modalcontainer-usage-example)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\nUsage may seem a bit complicated but it's actually very simple, please, be patient and read all the thing through.\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n#### Show `ModalContainer` usage example\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating such is a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of current component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if should\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nOr using `Modal.closeBy` methods.\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description |\n| ---------- | ----------  |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"7dbaec7b41d22bcf2a158406bc1b20848b19679b","_id":"react-modal-global@1.0.2-rc2","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-vlzPwj+2aaHrmigNf7VzZjUvIW3+t6KcYBUUHbdLSHecs9vChKfghObmW9r8h1C8P87S1DIAMhXZ9MFBq3QIEA==","shasum":"57a1771db689f5528a4356e9c924ec61d50a3e68","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.0.2-rc2.tgz","fileCount":6,"unpackedSize":25478,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDTnaUFnZCBsbx0poRsIxWIOqVQ6+w3JROgz1SuhPuKMAiEA1+NzvxrYiVB3x6s/l/XFiwf394P6JacvqiddQqlZqR8="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj73wRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9Ow//VnbS+ngExF/zGpxIwc9MxKWbKUCNtYdC/ot/FYp7157lUHBR\r\naYHvEEWbLNzKhi3GbxN+KWb64SoRowD58xQk97W1Jtaxvwme5S8Qt1yXAOnX\r\nWhyY3AK6ppByY+0UATAdnFzrcJX1LYJ7qhcaNKMOQyu09/rJkJ6pQxVfu242\r\n7Ys6vve0OYNhLgpI7lprC6gc4j76oUCyPJXR/iYmfWbMBrvAMMm+4HFAaHSu\r\nj14r8Qdm85jPCKy6iiCkrIaSLILOnxbUX9y+fuQZpRx7QR2GUWJ1omQhX+p4\r\nmv0+sug6q2Ej4VGWM35BH//+bTH6bTVz0/yYg/HJQiIi+Zy2Km+coOU85rqI\r\npfQ568KHTH/9ba1Dakg000O8MQoN1gYLMBagLdGSkLzt/nuZQQ1C7JDPIp86\r\nuxgENOPWW/CUrt5OlVMUI0DjNfHVKdfeov8T3vVEvDHt0n5PTIY979HTbJgD\r\n2Dl9XWw/V95IxTyUHAr0H9ZOdLgxvUTM4w7pG/IMu7xdfVW/kHGRScvJEKWd\r\n0LabT6bdrwzRBEpgJDj/YoYoqVYOeed21zHL16IX3BCzhEl7qnza47q+cT/n\r\n9yKn/o4JBwwzCvvtV/dh+1ZZYA8vezTzzb2paSTGWF/G0p9vaOQh3tmtjVQw\r\nGkYwuoHlptDf9MMsyFasMWfjY0bOitSHEtQ=\r\n=2E6h\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.0.2-rc2_1676639249395_0.31749215691216803"},"_hasShrinkwrap":false},"1.1.0-rc1":{"name":"react-modal-global","version":"1.1.0-rc1","description":"React Modal but Global","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute in GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Add container](#add-container)\n      - [Show `ModalContainer` usage example](#show-modalcontainer-usage-example)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\nUsage may seem a bit complicated but it's actually very simple, please, be patient and read all the thing through.\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n#### Show `ModalContainer` usage example\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating such is a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of current component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if should\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nOr using `Modal.closeBy` methods.\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description |\n| ---------- | ----------  |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"37b82fbf40648eef2b5ba2bb006b3ead5d94f216","_id":"react-modal-global@1.1.0-rc1","_nodeVersion":"18.9.0","_npmVersion":"8.19.1","dist":{"integrity":"sha512-qEEM8+hJ+ckdtD0g9EanDqUbPTuVc1s7FoYTpqCFcSP8o1JoPa8m4oJlz/dC6aGOvzLyifj3+PcxA6y62OBsBg==","shasum":"4d852e9042e1a775c367d39e75d0b8000a0dfb2c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.1.0-rc1.tgz","fileCount":6,"unpackedSize":25517,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC00jlLxFXfUZ4YkvZm0VhaPhXl21yafLwu5gCMNoNOaQIgcgOdl7lIbFUeokdE47WabOK36NojIH/f+3V1Q3MC/9g="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj78c9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr1+w//c8+P960PD6xGNr850xvokoguOjSLtEai62gEssTlRZO0eAgr\r\n/sdksB6KY2e+w+v4BiHbCUaocs5CCnQHDBlLVunecp5uNJ1Qk8cumea8ISvE\r\nfKcMsb/AmotE4gtI/3FGWpImYVxErshWocV/LPskj0fN2IMRiu3LERlcVOdx\r\nXrvghe7d64NZ4xLWouyx9g4bf6fzFF6DRTsI0ZF0wQZcmeaSYWrUjGUOt9zk\r\nAbGxrAonfnDkSiF4KvTlNI3Y6B1kfSEMjKci/GQctrJ8mTVp3K9uY0dqgpY6\r\nfBR+vahrncmWiiKNRLAVfwkEVK1IZsUAcEY0hRZqvtvgZLOLJxYKAPtgdHcG\r\nwPByBZW+z8hGEbQwAeaAiNvW+eR6Ybam418yplPUtzsxGQvnpiUNmIvGnAkt\r\nN9jPPWjbvPuFoSnUD1oNvnTExyj1M6lYtVan7/G0Rctf+ctlQKsqVZdIteNv\r\no8zARV9P61IB4bFycJGRYAPILAzY7c5mVgoubjw+jKawfcPybW4EySgYlxDL\r\nikDhRoTMAjQnbK7LG0wg1L3IS9WdJF6SM4ndXsuN3hEkkHWZplFihQDMnZOa\r\nh3yjbP/o98YcP5i8ALbsy26a1piK+GviXu+7esOgBG25kjmuZ8nRcBAKedks\r\nOWXafITv2HDfQlfzeVB0NciR3F8g1XBI39c=\r\n=bSXq\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.1.0-rc1_1676658493034_0.29619125728465345"},"_hasShrinkwrap":false},"1.1.0":{"name":"react-modal-global","version":"1.1.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"82e4953137d992d9bedb85dd2bf3c758dca6a89a","_id":"react-modal-global@1.1.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-SRGlk8uVDD4t2vM1pIlKctFP2Sdnvk9gMkFDw9DLNEun92vdEI1gdb+fQqXbeF0CljgZrb7ylfHkT7+h+Y2s9w==","shasum":"f9bee3f7d8b1dede0665cbc5f28f83968ff66393","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.1.0.tgz","fileCount":6,"unpackedSize":26465,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXvyXLShNv+TYxdrWS9DGlkqe3Y3LFeVh4XqGFkDO3VQIgZ2IgpbBLgUkcftPF8DCSMwaVmBwfw/u+rJLXg+Yp568="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj80UcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq/iw//elPs+/2wKmfOXH2VLgevoBdJg8FichCA0eSjT++fKa/51WRp\r\nfo9mk1UN+v4F499uPuW7G0xEVDsXL5FY5EAaTvwRNyTrr67zBC9Jv6Bzu3aL\r\nkrSDj0w4pOPGOQZ2gCj7wcUcmcb7dPdxiqaRtvhrQLbVoIUGT+kmvyJpmzAA\r\nKOLMlFtZEvt1ro3Zt/lvX6YXix6Sz00Co99CKYDcXxxlTWsP/Byh06I2feEs\r\n0SDbgd0ikxg8zDNsiX4wTvSj7vhR9ISAlFw9K1kJcOVJbEWp59Bag56k8WQ4\r\nwX8Wx10TGjYoLgv8YueVY7K5L8FlV3VHmEc3UUX8J2Xp+/kpIwD9YiaSMjFw\r\n5We2cryfS2PLA2MbhDqI2gP6aFHi2SnIjrD+EZstVlf8QCXe7N6+7iXGp/Bs\r\n4cEsx7CU7UMFuWx4Y3TZ8s/n+tGce03OcmeT+81XTvUiaFYNsZ8hpUMqjmh7\r\nMJ91hivXnOxrl+RZQW9Cof/KZIEHQ+bmzq/Ivv/B1nCxNTvqUHM/554osXHw\r\nCTaJlL9RmqTqN1aV1wjmaIXDTrj2EWqbD5u8In6MSFjRbi3Bp9sD9NfQPKPI\r\nZuKwd5QNUtjZ9Ca+3A48jHwJhoA9j+agRNBSfX9V4v+tdE9OcUpOt1FBi2DY\r\n3T7N9u8VW/PYUgcTmqYR+rOubtIaddjqBnE=\r\n=qgwU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.1.0_1676887324607_0.1008743062594688"},"_hasShrinkwrap":false},"2.22.2023-alpha":{"name":"react-modal-global","version":"2.22.2023-alpha","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","eventemitter3":"^5.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"166e9567e2c98cc5f63933ddb571e5fcf838ce86","_id":"react-modal-global@2.22.2023-alpha","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-okkkkk8iEmz/wjz8LM1cjldDzR6enFSTxHaP7WW0xYq/qRAM95pPu1nRz2hW54WxNq1QLCfbBwLBmZcv8tsMTA==","shasum":"6072f74af918cfdb3ccd06697818ac54e8dde68b","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.22.2023-alpha.tgz","fileCount":6,"unpackedSize":25526,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCqT9DwToCrlgJqhtRg6reTwuk8bykCj72sPbvlW7fEnQIhAMeG4d75MrI0il2hP9kMZuoU11G2ZoOzdxEGyYAgWEF1"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9ZHRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpubw//UStSfg/oc3qXFeG+H9qiSqHMBCXLw2Sskjpq6WZJI21PsNG8\r\nPP+H9iBO+R7vQyBMw7NsHecM6HpgezD1UGLEvVgWXjR5OpYIh0vpNQ/aymbJ\r\new+ODQmZnmwz7XWDPU2DJifyWzqvM1J6d9BBSyYFrV/qFDmN1Q8b1ShDCjV2\r\nowRxq4t/uQqJjtsDVoNBKomh+LCMlGNeUlUzzrLIL5dp3A3Bk7Ys+ESyA3vr\r\nxjRNT/vGbAwpvR/F38wBdNatB3nu8ywUvjnpCtFQ8k2CXIS/R2rsPlHxJ+ML\r\nqKAKTuDaTpeMF+HRbjHwB0x7sPvJTw5EstBV89Jh5h+B+RxYpzckZUDorp01\r\nl6rHoaQNmoMu4frAOHgtND1wMM1Mf7ommYpUjo23o80CvOxcdi5AhP34401O\r\nlfye8HUdNGp8/NcVf5HewXPlU1V6y+weCO99mBGJU2LQP2/vCjupRU3F6Gn+\r\nn7YJTIxYaGQlRlEshuzTAZxrxS52763UALsQ6+czDBruTZNOsMuJlDN2Futb\r\n3TMU7zNmzL1EzniSN7nUFYbMHddHkya2DReRM1Nn1iVPFM1D6srMz0ufrT7U\r\nj94uRVt/SY6qdpctWctAtPjFBxO9vUQguqYsZogfVc1LIQQVi5SiqExy7Qwa\r\n1v46kmEvcw5jHlNaXZOwZT43IR6IlyA8iA0=\r\n=T8PO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.22.2023-alpha_1677038033778_0.6854266110754186"},"_hasShrinkwrap":false},"2.22.2023-alpha-1":{"name":"react-modal-global","version":"2.22.2023-alpha-1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","eventemitter3":"^5.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"35886ec1d55ebd89924cfd7647c7ebd8be4d59a4","_id":"react-modal-global@2.22.2023-alpha-1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-fA1H934mG5JftA7ivIZrjeWP7RFT3ollzrYreN/Fx2Xa+aZNmm78bQ27nH8qgE1rlI1Ner73P0hVO2ChnyYLVg==","shasum":"da4918e44e1370488743e6d6b09fce08764c0067","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.22.2023-alpha-1.tgz","fileCount":6,"unpackedSize":24997,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG3jlTG32FhJjmz10C0cfOVa0ceDrq2S4R4cCGr3KlGRAiEAowN+92ir/SZFxVPQ1eTr8MHBor8xn36iOU/3X7CGFDM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9ZLBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrdyg/9E6enK8XhYgCnChIhoTD94+85LaPU9m8osCCnFaVi54YyTJmK\r\nn3auRq4KF0CIq8oCAxWFbIQmyCP1uxUjfd7vInXDlXCZkkNnCi6Il2ZRd0V0\r\nTk3w3kSdsQc6ZkqTLPNhVC6TJE3m/v1jZ4LkC2XzNsTVcZxk9pjU7b3rsZzE\r\ndmljg73xa8rNy0JFmUSyNRHlpLxXnhwIYWc454PZD7g4RbQmE1kXW9Tc5bgr\r\nBZI9v4EP1OIZSDma+bcOCvXQp6kexjBLkXF3K3aWxKUHzQA4dDhqqSYL/+0c\r\n6fON92L7BlZGkaj7GVqxY/A5JApgXShCHlMkbl7WxWgxCwsDb3WsRi7ttMQy\r\nuv+9CWsaPJrnHA7g33dvTIUOsJ8HvGUtizTaupd/85i4J5/w/5ASscAe8pkz\r\ntY4XD9PHtY8SQIocycT6P1o5VDqqpwHR7h1unWo8ze/Te8sZwQUknt6bZMqt\r\nTIT3ss0fATpBykb2c8zCA+Ny2Q3k/23j+hnWHN8G2JR9O0HD/HQoT8kh6+OE\r\non02NL6emeQsEDzrbpKUiOWxXy4Uavmbhidd6HLsqktwZGnuSLA5zqPeBWzJ\r\ndHk/T3bg93uJcKJh6+dbq17Nv1E+7rcXWaUTfMOJfr8SP1OXMUzdGYaCM1vd\r\nntGFi/xHmByWDfxviJqdTQFCqyIGXhQz1TM=\r\n=S4wR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.22.2023-alpha-1_1677038273246_0.10553452232292693"},"_hasShrinkwrap":false},"2.22.2023-alpha-2":{"name":"react-modal-global","version":"2.22.2023-alpha-2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"c5fab699105216896598ae0a452af92095b79f66","_id":"react-modal-global@2.22.2023-alpha-2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-RRdo1ThjDP7MNOHamM++rkpNbL9Js1vmQT6EaxQMXcsYb2vgXQCzYTqeJkGoHnALPj5htlFVjHBgx86I4klXWA==","shasum":"d1cd1f2ec99929c3a08df059aebf4a3e993f40d2","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.22.2023-alpha-2.tgz","fileCount":6,"unpackedSize":25021,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDNdJ4mAhmzeGP4PAVHSXfb0nLsJ+BuYGBAKrhGaR2VrAiEA6LW0NZrN0A0X2WvvMMSMKgyKLarWkqJHNblubo4HeLI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9ZOTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJMA/9EZzqQAGtTc0WN43IpAoBMbn+WWdU1ZainbMRjL/hu7Uq/I0D\r\ncghbjlQxbjl2KhIDylD5oQNUqk3Q0Mgsp0gWryI1XsOpRypDO0u8ltWr2Zmh\r\nMcymDNXvuyjY7ibPvUCK0IDKMapFfwNoYPVXFszdBGl2gnyXcH9SEO9yOxwk\r\n3Qwv/FTlxdBKJmeQTa/nCufFmvLLC17pdBeVa8KcFC4rZihwq7yzHV44iDwS\r\n1xtq69rCZEJFi1pJnOB2TOqnnNcYrSiEP2DUEYEs7pm36NEHN+DxuvFafOSb\r\n7FUn0n9KXIc0v60/IyzRWw+MvFilKweElJX5cQrO/zfQHsJXx2VVnf/ZcOvT\r\nEzL3ICrBQqWZQeVDlPlu2LGwqBlICke3ng/YStApH8mZ+eUJzoqSNBvf1RP4\r\n9u/Pvl4iQASmRpoEV3GvS9qmvTT5y/6U/NjapxgtSomZalyrIsRoR6slmTds\r\nTeSm3i7Zg3Xsh+FQwlOTyjtK207aoAf2PD+Hill7FkxLLYX/ctQWyU8QEn43\r\nfJAZTVeMn8zWNsqc5AHL+/aVuSm4cJoCiMGNURJT3QXUBJG7ae3v22f4/p3q\r\nUKfg1TE065Z/bGTekMR0YVhFt36Cz0TeUC+B/O/mLMxNVr4AwgvD8dqQ8pQe\r\nJsbxPsoNk7ViY/cv8pQCXR0OrmezShTyk3k=\r\n=CCRf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.22.2023-alpha-2_1677038483151_0.9922686273036376"},"_hasShrinkwrap":false},"1.2.0-rc1":{"name":"react-modal-global","version":"1.2.0-rc1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"7df30700eaae87d3d8220bb5031cc5b24a7e12e3","_id":"react-modal-global@1.2.0-rc1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-Lfh/5ALO8WOtdNHEyI3iktPb7P2weJBsvUTI20+oRu/O1wEwdFAE2p97ENkWi5m7clN0se/FhOdLJZTFfckxrw==","shasum":"f93d6bb3460b8ed681b6117560d23ae2a8e65d47","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc1.tgz","fileCount":6,"unpackedSize":25437,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGY058+7/Xw09+AQPgn238iIKYZJVt8N0Xo2eU0WbhV6AiEA4CjlXTos/RhJ5ocUx6OcA1jLUdPuvFMMNfUIBj5tieU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkFU31ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo+dw/8CcTs6FCEHD5Uu+qV1wsPeBh4LzdnEMaQ76jEORxVIw/mEC3/\r\n88rMLMkuWNBKsIxgaSNxlVcHjzcE56gCb7M0Nn60nGK7O25mOCPZwHKbhNxV\r\nNGul+W68q5CImg7En3j5hAa4PjtnYLGVDfzAKcHFunlm1Yp1JFhoSSbVtj+l\r\nhod5mDTMHapcrAZ4cLondofoihvfny0wjKcRR+nfpSP9jpMkTSccBx8Unbvv\r\nty3sLfQAaeNDkaPAbLI0uGnfD9oZp0kLTvv9s0oEeBdU150o7Yk6Gsnc5/Ra\r\nNkkDlh5o19h4nhgNqrimu/PeONS/1DZKYXYGYHiYfiPytp/Xjtu53J/ZYBiD\r\nQuwLx+RUcLh+xXG8x6hUDHXNf9GhLOvCA2ksTSgZgnw3Bz0X+NZZAYmIr3OJ\r\nESMgfoWXox6n6Rdy4rwMEDPdbGl2bvbWgZNAPrdURhC4L+2Rle73kaPpBUrP\r\nM/Q/ajAykjRO++8QGj9SJJ1uzP7cIz1Tttti7wLZ2W0dft1CPK4QfDAyNxc+\r\ncoOFyfTN4g8VJw896YZP9w5Htgg2P+3JZFj1s7zRCnflrRTKGvE2IenklCbP\r\nX5vA2jx+64VF7zv87sBiYfdbKzXDNeXkz6754ynvnJ2wj9Qi5/1z156l+XV8\r\nIpLklKQ6Rx940bYGukoydt1xf6ODH1cZOGc=\r\n=VVAb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc1_1679117812984_0.3274934692355844"},"_hasShrinkwrap":false},"1.2.0-rc2":{"name":"react-modal-global","version":"1.2.0-rc2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"e7178ff2298673c274e19e887f97ab109fb72e1b","_id":"react-modal-global@1.2.0-rc2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-yf+iWc27dELxKAUwpJKirB1HHmCXIKtiooznKaAG9UfJuR1fRxmhExPX1YWzzQflpRDX2RMu2pNb3PCQ6kPGAQ==","shasum":"299c28c7fd91cd5889cc47c8421ffd5e34abfdb5","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc2.tgz","fileCount":6,"unpackedSize":26613,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCgO+kkCTLUnbqvZrVVRfOBGvpBcdJy1xPQUZ7Dld8dQIgO5lPROkkL3/bpt/ju8JWZeV6IYUOhX03FInyrLsugjQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkFVGAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmounw/+MxXcVYP3T2Ml7m1vPJnp/5NmN52U6dc6NB3jTXGx1NcUKXME\r\njYap0XDSfe1BfKo7ZS8LAbCUO572BkNtuKUQIyLz55bYaAGYsdWlXXgD6Uuz\r\nDumaMHbW2WGS5rmLOCrPvX9P22wu1MBwJAHwSLbvK7NmAvEXkdPR5uyMQEBC\r\nVTOB4MJLBXnyu87MpWMxt6cdZcUD/VnNumXDWgCWGWNNWwXzJLmBa9EYepP4\r\ns+FOXAZPqXCI/pd6segwy/dxU7yFvREOAoFW9ZS2LCXoA6L5Q9Os0I6n5BXN\r\nPPBEWzgP14rqiQybXpuFTRRud4bSD9b2YiPRdtZjJGZTv3SBlhAOe+70tiPZ\r\n162aI/nvbDfiMHDGl0Q80pDGS+5LnkgAnpFyhDf0aVZ98/FM0OGWJTS1VjDj\r\nAp4IPBwaRDxjATxL4hivu158neLerhtd3ugeJ8VKXPLM0K+IBOXWqj8M4cNt\r\nUOiuL1U3o+lrSCiGu34pwMVNE2Yh6rqSarVlEEegrmESqW/kKoUWBWWIEkK6\r\nws99hJsUEtISfq8dg2ujGGdAYsZ33TEYFM19Z2/zqFM49devcFE2AazIuAmv\r\nXDgl5g72dlOVDtWyeTsQ+Ry+XDFWtHDFrn/K0a7XOm4MPA++9GDDBZb/zSFF\r\nLSki0CEXMI9ikPN15MFUf6RTZcSvo4GAb9I=\r\n=bIC/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc2_1679118719857_0.6078228446526459"},"_hasShrinkwrap":false},"1.2.0-rc3":{"name":"react-modal-global","version":"1.2.0-rc3","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"2ea46d0a5049cf327f0a444f0e17bb69c52d9d3f","_id":"react-modal-global@1.2.0-rc3","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-879GoknI3LjJ0GfQfZitkMGrisuJFKHFqHWh0mQgudcTn8+dtVJ77fqSN5/LEzcScoVcZHeKiQyJLslz9ESpgg==","shasum":"03b8a75002d36b65b2a35730554e6fa8df0628ae","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc3.tgz","fileCount":6,"unpackedSize":27962,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEItwSCfDlMlswRI4xmAS2+IM7jtGpxlrT1iqwdP9Vl0AiA4ueU6TvVobhZJE1jTJA8OuMclvbdYFsdUU2SQrmJeUw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGsFtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqLCRAAkedAX2PbxP1Xo1KG0HP87UeIuBHffpESBJ6WooLJfDnuTlYy\r\nkHDH1uCeGFSnrHK5vVTBE0MwhybJGjOzkC8+A7YXRZY9vUR7FPou7USirN2o\r\nLDHHFWpvLNx0yVcX5jiNk6mmmr0OPwrZ6o0j+zbiwn97OM3zVIMBAZCADsI4\r\niZmvsVdynIY3ZXAl6GAfb6Ts/TynXtb3eT1OwBbXy6zrO3mxXDfW47kEPFtC\r\ndCpXoMQCxgw1fNtQzZAb5t2IgaJRXcdOtPevdAZazecwllKvgVot/kDeJFkI\r\nMr5aE8m7Qc1SsO2e1RKfJdqn9GCsk/PgGMMHe4Tn6Vl0mLyZSuD0AYY9IoQY\r\nNxtN2FjmLLFwg9HhFKUBAoaq5WeskEqJUny9kmw8Ob7J0dHgqtX66wf0I5cm\r\nSpNCvv+ZxUOJCY9Fng7uJ5n0Sw763iRxfOB7d8e1Xzi6C8WWx4zTeOHV5y5+\r\nDy7UuSA0nJ9MfVxG/yQXdYNiSVHhXjBwyoZe99CENPhMVL7oN8rIYUaGQfiT\r\n75an1XHyHS4L1GtQqfi24BeWP/TLhnA6v/g0VkyUSpj/T8QGhtrVrPxksz8h\r\nKq8LK/26gGWEIaXYaSG1S0c0SLmBvmkJafa+zmB/Sbm/vciXwa50p+Va0z3I\r\nxmnHcX/0gXljhzALIeUI+wlayJp8JWRSvD8=\r\n=YA9w\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc3_1679475053435_0.4644426326083628"},"_hasShrinkwrap":false},"1.2.0-rc4":{"name":"react-modal-global","version":"1.2.0-rc4","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"3af15eecf99c32d2e22ed150f1115195bdcf060f","_id":"react-modal-global@1.2.0-rc4","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-Je6UVDly7P9s49vygE/SKWrEMRYLf03uCYeqaJiAKixjKBhfViBS8qtkaxnu04vimSE4lSq9miGqlGMmWZagaA==","shasum":"2bd773350eb1408b53d8e5a7361ea3bb0bd13da7","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc4.tgz","fileCount":6,"unpackedSize":28038,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHKozLtZEvQGJsrCJOQYaMBY9B8+gYopIYTBM+XVfbzHAiBJMufq1m1JSXn8E67+fnIltrkhKLejNx8zWcycg21XvA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGsNMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqPeRAAgZBG59UHqSIG8yhM7glBlCQab8VKaFksVOk8SW8VnHwbjAYa\r\ndfs9kjxUGkpFhHROOqqlwaVHEb3WH/UpCeqVywj2NI9+RoROEUC7ldoL/rr8\r\n9SNCYyVgBqkRBqPjWehryWEF7NVd6hOUf5eM9jHfwVveiR+6IGOiOtW3MG+U\r\n43Dl6QixERN5VqbxJbhjn1GDAI7EMKCGgUDlsyYf8JAfPyQBPduiS5o/R8/m\r\n5fQdU0+pb474Pbbi18/Y/LwmzFAN9Ss0RM9jCnUyxw3PFgLK5VijEj9kVu/c\r\nElEIejR8HZB4yGx579Uf9e7isHdi7JSrZPcJC52MuxewBfka9Q/vAYWgUnaB\r\nSqfSCYT/IfqWHCCSknt4PWCl3akwsWxYMc9tApE84MxxiaRU2DTLYcN40NDj\r\nNFZ7ppxyEhCpyvqhOWraoui5qz3k7JfweqaYxaVh+F3+pPRXJxgKQifLR3v1\r\nWLAsaDdWNChyjzZqbpSUUfuWSXDc+ZcF1o4zAW4644mvDJH0cinvE9AlunC0\r\nDx/3yvzCUPgsLvcgnu+zmWbPoWYggHorVek5qOCCdxhwHpOY9kYvyoGPtAnb\r\n7/0rwJ41tHQRsEAyREeUsQNc8DKg0ykktPbiD13oh6QmB+dOCWdMDEgjxajh\r\ns0O0TJPiAS9Sih+9vf9F2UyOPH7DeOLKEw8=\r\n=YMYJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc4_1679475532082_0.45919566745424656"},"_hasShrinkwrap":false},"1.2.0-rc4a":{"name":"react-modal-global","version":"1.2.0-rc4a","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"a639629a4334e897b02a1dab8627e56b61bef6b8","_id":"react-modal-global@1.2.0-rc4a","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-wy8QIXZ5nrnfwGyEIaDb4HvfrbsgS3/Cn1M/fCwFKU5J75GpqH4nNXpeRdRNKPoUNCQrBb4UPgP/kQeB2inIbg==","shasum":"df55cce333dbb9802091eb17f063ab5d74c7bb27","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc4a.tgz","fileCount":6,"unpackedSize":28037,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEWAVZhkEuT6HrQM8vF07tQGV7tatMEKZktg8wmO2B/sAiAiiUZlPXnFo+4hJSCgMcDk45/cHX6femneJ10mAUo+kw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGsR6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr3Rw/+OYe3VTRaoqN8l1eLLDq/9gIzlCv57EuZca7WxPHBxG1s5Zqg\r\n0HzUXTYgXZtbn1OI/4WLVvhEeK8zd4MN3dUL1mRCtlYjOMdcSAW2e/P5b3PU\r\nJTuJvfv7HjjM1uXqCOB+zga+p8/pO0Pf+EFpGFq4ENPsNAmvhvsWZofBVo4U\r\nLA308eCneW1JHVcAcQ9Me6+9vsR+eoWphzRgILBAwKoHYOUMqR9G478vxHG4\r\nR5ckUblEF2KmLgrut3hJ6phO1HDrvZl5LbMA70/niZ4EpnO1rXFl1ZYwRd/3\r\nx2MqyivgwqTKuIOv/PQqMVr3vAL92V3yAF6tvLuzFoAfHMHpTkk1GApr3kMz\r\nzZAZws7D9lBbFCfwq+WO482OLPd1/ui8UuFhvN15XKqampIluq8w/IViFJDK\r\nPXi6B7So6cMqk/49iHl8lCxJDoJ60Ef3JfCN6d+jxrak4Ky/lWLAwyPvNrU5\r\n9JBIXEAtnu0D1ST1uFdm6nU7qK0eGlxiuDN94yL4qAdsnxpBr7JxoZa9ckUz\r\nMS8oe4Ob7vIl66Tc/ZQD1Sx/BCqLnJtLE2I0uJc4DcY0LkGkLykSyqYoxJQR\r\nY7HM2N6TUvqmk6ZE2q+1fi7eFYJ/zB2UWs52MCdHoL0UBNbH8h48zK0kfm2F\r\nxBac/apFrJHCexCSG1LUk6pTnSRW3l+EwlE=\r\n=nDAX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc4a_1679475834410_0.2534507548608156"},"_hasShrinkwrap":false},"1.2.0-rc4b":{"name":"react-modal-global","version":"1.2.0-rc4b","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"1945b3417d57e9b808fa4f99cf046dbdac4167f3","_id":"react-modal-global@1.2.0-rc4b","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-Iqoo9l65lpaU/9wjOSVc7nZmi5NuZnFWOA/rBGdGQEkkxViXYdM0TxmjBZeqhNfJrr1880lukjPbCcW0H7tVHA==","shasum":"92f9e7197121740ff99d84bcfe6be3238da8c204","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc4b.tgz","fileCount":6,"unpackedSize":28023,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDn5CYYVlfiADK3r6O+zBxEGcelg9YlRWQ3SsM/giFy4AIgWr5ZNXIM85V5z59KBpPSV05vigHzTqvzW0+SkhwQWIc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGsVmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqXcw/8CpI8OA695twdvN3FcsDQB8fmt/iNCibLo2AboO1NzdMZjmo4\r\nReeUX9/Q5TUJoOZK+Q/7Q/KHzaSrayx+CHRdJRCnA9dkQV/Ni5SQeLdHl0Ud\r\n1Tu+AyoTae5Lznj440bGv7sElwKw7t5RMfZtvO8hPpC0joXlhd+A679owKjw\r\nCsfq/Pq3SmUJReq+XoOfDpmZGtkxWG42+popAw7Jm3VHP/CV3oHbmBfOxHJR\r\n1JF6HSfHbn2ECxmSBugefmelqKNl5+kW/csBThE34aVz2nTXwpC2igOes3w/\r\nKs5A7KCHiJKQLEBREVVbXGR5t8cyTsYhXRg3ZTSXiOlmWzet1WV8WFRay14T\r\n9dq7MRltoCCwvtawjJeFgm13ZzXU30uT2K2Bmd3er1br773x2dyrzgiPpn+J\r\nxwFuHdrdtn74CMjEA/aSW3b7+AzhPA72JJ7LZDt6P5cKJOJiGt94TSmqrPp2\r\nky477vQWqJsUHa1M44u/0sYa6tI3eXdFp8okA5YHUJJubNr2MLY57/GlB37u\r\nt1iv0P/v9smDDHRvKGdBDBRiWQFvLeqJ/LkCAJpSGQXJXlPOnUFybMly7wdC\r\nGFqiBsUkZodJy9VIiWLP+sZCOJgkhZy8BbU1uJSMFJ+WRJRzhnu70PZC7VcC\r\n5IaHVWj9i8O0xG1vc6XeLwGmLNAhkgbzfUA=\r\n=5Uli\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc4b_1679476070644_0.2771234448156197"},"_hasShrinkwrap":false},"1.2.0-rc4c":{"name":"react-modal-global","version":"1.2.0-rc4c","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"295660ed3b86389821438e0a1e204af73975f2f6","_id":"react-modal-global@1.2.0-rc4c","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-Dr7WckZczAWFH9Upu5RbxD4i2qtZT/IPhO3Ae5BgpMBMd7mzMNDN3+RXaPp3GNS+OuiKl0Hr2lV43R868bXpBw==","shasum":"a58d0c199434dac44d118e4a19e19316ccee5fe2","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc4c.tgz","fileCount":6,"unpackedSize":28025,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVhB0eDO5YOs2gV2mO+xNvt6twr018UoAMNIXNwPWiuQIhAII+WWbuoo6JuPzZA1kylSJzJO7vq+hgJ6xxaukmrn8W"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGsYvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYtA/9Gyf3zoMeOFooBZTgFRQk/lBlJ4QgKbAuX0RXhnazZ2S/Y++L\r\n6/EDcijSljaNEjNuZLo/2BcT/YRgJPPXP/mSfHY7yvSSyblmAM99wDu8LLGi\r\nitbBK2/DtnjrqABcSt8KYtbducroaVypg5/JfkfkhcrcAxVFm7R8wwGaqz2Y\r\nHDEO3U3XqHjY/unfP+6qa9EU5v2viYbebnN08PJKerCWZ4arLKIqieIesZx1\r\naWVKocOmiNWwHUuvDSUikUTMLeCrq06/2EsN9awNGjuAG3V79JNB4/luNV3P\r\neXmH2+0JnFo1XtCKLO+cqoXTcEBE/BjKD5L7BncweZRnUU4X91KKt432oj23\r\nt8oYdGwCaN9Jw6up+MxHpU5DiAZvVdLKd0KEzltOMe9Vo4Z+PZCv5cU7cx5S\r\npn7Cl63edLBghE5GDVGSVYSkLzc9A2UG6esCQoJ+KP6G+GFA+wO6Jjv/RIfi\r\nZbtM0HxbZhvg5qc6QPVwUGehFwttpZ9Snics2OT2MHQGC+UxGkf+eB6AbCBz\r\nuVm7732tCOqNaRppJ1+nGwehpFRFNopFZjsZovjI8IcCkftbRWXx8FmNoRbD\r\nYreIDComWr0Mm6WwBZk8ckAo9f9AAANjApgdalDP///MWsTFcXytFZE7lsPT\r\nsFg9k9Bb/iuLcT0dwi1ME9abPeQkOCZMOlw=\r\n=fxMM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc4c_1679476271319_0.025825297875666564"},"_hasShrinkwrap":false},"1.2.0-rc5":{"name":"react-modal-global","version":"1.2.0-rc5","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","lodash":"^4.17.21","react-use":"^17.4.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/lodash":"^4.14.191","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"ee2f7c6cba9b99dff2c27a91b2918db911b0833e","_id":"react-modal-global@1.2.0-rc5","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-HbqGjbAf8Sumr3Y8EBasepMaP8x94gPhu7ePzm4rp1ijRtdHJfgIF9zgKwKWW2Um8RGlTUqa1GHKIKYzqLxFgA==","shasum":"4f38ef9a71b4cd0ccb0c686976a134359b833d54","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0-rc5.tgz","fileCount":6,"unpackedSize":28220,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBNHtlM780a3U+7DEzuBJRq3vyqFbKsoMLaMcEkzozXIAiAbGv3Qcw7ewynMfwLIWZFnddTJbVaL3wnI4cCsvTQtXg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkG1UjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqgpg//c6bgCXYoLg+cIr1BCBRqEzy7sjYEb2/U2nn6hzoyjFVXpuuu\r\n/s8FKcBJsrRC8XuvXohlnEOygSE3Vhc9fZbItrjGAcb5WPuFsEKXo22BiRS4\r\nYylrazOyXklhPJhuJpHpBWBKB5huNSeVlT91TIBcXqozuV8LSj/BQADzu4Xe\r\nbswmcfylSGgXhWqoQf6QWoSqxc/5HsDng/rJSoHGggoauwA4LotmOnlxt1Wg\r\nh6JD20nokndGLqbhBJY88PP2Nc/9sFSwkYfJsWQRBvnBy9CrG0a7CRm4+szX\r\nCIu2HsIpXZImXc7bbYWzC1pHixXgQdjya/nK7SjFoX/raBYVHOf0YvxPT4LP\r\nLPRXPQG4/x3dZnBVTPFwV4YEcFr28qYmu9veJn/H5zVr6l7YB5VzaCtUGNg8\r\no9Ct7RU75k/XYKasAuCaG2i8OPXjxweOwnhaDHmNccFMAH/UA09wFX9uvDdR\r\nBg64xeuXgiD6H6z5V7/HQvlbOrp8CNtFB9GRIheHjF43qQ0aiC70Eq1JI9Or\r\nprYIfdke3AIZmG3cpXbfas7ZeXcKetLM2P/G5aGHx1q3XLUp3yV8Q6wXpnlf\r\nZjMB3atmNLZ+HHWsSR1RhpNF+RnQjXZE3by501M0qV1yZa9JzzKInPEJjKeZ\r\nPoOq9ef0kVWzuGjskZIKjaU3kjSXnCiRxy8=\r\n=Ewww\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0-rc5_1679512867402_0.8680070797957873"},"_hasShrinkwrap":false},"2023.3.25-experimental-1":{"name":"react-modal-global","version":"2023.3.25-experimental-1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","nanoid":"^4.0.1"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","watch":"ncc build src/index.ts -w","compile":"npm run build && npm run start && npm run post-fix","help":"ncc","test":"react-scripts test","test:coverage":"react-scripts test --coverage *","post-fix":"eslint out --fix"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"43966dd0bd4900aeaaffefba3bb4cdbbf36cbc56","_id":"react-modal-global@2023.3.25-experimental-1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-xU+QEaxq7raFdpem9HDu3COSXL/p1/PitvKkqMp+usKhvAMa2ZSHkveB/BULpnwMh09WBhr2SrBaUg4Y884Lfg==","shasum":"d27e7dfdd9ffcb609fbc2c58ca13f3df91f5da6e","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.3.25-experimental-1.tgz","fileCount":6,"unpackedSize":22980,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHqv05hJPhWFIWCCG1yOXD1oTVbQePw5j6QvH6rXwpngAiEAol41lZGDUZIyW/dgScx0QWe6WvAf8PiUcBXZgbp+ZvY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHhXBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp5rA/+IFkkJrRYDb0SNNOhSRQqeCCdRRsjE3pOY5hoaDd+A4u5TVrg\r\nizkRXvE2pzs7uo0qBzV9XBNUrJeHolfm3y22CkQQsp5lDDUyiO+TnInMGcmO\r\nuRmMZBBJLP535tlTwZme1l58ZcgDDv+1iTW2f8xlYj8Om1VRITRsEq1QXMwY\r\n8erN/DtN0SG8P7maqT9adFdrV2sbtHAq+Zwr9b65Ya/NhbVU3AkPWPMHnGnw\r\nogA+eacBhMSgDBQWcK52MrXoHpUc+zDxvwEGEiVoyI/OP3qfC1OWYkWmLF81\r\nzFp4Fg0HDh7uC2NujIlAZhnBpQIA4dAaS7n93S1yX0wrMDONnq+0XmP1P6ZP\r\nDbvxd6mOsZId/lYaPj06h/WE5L94Rpowwny6milVDoTCdlRgonc3QPCc560W\r\nvVz31SlOVV1TbB9u4UbJhvURajUinak5ecGl2E/WjSRpUdVxCR0yPXAheBYW\r\nr40tcGAm4R6zJlb71Hw0yAaEEGRk2rKtOkeX62Tlk8OT+24fYGrJnWcOzhLD\r\n1nsG5CqsBF+OgmUzwM+UkvD9B3Vd8n4lbemtk2kFsl5CMnMINQiJw+VBuBXc\r\nvBCRj5HIYvAoOX/nNPwj9i1yOVH8mF6fyngbFPCbhcmT6weUK5eznRN5Uv6W\r\nBHAC1FVXOUU3ujIr518ob8i0KufCly0aTWk=\r\n=nZhe\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.3.25-experimental-1_1679693249115_0.5511113260136478"},"_hasShrinkwrap":false},"1.2.0":{"name":"react-modal-global","version":"1.2.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"5434b1badd970f8d23c990a67a3a31f6473c6766","_id":"react-modal-global@1.2.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-1mUL1MASODy3gHhqAOM/M/yc7vvq9mPMobeqlBI+0eRCvK6P2Q217LzhdZ7O2yWXKrMBqIDSHK9sUk1CxUhXhQ==","shasum":"79a5c1652dd0587ce0e7882901d93dbb62ef022e","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.0.tgz","fileCount":6,"unpackedSize":25483,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC+tK0ytSVNHU6vXx6VM7bS8N4hlovIiwYr0TdHgKQp0AiAFacUPC8yi+4/zzDgmXmqRkvSyeT1dWGeu49e+LZ1LuQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkH4npACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoRSA/8CxE2n32CL1Pawk8+ffLDWe03UUmtiPVjcWoszZPYTwt6ZTme\r\nWTw6oLYxWVclUuOBajIpA9WZtlIsvCSUbxVFX9dvZlGuQ5a1ltBsKbKMK1s6\r\n5qulZ0Zzz7YWAtlmede5ygUGl+9Y/6tJy1metCxS/6S8HYSdS5GpxSAhINac\r\nFe51Oz055cu0WbXADsKAbGdFo6hEMzt5StIwwgPDnvb4r3OWtadGP9G6kctK\r\nly5F03APEhOrR3rs8eqqkHkoHZGYwT6GiowljZA9OX/mDGqIz+YMiRnrLs18\r\nsrgnKGQR4lwPSjDrk/W7cSiA+9J4A3fXAXI/pISiUFfiZ30VFppyBlas7rGi\r\nVwNoMCFNMeORtIJoKfAyvqgDD6A2KI+q2g7PZHqeDZJMORubo6cK7nYQog5B\r\nCV9hv3cx3SMVYvx7atS0MHtJqLHtawhNakGGTgjcc0esqBsrn6CxAstEnXEG\r\n3pMcjIZioevYBL5aUULMnmqAucxywVn+1cpKbrozEkIT2o078SRm3q0ASnfz\r\nSKgwOM7YRS81zod2FgY84VsluS61nqYlSnmlULHCjKELeA9BCVIc5ibyTUlK\r\nfR8jlnVCe4dWoc0VO2jesu+9ZFcWKr466V3PUWz+ApmwU2uNpVMdFID4gO2W\r\nobuXez3efv5cfdU/xocvzLOjrlveD11ZoG4=\r\n=B5IG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.0_1679788521506_0.315783382521055"},"_hasShrinkwrap":false},"1.2.1":{"name":"react-modal-global","version":"1.2.1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"ec779c2433d6560536c264a23964ace4406e82d2","_id":"react-modal-global@1.2.1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-xwuhcrfmkOVBPDK/X8h+FfpsZ9rS5NXamEdLn2VRzA+nxCzE9j44cNFv8rGx0tNJJ1E3sn2HJCd1FN89Xqp+HQ==","shasum":"2a1c632515df34d6e1a287d93f256edaf81287b0","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.1.tgz","fileCount":6,"unpackedSize":25542,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCr1C5znmD7ly/LWfFbw+pyf4XWuGeD0EoMuG+8U5y9XQIgWh6L3m8oyvbf5k0tvAiA90EC1a2Cslabv7TeROMhnAY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkIxz+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp0Cw/8DufmD2JG+vKJv3/q9mHFCQTHqkAWA2HsXW0UzZ4vKnwSA/Gm\r\nlOzbMDLaLU4W3NxqwpneG+beIEw7T+3VxjIdG5xHaRUcGFZf+cskgvtdrQM4\r\n14xUrjpJHlqrm79SoP0JO6JD37TV+t/qdH3m9wc6rfYrkfLLDRTeOiAk3/6F\r\n2vwJpnKaF4xTNJtiyhAkxTcm+xQgUBmcTZQcJM/6DccPt2Lsq2XnrlLK/V+R\r\ngKhsa28q9xPrndBIFxTDYzh8HcWTgIBBC5fqAtv0PWGUDmvytvBpw6XXkjcw\r\nnSLhgyup5ly1A0kwGtPUwkChfBjKim4pFMKlNtjwuzX/HZOI1oSE0tmzqfuM\r\nD5JLV3x2PHt8/EpdmGWzvCUghUyVtN8Od0ZHrjNLA8L/GxT9IMgP5mv3sabG\r\nSOJj1ZCHtUig9xJhyQoeYci/Ex8ILqr2POhxIVux/zMcKcIbJCW9d9a5MeDo\r\nd2A5Ywibah2ke83Ih/SEaDLzy6Y/2oWqkurbwfn7TR0D5vqznd0zJ27OD4TJ\r\nolCPcNn15ONJJSNtcmjI8jJmoQrTKBHijbtNY2oHuMyDL6Ue21FMCH3NmuX/\r\n0GVPiZpyPQwqUhEv+6BXmx2o90bmWuB79xh7TlJZv3S67ukjERmqnH/xEokD\r\nK+XKYZVnkPNf0ZCnbW5AOSmMCa135eBYPqk=\r\n=e2sN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.1_1680022781991_0.057930640880032414"},"_hasShrinkwrap":false},"2023.4.1-experimental-1":{"name":"react-modal-global","version":"2023.4.1-experimental-1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"react-scripts test --coverage *"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"963c67b3757143a872ca4cec0372a410d937a4d2","_id":"react-modal-global@2023.4.1-experimental-1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-/a0YjAt5BoVIR+eiXv+RTPlos4AgQjPEvAItHdXwBvU/vqM6YzcoqlJFmadO3eaRVKwUdmB1Gef5du075cs5Ww==","shasum":"e783feb8d000cffbb153e5f85cfa753458bd1e62","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.4.1-experimental-1.tgz","fileCount":6,"unpackedSize":25200,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCqpM86XD3oLAL4PmwshQry0jK1vIxRD0OsjNtM3qNyBwIhALZ3rxZCtbJi5vaLzXvyVgvTVJIqa96Iv2FS7TyhK1aT"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJ5AHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmommBAAlIJeq9yR9peMtMoPNP3KJvdtmbHzaw93PBPHBFL0Ulx4hq9g\r\n60vyjE1sHLeP12MU1AD3pB3lHGy9+uLbbnQQ+es/j28fClDbLI/fvbpZKyAk\r\nH62ApjrrqyCglut5nqwjacpOq1t3aAe9NO2f5Z5hzW7Lj5Ji/eU8vN+19Rtc\r\nrIkC234Ah5xA74Gtn+1kDH7zidCI8OXkRhE+y99x+bFas/CjMjXlt6LfL6+S\r\nd+bYZVM1aq866CM7NUgYr26mtbsD51q78bplcwnsTyHucKfdBIJH/VCC9jyr\r\n54O5EZFYiJ267espHGGDKyAqnXULvULI3ZMVrN5uc3s3IwypEq7BnfbrvGox\r\nV4qfL3vT6uFOZ6U7LvAIJiVB9SHf8i2N4OL2+tERkkOAV+Mv95CvJmMhk+w8\r\nuoEtn8jDbfwt3U8dMbQDAukREoviHIM4o9n/POMv5YI6O1JkQs8PinmK3scc\r\nYJWZuu3Z186RZlljFTdMQ2h+920/NKeD6T8dWPOiEq+41gFsfec1+/ZK0pzP\r\n+yXvGLMojmHCAxMBINWJtUqAwJeZ/ZkaChtQAM3qHWhOLxJiFec2rs0VDtnE\r\n/WF2FP289QBIpE2VKFXpKPDblEuIVAhB4fsUrp15BZCExJ9OV0kyUb9aj3D0\r\nCVuIwVSQrYA568F5/6HI0I9ydBxJtaQEExs=\r\n=AQho\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.4.1-experimental-1_1680314375329_0.4802290440453745"},"_hasShrinkwrap":false},"1.2.2":{"name":"react-modal-global","version":"1.2.2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"gitHead":"03ffacdecd3995d3db51236bd96dd592aee59071","_id":"react-modal-global@1.2.2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-0uthXdYjWP1fB7+4A4QMnjdEnPVzf49c3rISR3vkPcNot1B639fjo+S/R/vf7f13glj7yucnaLNFxq0TlGM1SA==","shasum":"330ab24f5343f828e982592f079ab1b668ca94c6","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.2.tgz","fileCount":6,"unpackedSize":26282,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDhan47LLMjQQcMKTH9/mXOznV7eQoUi9XLdx58e3IZdQIgEpnh9NT+WcB1Abxp9vAVsGwuVoMItFr/0Jgt7A2ETgs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkK6FKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGQg//WSO19jt7NUm2PV38PMrkL4DCwYP6BwZcTRm1Hu/4QgkldnXz\r\nfryvs459ji7N87zZRNhM546Kvq6VT/FGnAtQUxcZfanVFoQjFvHg0uMoy91l\r\ngm0RaMjkTwbtuElp1noT/VvhAJqLbRn6wY6fL+V7yqPd/fnQ12TZ7P/vgEqj\r\nviuLczUnB6weN7F2XXNzln3lL/WzDQyY3irnP8Y6kV7JwmL57EcVLPb0lzx5\r\n5e77x2qk+zUwdqyxrMbR+nXBX85vag2Axe/5bJWwjRMga1IrWyDk0PTPsPFw\r\nMPYl6ha8gPYKpvXOI8Jb2vhNt/m3Fe4v19ikLso9PECajego0LQ0QOZuZus2\r\nOMaT7ne8Ywo+5dnc4AkUK86Ny0MwaFMFuk2jGwrSQlCZAK1PsUsTygNkwMGS\r\nYr7RC2dzauzDURflZjBJVtoFkAqmsTrEEKeTh8JbraTPxI1kPT9ThVeuZtNk\r\nGHmMibPWFDtP/mMuuEn5QUPWD/4+i//as/dv6EPfZ9Cq3HLaB0e+idOxG+Os\r\nOcRqTPcVJ9OZX1U2/SU9BgqUqd1pomkBtATXWuKyf594uMiNgvGRGi6KvkeI\r\nMqxwRtkSfsDHmw1c+PloX1eqLbWjIWklglXVUrCZC9Vj3tHkTmvbkmkO9Bpq\r\ng/7RpV1t3nlGKMam7er8iIOEeKEdu5G5PD4=\r\n=zUP3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.2_1680580938437_0.5604164119598158"},"_hasShrinkwrap":false},"1.2.3-rc1":{"name":"react-modal-global","version":"1.2.3-rc1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"09a6371b567ec9d226c012282972eb3a8bba931f","_id":"react-modal-global@1.2.3-rc1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-sXAOt3kGuoMakYjHWGdCMBOiadKZct+OhmFcMfBi1kaE8ElNR6z8RKbpCbKxRcJ5GWskFueAYhm0k0ZutUjkIg==","shasum":"07a03171a5bdd63f44637add4c03ed0f5753b640","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc1.tgz","fileCount":7,"unpackedSize":31782,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHNbsiaFtPzIJAk/n6vGlApu9/5V1eSG6c4t+xegxkItAiBRljfl17YziqTkoxDrU421Sjd3OnpzNJYUeXq5b4c3BQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPUtPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrfMw/+KyUkVMhuLnFYkYFUycDpEtdUz8/uho2hYBzdWP2tpdwuxmJ2\r\ni1/HTh4oeJVyyCyL3LfhW4l4xxf3tk80JAu5Xb3EPXWdiQCdTKZwfkIOkRve\r\nyH6tvgz0vRbgQgb4SM6MO3Wa6c8oBgNuzvOqfncLQW2mSd7CNhHSabq84KWs\r\nIZzqKdibebkToD2uiyAkzIjnAh4Jz8nB+h+ouF3hFnNyY5sRUL1elOIwrLKN\r\n6wttzqYw6W73xoXgiLTnPHC6S4sWCq9BeF/5/nwn2JFk7dsKotmqCwsKKym3\r\n8fc5M/CSZ0rhxX8ARZ0Rh0ECocpUJ9qoXHbpZYh5fLAUGI7hEM4CwHyXSnJR\r\nxWs1Is8j8iSyzURWCuaqN25ui5sk06+k3fK6KjJhKvIKNbuR3i8hxINLPDgy\r\ncKen8hDZGv5vAOnge7tL0cUX55dWPoqMrfeaXUuxAMOkrQFHrK0u5Yu0P6RY\r\nZcZbvDJ98oaMaz4XB/lfZCpr8hvNkv4h0SNllgcldKT3wolL5AgPKESbyRgY\r\nuAdBV+Xq6RiGFkuQZ7n9yKPREKQVPsB6PmaWj0JCaOByq1oRzDbPth+cC6iY\r\nSVoWZhbG284NfIFMHlyXS7RStRjPElN9sOmIP18X6DI9eb9iiqKJ4lgApKeJ\r\n2LEEhS3ryTHDvWcMDY1awBch8z+Oe1C/W+E=\r\n=PMWa\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc1_1681738575679_0.1568837649164041"},"_hasShrinkwrap":false},"1.2.3-rc2":{"name":"react-modal-global","version":"1.2.3-rc2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"600939a486946a892eaca5b9a8cd6b63d7f195e0","_id":"react-modal-global@1.2.3-rc2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-fhK7rEU9fx+aFiAJpaq639ZsqqtB93RddqqwbZlU8cyWEeVaglj9FijmZF5J+04wJpEjQWzQkzF/jNtjuvJPQw==","shasum":"cec3f98582a811c46df0c092ed471c7f3faa0808","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc2.tgz","fileCount":7,"unpackedSize":31970,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDj8q8WtwTt3J0tqvKs1eUYeAhHhljTl9NUSzO2qPwseAiBjyHc+BOXwAvWgJS/eXU0/W5wjN9fJtY+IZ51jXm14IQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPVmfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrABA/9E5Asza/Md0L3u00ZiTQzZXgoijcITd6Bfl4t+RP3NQEqH82j\r\n0gcpnfvCZTssWaeQGM8U95Nk/TJWP+8JorvcXDQSz05/fNdsrmjZHQky2bFq\r\nMpE2qv3GO8SpCcdbVq/fCYddCg1vv24+ytwPKsleijp7Oi+6fkx3MUd73OV1\r\nXrJpr7V+iaDgZfARijNCguD1NLFN2eo3/esqLXVuhWXykyDXCoevbUZy4moG\r\nNYiG6q6O3NBSRJc2VeKdJzRVa/UsBEer3WcDFYcSeLWFf2MR0BmRQ0GGSzDN\r\nXTPsG3Hm47cXzQeZ2O/C8BYqlhMPrWm3Sq8ButDETW8kYZ6TV6xREk/V0wn2\r\nK0lZqPKPvvXYMLPLfrQPLeN3VMLm5x4dhRm6gccf1xs7AnJtE4PQQE8ITI1+\r\nhHR4g+ONyJrxe2K4pGS246xnMcUaMtKomm01lRaGG7reT6fG4vUeDvFdo0t9\r\n2ibO1Yc2hWEd4ySCdUj+kpwxjigZfGJ/41Sm+s6ewDTnsFTznwijZbTa2r0G\r\npsg254VYVUfzWQO4srGHQ74re5MLWAVfgYr+GAwKf31wJls9aBxlQBLz8MaN\r\nO6CJXcih7YKc9k9rdTdXWP9cJPJU83xZ0YYRywSWHk+v3d7M+Q/J3iS1Jo7t\r\ncmo4m5+kdIZWOFVyYJzUUMotQinrgwawsLk=\r\n=ABaW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc2_1681742239778_0.8138831817951808"},"_hasShrinkwrap":false},"1.2.3-rc3":{"name":"react-modal-global","version":"1.2.3-rc3","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"7ec12b35b44ec588b77f7aceccdba7cc4d6bd41d","_id":"react-modal-global@1.2.3-rc3","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-ytrQ4Jxl+J7j0wPMLENsjd5vAFKEk8NlY5l/weBIxoObSXNN6Znn6Hqixw9kWVPCM0Hu5bd9gCwmyLyrnzd4XA==","shasum":"19ed59aff91e57ff083472a0ac7e3c6ed5d4df85","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc3.tgz","fileCount":8,"unpackedSize":32044,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCiwwSLWHpnaZ+bNvpwnet7UHz53ILrIcUXT67SJLHOXAIgDIOlyhVDYILeQzkc2bNBMbRr5eEqr+itOSqhiGLsXLs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPVz9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmogog//bPDOeTm2RjRBEtyYwe4sB91Hsw/VSwY8TXK3/awfQu7toKIh\r\nE6uDgCz1fpQif5anPMNeU0YbYYzn6LZ11hv2EnlbwQ0L8vn3qHf1YupxeglY\r\nHdlF1a4taY0xp3a+mtYrp+em3tAp+7C0S0cHFmMnnwhr8/ZxjNAo9Xx++5b4\r\nRa6SQOLNP3CFzExWmMbsi6gGePyqFt86UCHgK0O0cSQWfgH/Kiwicz9EEFSx\r\nm396lLDwMlBBv0BMn76Xsw2/ut0Gwrxm0cLqNkKk0Jh9oIzKgcG/nfkTR5Xb\r\nIakanLCM5QVynOu9OCAc5KC8FSbG3TUuYGtAxiWMFaLMNAVVSj6PF2/h8Dkl\r\nNL0PPAYwabOJqo4QdwwjSwPUDjOL11umIiefzc8CBTk15n8d68amEw8HhJhq\r\nGVBlzssHx3SouF/I/dMu3wsjZdoOzrWuGjnXIVs6aLTBkico5nJ0YSM7/cAr\r\nL1198J/vpfHrrW2eJwPGuM3Fky0QvWI3C94wjVZDn5shU2+uHSfQAkmMysPQ\r\nIH1AGbVcWAWuYLd9w0mpg9h5RblShaMTiijPePojUL6JO1ggXXN82TKE2LqI\r\niRCsjDluX3JrbZiLAdXuBu3+ibJ7i36vWN3ch32CuyjT412of5igUbUH/QvF\r\nNu7MrP/h3JCliHua64Rc4p4gna3WdgpwjDw=\r\n=tw7h\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc3_1681743101723_0.930050177234415"},"_hasShrinkwrap":false},"1.2.3-rc4":{"name":"react-modal-global","version":"1.2.3-rc4","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"d6bd7094df8980add30ada5a731b2b65bfc4c786","_id":"react-modal-global@1.2.3-rc4","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-iuUb/Qbvg/Cn2cClQjVgXI2qT1Qg2hGkRaRiazu8ZqKOYnARprr8uHJttcuqVdqgNPS+h+z3VApEwPgLfJjwWA==","shasum":"dda5bbd5b2f7e392ed60934f9f81843b1bc2c64d","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc4.tgz","fileCount":8,"unpackedSize":32044,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCJqWk7SMoZyjTeFwT+yYlJqdZUJBEEKjEYtCeNR+6yegIgDVEV2yicjpZi6ddAkdHR+f9fdDcPycbkqQLdNK5BN0M="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPV9CACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrcIBAAgfO2RG7W1dU8atuGZd2j6zOm2l8sqrpt2g8zT+KRBxMh/uH0\r\nuSnjh0ZigYC66DOHknAu+lXMMxGKS5RkYOZy0ZEXmf93/Jegc2gLL5yt0Ahr\r\noaAlIPngdsrZGF3bN7jqQLc66cm4CNe3ECoNOh7CPMx/F4Ytc4FxCw4rIDta\r\n50fN38d/+aZDdN7C+BC3UIBYZkvb3z+eyjb6SPGdiAQbMv3On7wqwRL9frgN\r\nIalDOLcVwAdAOcwjq2sUSyOoHBdtf1ku1W4Z65qpN0y42DYFLAQqp7OmyrCa\r\nKTHjLe8s7NgD99RQiFeh4rc0aNUe+CpjBHGMOlPxEVhUNuAwESMSL3k6awby\r\nW3sue482OrnKCMWq+ztJl9aGMg7++qezIiHgB7mRwZxwdoM/6sFEg0bbDpng\r\nN2D919Lr3OAkHHVpk+CbfFuQ+lt/gc1NB6n9fPIffgGqZ+xyVJYMeAsI1Djq\r\nIKHVMv8zYIT6ziXbj/Y6wjO73u/PwImciMhwTy5mwJ2lQCIGJ0aL438a6GmF\r\njqeTBZYrA3FNzT7CQpeY3ZiOpw6etcAETY0H1n7hkLvYKIASsnqJK28P+CP3\r\nO0VxGKNBdbQfAbO9qQQwAaHFYBzyfQn+cqMLtcZvmz8esti5zNT++CIGl2k7\r\niufy6bb226PayhIqwOF8yQnFP1ORPJfYLmM=\r\n=N7ig\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc4_1681743682139_0.11915772407303882"},"_hasShrinkwrap":false},"1.2.3-rc5":{"name":"react-modal-global","version":"1.2.3-rc5","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"d066e4f8c8c5c2bf941f7303344601958bb42097","_id":"react-modal-global@1.2.3-rc5","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-blLkuUzPYD0RwLZCippEfwMbNCdvMcSexS1AS+dGNunOJH9/vWybU2ysKXOvqRq/GTKWepUVaDbvw0Tnh/TGIQ==","shasum":"291828d74846c318cd51b3d017ab4905bbbafbd2","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc5.tgz","fileCount":8,"unpackedSize":32115,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBtXeqhnP+pTmFDDbvmmDMloWE3/vDFM3zWfncoYTub9AiEAv+po3q/zB6oZ5uBZ6ibKZS/m3MmInW7f5NyUCkeWl3s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPV+pACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrxaA/+NrVLluVSC3/CLIbqewDtqufVbHc7xE/+1TgBNQpgpcBc6Rlq\r\nNI6dy/au8ZiIWl/RDQIOJPnqQuRIoqMClX1r0AnG8Ez9BivXeBR6+HmH+iWk\r\nIBO+RYNPHTCQvBJ/kNoBZgMJyLcWzIXrXZ+jbvmb45TOWU3Zs4omDc6J3Axn\r\n6EPnak+ugS/uP7R6VVgcDwv4JHmkExCBzLBpIex7oseoA1DrnU/YAtxf+KPy\r\nOTgVC/xIMFzT2nvhFRpqeNQ7hhpQcbGLMaMoxZdA5tzQo2K+VyGtfmLIxhCX\r\nCZuDF90AKW4YLlp5BKdfPsmiQeJfu7qWQSoFaA/HBpGWbL4+sG918r62z+lS\r\nJZ/blI7Pzj9y7rjfZ3CWuJw2KKuDQh2OlcpU3ueadnGGCGouu0LZ6L5V5DDI\r\n0jy4aw1FhYzDKwyQs2OgV4dpOk3XsVJ72ZmWDnU7+BiccgLaDFnIT/aBunGY\r\nSOnxyaVZO8rdlqcTXSe+LhiDfwOC09tkLrIBXtccBJn9K4hC3wEpfgdcfai4\r\n1regkhRKWQwBbVsMF+CAUjuYNGabHyazfVjQaMw+ql15J1Dbg4InpTSNmyQ6\r\ndJ4tt+U6NPVDWNxKM04ciqNm1d7nC0F8rVvEyIA47ZkiMz5kL0qfEjrlLGjb\r\n9I57dx8H54J6rR6dG23D7QogYkFq8j6s1Xs=\r\n=WwXs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc5_1681743784814_0.835639670981188"},"_hasShrinkwrap":false},"1.2.3-rc6":{"name":"react-modal-global","version":"1.2.3-rc6","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Composite global modals for react, which may be used in `useEffect` or any other global scope 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalContext` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\" (_in development_)\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method. I found a lot of packages that allow to use modals in non-component context, but they all have some disadvantages:\n\n- They are not global (you can't open them from anywhere)\n- They are not context-aware (you can't pass data to them)\n- They are not queueing-aware (you can't open several modals at once)\n\nSo I decided to create my own package that will solve all these problems.\n\nI insipered a lot from packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-alert](https://npmjs.com/package/react-alert).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\"\n```\n\n### Create new Modal component\n\nModal component is actually a React component, however this should be  exactly component not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click).\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently focused component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\n**---This Feature is still in development---**\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another, which may be overriden by focusing another modal.\n\n---\n\nIt's in early development and accessable in [@experimental](https://www.npmjs.com/package/react-modal-global/v/experimental) branch.\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"General Consumer Modal\" (this is how I named it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### General Consumer Modal\n\nThis is an approach just consumes `title` and `description` props and renders them in a general container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).","readmeFilename":"README.md","gitHead":"745f4ff7e9ceda396312c94056b33532322d6179","_id":"react-modal-global@1.2.3-rc6","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-iHI9noRH9dsi4rjZe6mIAq8xvSWP+0X4fLp3H9E7YjA3o7uwIu9Frls2UKO0KmSqIqZ1AQWzLqX7C/3Wlm9bTw==","shasum":"64edb3ca11ee2baf3600158be7723815d2fbe18d","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3-rc6.tgz","fileCount":7,"unpackedSize":32041,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICRPu3ThjhUSZlSlswgIwjPqmsWn2Lfnm0FWuNo5uIUnAiEA5quYLbUAEj/oXzlx4NnaoeghU+2e4ZRbz0GP6V8jO1E="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPWF1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmouEg//Y9cP/JYP0x+SKpLWf5FOQZ7MtQzxnjAyCBl0fVqd2UMdTY1V\r\nhJ7KZbMB0OkZ5SB1eezcXn4X6I/8QlvZ29AApZQhhJ7YxtPuqbb0rJCq5U1n\r\nYdRi5eEzYy+BW79DKmjByUGamfd0JK3a1FvdkWoWSOAqICiaFgSE6POaxAgS\r\ndKj5jyX7iqguMM8aH4BuPBn//1i1pxsIqZ9L7zzAPleR/W+e6R8Hfy6tDvwN\r\nIzUgzGhPkJsPX30zsxmmT/ToSafdCzxemYJxjXqtLZcWsSiFEb8SwBTiEp9y\r\ncHuZ26XxvOJUWMHBR7XKQg7IV0a/3yiykr4xT/aUg+GK86VgfBsJUbkJqSHM\r\ngUzvmdbaQutXy2H0n+JzGlCDCiRu8luHwm+0jQg9wjYGIyV+hG9oupDbl+f9\r\nx2JXP+1NYBXecrJ1aRWarXFiZeP2xhkZYx2C9bgq2YVfaac1a1QZpKds24US\r\n3cqJHshSNpcVBjLp+M3Rchd+Z3c5YP99JZmrblYkZ74xLtADqQ6AGBw1iv48\r\nagKb8N06fAWKrNOhoTBc/FDMXusuCN8ro82Ekexn2RP4XP7WB5uV0E3YZ93W\r\nzuQuVozhVrOPsG6jHonKNRa14fl161tzTL7geIERWmbxgFOYCvKY1YUik71F\r\nMpncMZJWreP0kY9NNpvQpuQGOY+ndjR9FSc=\r\n=Ygy1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3-rc6_1681744245495_0.846123164556305"},"_hasShrinkwrap":false},"1.2.3":{"name":"react-modal-global","version":"1.2.3","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"18.x"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/react":"^18.0.15","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","reinstall":"rimraf node_moduless && npm ci --silent","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"311d52d0743066e1cfc996729322cdab57f8f364","_id":"react-modal-global@1.2.3","_nodeVersion":"18.15.0","_npmVersion":"9.5.0","dist":{"integrity":"sha512-NgLhWThL6RN4XeLsx8W2891MyO5OQs8j3yIcDKOejOwxWVEg4ZyYz+jD4X9W/Wzpaozd2SFExQkmOzFK3IILPw==","shasum":"5656c328e98f3c4f7686e4e38b58bec323f108f7","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-1.2.3.tgz","fileCount":7,"unpackedSize":32038,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHuAC2bhkh45KeHUQLzqgL5US+TkYcxesN86Hz6GmnrwIhAK13MoINQjH4c+wv1Ph9ZGdwi1PJ2YEIlgkhdaMcllcE"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkPXXSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp56BAAnK4D8BcxDhHm5FSmopuVSIjak8ymFGrpVhs84p0TzcA73PNP\r\nXUNgBB38yhJ34iCRYgPQTpEG7S4bnzwb0dNZ9LS2ZczchcyYK1+z5qzXGurw\r\n0tZQdW7xZXnqeLOHi2w7po4M6z8EXfMWqz/BY41l5mxIhR65yuuK0Wh7B8S0\r\nFs9uj6BKfut4jm0n1U0WzfORVkJFUE88K/mrLrxdgvTqaObg/4tzANKrvpoc\r\n7yNaT+iEU7P5FSOSSn7tJ405R1RroEZ8vsqRZuCbMwoibcqqN54b7G46lBN9\r\nOFQrO2ZYkLZLTLaiMo8zcCF+bCL41kfQ+8MIryjsr3Oon9RbhEEV1J3ANAbv\r\nm7KBjqzD6P7W/PUBVttQVaiyZa4vmafWD33B/Rc+an6vwK/D1+r4/B84+KA5\r\nQad3w/hRO2TZMA29nyxwDtI0Jx2ydsRWS1Cm/9Ngc5CSvIq8B1QmO32tX2SU\r\n1wQgtoR+rsMi7lTtARZMqOE94wJwi0Xe8L/GZ0JjzhGHbMDceBa4Mo62Cm7A\r\nm/g2P7UZX3MxMmWf7YNtvqP5fEWQ53anyNaNK6rvJtnEUwCDjXmJb7QQUKmZ\r\nSNkpEhaX9Niha7wft+bjBLR0/Ge83ofZTVjKjmf/F/CJ2e6RpdAIfrnzffpx\r\nxYUAhN2HjjjlrgwYsTqd7y26XyO7BTqf6Xc=\r\n=YQCV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_1.2.3_1681749457992_0.26328111081780325"},"_hasShrinkwrap":false},"2023.5.21-experimental":{"name":"react-modal-global","version":"2023.5.21-experimental","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"react-scripts test --coverage *"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"8c6229f74517eeb5d6d94937f5ca54066ac0bfbc","_id":"react-modal-global@2023.5.21-experimental","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-PbVPQjZPCwZWXYhXXLQN9ZoisQ7XodRQtE2XPEQ3Xg5LkjXZLMfNB8yPQPcPlWf4TJFoXufxEx7OPthegSt7cQ==","shasum":"bd72e011f57bef9b0086a524f7e280559c8b4c66","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.21-experimental.tgz","fileCount":6,"unpackedSize":25010,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDueHlJPmpscG4vt4UO29vJU8jO+bqC9NNy+kZBc13+4gIhAM4ZteyEGLsHDziBP7XfaYxcB9K316Iv/uViJpfC4nOZ"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.21-experimental_1684684238869_0.7232734925154771"},"_hasShrinkwrap":false},"2023.5.21-experimental-2":{"name":"react-modal-global","version":"2023.5.21-experimental-2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^8.3.3","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^13.4.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.30.1","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^7.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","type-fest":"^3.5.5","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"react-scripts test --coverage *"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","popup","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"]},"readme":"# React Modal Global\n\n[![codecov](https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA)](https://codecov.io/gh/FrameMuse/react-modal-global)\n[![npm version](https://badge.fury.io/js/react-modal-global.svg)](https://badge.fury.io/js/react-modal-global)\n[![npm downloads](https://img.shields.io/npm/dm/react-modal-global.svg)](https://www.npmjs.com/package/react-modal-global)\n[![GitHub license](https://img.shields.io/github/license/FrameMuse/react-modal-global)]()\n\n[![GitHub stars](https://img.shields.io/github/stars/FrameMuse/react-modal-global)]()\n[![GitHub contributors](https://img.shields.io/github/contributors/FrameMuse/react-modal-global)]()\n[![GitHub last commit](https://img.shields.io/github/last-commit/FrameMuse/react-modal-global)]()\n\n## Presentation\n\nReact modal dialogs which is similar to [`react-modal`](https://www.npmjs.com/package/react-modal) but it may be called from `useEffect`, that's why it is **global** ^_^\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to [my discord server](https://discord.gg/DCUWrRhvnt).\n\n## Navigation\n\n- [React Modal Global](#react-modal-global)\n  - [Presentation](#presentation)\n  - [Contribute](#contribute)\n  - [Navigation](#navigation)\n  - [Advantages](#advantages)\n    - [Major advantages](#major-advantages)\n    - [Minor advantages](#minor-advantages)\n  - [Usage](#usage)\n    - [Playgrounds](#playgrounds)\n      - [Example of layouts useage](#example-of-layouts-useage)\n      - [Example of usage with ChakraUI (by @laurensnl)](#example-of-usage-with-chakraui-by-laurensnl)\n    - [Add container](#add-container)\n    - [Create new Modal component](#create-new-modal-component)\n      - [Plain component](#plain-component)\n      - [Using `modal context`](#using-modal-context)\n    - [Modal component usage](#modal-component-usage)\n    - [Modal Template](#modal-template)\n    - [Modal layouts](#modal-layouts)\n      - [If using several containers](#if-using-several-containers)\n  - [Layout concept](#layout-concept)\n    - [Description](#description)\n    - [Aria](#aria)\n  - [Modal controller](#modal-controller)\n    - [`Open`](#open)\n    - [`Close`](#close)\n      - [`CloseByComponent`](#closebycomponent)\n      - [`CloseById`](#closebyid)\n    - [Modal options](#modal-options)\n\n## Advantages\n\n### Major advantages\n\n- Allows to use modals in `useEffect` hook without creating a new component for each one by passing `props` to `open` method.\n- Allows opening modals without wrapping them in components and controlling their state.\n- Allows to use modals in non-component context (e.g. in `useEffect` hook).\n- Allows to reuse modals in different places without creating a new component for each one by passing `props` to `open` method.\n- Allows to use various modal types (Dialog, Popup, Drawer) by creating your own layout for each one (advised naming is `[Type][Name]` => `DrawerLayout`).\n- Allows customizing modal controls by extending `ModalController` class and creating your own layouts.\n- Allows to use several containers at different depths of your app (e.g. to vary templates).\n- Allows forking modals and creating \"layer depth\" (_in development_).\n\n### Minor advantages\n\n- Globalization - opened from anywhere (even from non-component context)\n- Context - data that passed in `open` method can be accessed in the component using `useModalContext` hook\n- Stacking/Nesting (as a container option).\n- Data preservation (after closing last modal, the data will be preserved and if same modal will be request to open, it will _restore_ previous modal but with `weak: true` it will not happen)\n- `open` method is `PromiseLike` (`thenable`) - you can use `await` or `then` to wait for modal closing\n- The package uses only react as a peer dependency\n\n## Usage\n\n### Playgrounds\n\n#### Example of layouts useage\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\n#### Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl))\n\n[![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f)\n\n### Add container\n\n`ModalContainer` is a container for modal components (it usually appears in the root of your app) and modal components will appear there as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      <ModalContainer />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### Create new Modal component\n\nAll it needs for creating modal component is a react component factory with a valid `JSX.Element`:\n\n#### Plain component\n\n```tsx\n// Arrow function\nconst ModalComponent = () => <>:3</>\n// Plain function\nfunction ModalComponent() {\n  return <>:3</>\n}\n```\n\n#### Using `modal context`\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalContext() // Getting modal context of currently active component\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n### Modal component usage\n\nNote that `PopupLogin` should have its own styles to look like a popup, it is advised to use custom `PopupLayout` (Learn below).\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // import default styles if want\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    // Recommended naming is [Popup, Dialog or Modal] then [Name of a modal] i.e. DialogMyName\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n### Modal Template\n\nThere is a multicontainers feature - you can put containers at different depths of your app to vary templates.\n\nOnly one container will be used.\n\nThe last mounted container will be used.\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalContext } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalContext()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalContext` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option     | Description                                                                                                                                                                 |\n| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `id`       | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else.                                                               |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close.                              |\n| `weak`     | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n","readmeFilename":"README.md","gitHead":"8c6229f74517eeb5d6d94937f5ca54066ac0bfbc","_id":"react-modal-global@2023.5.21-experimental-2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-vH3tgklcbvYPXy0lxZhEWStX2PLA/a8x1PSd4JGTMTsuhRZR2qgm21qT4bfm4Y/Ep8Y6GMfMvF7iBYACiShemw==","shasum":"db983370c4cba887fa911a65018e04e779c8162a","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.21-experimental-2.tgz","fileCount":6,"unpackedSize":25713,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCbiuLFpCcvEHLNksBXsVQgmz71+anyxPsOBD84hKIlDwIhAOBsBMWyOSjRRFUSOmnI1B4xXo6SyVfGtNviyaeaMjFF"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.21-experimental-2_1684702259689_0.2745366073343414"},"_hasShrinkwrap":false},"2023.5.22-experimental":{"name":"react-modal-global","version":"2023.5.22-experimental","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props, to what you are used to. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```tsx\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\nThere is no `Modal.close` method because it's hard to know what exactly window to close, instead you can close a modal from inside of a modal component using `useModalWindow` hook.\n\nTo close from outside you can use returned `close` method from `Modal.open` or `Modal.closeBy` methods\n\n#### `CloseByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```tsx\nModal.closeByComponent(ModalComponent)\n```\n\n#### `CloseById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```tsx\nModal.closeById(\"insane-id\")\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `weak` | By default, a last closed modal will not be removed if the same modal will be requested to open. It will _restore_ previous modal but with `weak: true` it will not happen. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"2a24bfa593e83c6d00a457c0c9f557da389fbf7e","_id":"react-modal-global@2023.5.22-experimental","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-mB+D3dHqGT8sciSCi+jT5/wOu/IYHC47PgfL8lxHvx8MV6wgPaaYa7gX4PmkzWRG3CYsDJbZgEWctV82VGyzhg==","shasum":"67fb848043332a3d7cc1b7efb5ae4cd97415661c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.22-experimental.tgz","fileCount":7,"unpackedSize":33050,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/on8IoXvuXAYVqi8FJfRFtRzzv7U8Tc+abmMpLl49DAIgWqFDNpkWEqk4ILZzjQzQw/GfrNjDB9H2tywSezeGHXM="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.22-experimental_1684774128423_0.5425316310216737"},"_hasShrinkwrap":false},"2023.5.22-experimental-2":{"name":"react-modal-global","version":"2023.5.22-experimental-2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"64cdffb928cdfc6aed0a0be6e36a63fdf4617ccd","_id":"react-modal-global@2023.5.22-experimental-2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-e7Od1tHGo4BvLgFWC+IY4SB8wSZXX0oBi7v5LdqcellA89L9HB3WTlCxLJv7mhtPr58LGKxO76AYNNKpsunh+A==","shasum":"09e14038cd3798041f353ee1f272da8292c9ac98","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.22-experimental-2.tgz","fileCount":7,"unpackedSize":32958,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF2WyDDUvZV9AtS8qViT0L69nTm//EK3+w/OuutQxtNWAiBDshkwXGn2DrGRYuP9Ju5E2dWpL1KTfRDhcZ6LenKrQw=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.22-experimental-2_1684784030427_0.5634532224507385"},"_hasShrinkwrap":false},"2.0.0":{"name":"react-modal-global","version":"2.0.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","uuid":"^9.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.5"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"e1c17e94b5361009f55595924e19f3091afcac96","_id":"react-modal-global@2.0.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-wL3/3Lvq2REcYCogguLVLGEJtS8EqZ5wGb80afKEu+6EBv10m7DbvE0XB6D/8UJBBAhEViY+gIi6+UES/Uq+9w==","shasum":"0605c58b42441d091aa05af605225b847a0742fb","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.0.0.tgz","fileCount":7,"unpackedSize":33409,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBz0VBTdwcbVI73Vbm8dSIJk1nLgHH1UYQJ9Dayb1V4gAiEA4jDK3EaSQOTmMmLQPGXxStsyIEc7X/gZjiOhLhaYsnc="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.0.0_1684786917998_0.01502477036686356"},"_hasShrinkwrap":false},"2.1.0":{"name":"react-modal-global","version":"2.1.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^5.0.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"8b9e24ee5e1a5df5b176f88678f8d0e1a97a7355","_id":"react-modal-global@2.1.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-HTEtIAPgb17fSKhFcINH4KgMCLmXryqV8K3rR6jJbxaRMukYWFyXtM/tNm4SRErvULz+KGC9bANsHdw7FbKwDw==","shasum":"a415a5994ad4c67e126889a13dc62ca8c6a1f959","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.1.0.tgz","fileCount":7,"unpackedSize":34862,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFVfoEx5RFav3OVuYSM6MH/nT1VxGXKbUO2JRkhscv4yAiAivffyb+6JabT50BTHBuRJ+OBvMFJu2xe1LjJV0GfOeQ=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.1.0_1684843646868_0.5625279812050172"},"_hasShrinkwrap":false},"2023.5.26-experimental":{"name":"react-modal-global","version":"2023.5.26-experimental","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"f60093ee0ea88af9b517469bce3e43863186f35b","_id":"react-modal-global@2023.5.26-experimental","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-tI8FFQWOpz4enRbxCB+o1Nce+uQW7whlR0ZBg6Zlffff4pnIlBzoAM72339baC/54JRURn5DRFHbxkBVcBWnGg==","shasum":"4ebd199417fa324de047d1eabed9d712559c2570","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental.tgz","fileCount":7,"unpackedSize":35766,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH8/U49rTsUbwip8RfK9rlO/1II67yIUyix6a0QBBZTKAiEA7ivqFhu9pjL2/arCFyEXHYU52I+qW10BtcwAykS38HE="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental_1685084401598_0.3897097823858271"},"_hasShrinkwrap":false},"2023.5.26-experimental-2":{"name":"react-modal-global","version":"2023.5.26-experimental-2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":">=18.0.0"},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"806ee8252b431d32016c20a76c6b083743bb5fcc","_id":"react-modal-global@2023.5.26-experimental-2","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-Q4jvpvuUv7ZuQZX2uHRhKLlnThXu/yN+yDUhH3HMUt2irAbs+ydmeDDlcbPcdsoQW4gOqFjVw/SRHD/vOtR9Rw==","shasum":"1a29ff0bccb50ac9e5b770dbb4b4404b7a748151","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental-2.tgz","fileCount":7,"unpackedSize":35913,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFeTA3r8Qq8kXbif0DGUa+0RDPQqK5pE+F4bUTqEP49vAiEAqKNlYytb1hCI2g1qMUaRjVCrcH/jes/pdtPwg+GCZBM="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental-2_1685084866324_0.7334701002840001"},"_hasShrinkwrap":false},"2023.5.26-experimental-3":{"name":"react-modal-global","version":"2023.5.26-experimental-3","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"260cfbe4712645dcb971bc32fe959c097ea153e3","_id":"react-modal-global@2023.5.26-experimental-3","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-pMQEk0X+g5xJiaF7fTQbV+c+L6Y/PDc0sobLQTi89cchDrPdTpb/adL2O/sTqq5TRj/oA4DhMERfBkYma1s1Zw==","shasum":"048fa772d9a8e2d90d9963e32c4a774477f186da","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental-3.tgz","fileCount":7,"unpackedSize":36021,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHJ59Ff8HPaSFjc9huQoQ3J7HyGrshBiDiI2NIht683iAiAEJojgECqVgnEpNmF/1viP+tf/aaYf/Q4uT2ZO0OIpSA=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental-3_1685085205019_0.5781803182404595"},"_hasShrinkwrap":false},"2023.5.26-experimental-4":{"name":"react-modal-global","version":"2023.5.26-experimental-4","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"3320065a4586c8dc3ffbb6ecf6e79fba344a82e2","_id":"react-modal-global@2023.5.26-experimental-4","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-D7HE6RNBT94hROC5cDlPiuA7ezWuc0HsDK1R7aJsZGbjqf/MmmkQi0GeF0d/foKZQ8FJlenQW7p3iiMV9doaZg==","shasum":"cd045919cd6eb43120a35133c59f32b8a52c9536","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental-4.tgz","fileCount":7,"unpackedSize":35937,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpsd8/titLMS88I1M6pzpbTcZPbPFTbCNuAKAfIg37KQIhALe3oEmSplY5tSwMeSlFtwB9+sE/F1gs1WNvspq0Oloa"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental-4_1685085517487_0.648384645340947"},"_hasShrinkwrap":false},"2023.5.26-experimental-5":{"name":"react-modal-global","version":"2023.5.26-experimental-5","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"01108cb920c40c018deee61794f94b5bfc03dfd1","_id":"react-modal-global@2023.5.26-experimental-5","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-IT9ZxvZTjVCuheQZg42I4E9vne8CuZSZ7BKRQQR9gIXaYZfggbUKVuaC5U/f2CA8Znu5/6TZyMc0wRuMJpwe1g==","shasum":"2e0ebc0f131e2c0c85bd55c0542ad2b84dc6af0f","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental-5.tgz","fileCount":7,"unpackedSize":35878,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBf6YP5oJ1w/spMMu/M37IlG13XfczMI5pXNL67qu2I8AiAwy7Z8SlrsYl8TfCuZjCqFjS/nESXzh23RmUFV/zghSA=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental-5_1685086610085_0.8296633510106604"},"_hasShrinkwrap":false},"2023.5.26-experimental-6":{"name":"react-modal-global","version":"2023.5.26-experimental-6","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"b78b9e5c13cd1de982ab71ff98d012aec0523b85","_id":"react-modal-global@2023.5.26-experimental-6","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-5dsJBQt8bY7qOTO5j8aLD6cyKSVnoju6fuOl1x78MHsMPP15KXDGeU3deILZPcGg1+Ssp33CvWmc1CA3x0DLow==","shasum":"44ac8d7178fe5bf6d2e1922b99a30d68401b7665","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2023.5.26-experimental-6.tgz","fileCount":7,"unpackedSize":36004,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICb0cqVnOxps+bHn/NymZ7VGzxmAWXGcnKKzOrKlqWxLAiBSxEK+zBFhRqVMCsgGwaXozYC47WxVHWtpngFknBgNZg=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2023.5.26-experimental-6_1685087131688_0.9101390861934715"},"_hasShrinkwrap":false},"2.2.0":{"name":"react-modal-global","version":"2.2.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"31ce9a83bfe4cdf332802af9db42add5e87a80d8","_id":"react-modal-global@2.2.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-hCnzxg/NJZN6JPt8wdPeuJZ1gRz+V0FTGT5NmYGBZGrPJm8YmUnxuFXUyPD6AfclqS1OeiE3aSGZfjrJMg7Oxg==","shasum":"89dc52cb8d860e7f98ef185d030cee5ccd3fd752","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.2.0.tgz","fileCount":7,"unpackedSize":35985,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkE1d0SFgMQwDNHtY1piUM6vi1V5k90h16cZkcSClF0AIgdVYBog9apF1pN2Zvq9dR1k43XQK0q+7vxWen/UqGc74="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.2.0_1685089315498_0.13641660763540608"},"_hasShrinkwrap":false},"2.2.1":{"name":"react-modal-global","version":"2.2.1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^3.5.5"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^2.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"4fd3735e7215a346aa967c0f8eae85401ae04e86","_id":"react-modal-global@2.2.1","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-F/HV5j/ay2tNJt8anmxjIwhLW6NDQK6av/8qEivCyUPUDRskVm9L04Fdcy16PrPgQeMicsFp86yNqJ7FQbwNEA==","shasum":"e24444179db5897b7274473411f49423490f0511","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.2.1.tgz","fileCount":7,"unpackedSize":37351,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIQDNiNBBOVJskD4j5zkwFsrxhfiHkvPLlQD5ppG/pxi2hAIfbOD4EG1DRyT+8LF10JemsdJtVrrELd8ybiG93yDnag=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.2.1_1685218854722_0.6186153103840031"},"_hasShrinkwrap":false},"2.3.0":{"name":"react-modal-global","version":"2.3.0","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"gitHead":"010f1137c21183d334a17ed689f91ba8d6baefbe","_id":"react-modal-global@2.3.0","_nodeVersion":"19.6.1","_npmVersion":"9.4.0","dist":{"integrity":"sha512-HQGQXufEBajAJvREPULyu8TblyhfOaPfDm2XpMFxa30zH2fRasFN5UHey6K7aHSrHaZH9KrIqUKGJg0YunrR5g==","shasum":"394e99ddf00e42a93366728721bd8b402f45ac2c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.0.tgz","fileCount":7,"unpackedSize":37485,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd1bpIIscBmHR1J8nogbH/upuuuWVqcDR5p0qEmwrZWAIhALKUb6211zUpWD2nnl6CAE5w+8e2gyniT/YyiIEJJFl4"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.0_1692774639495_0.5453540626209763"},"_hasShrinkwrap":false},"2.3.1":{"name":"react-modal-global","version":"2.3.1","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^8.53.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^5.2.2"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"_id":"react-modal-global@2.3.1","gitHead":"da35d2b2c4f2d6e36d2a33feeeb5647551c075e9","_nodeVersion":"21.1.0","_npmVersion":"10.2.0","dist":{"integrity":"sha512-LUnqGUs/R+UhKf2o6ymOsFc7uPpYUxKtPG+Der+HjfN8Fxjr2K0btZOBe+sDYXTISirBdi7qTfSBq4Fyxu3H7w==","shasum":"8d55e42eeb51e7c4d14e17c1e1208f5ec48740ab","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.1.tgz","fileCount":7,"unpackedSize":36304,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAXcRQLEseXPt/mYLKRWCI2gifRDwJOqXtgo+GHWDqtzAiAEerSv0tf+GX3OG8n63I0GkhpKXqFPStHseSqZ997Pxw=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.1_1699607090843_0.27864187006600494"},"_hasShrinkwrap":false},"2.3.2":{"name":"react-modal-global","version":"2.3.2","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^5.16.5","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","eslint":"^8.6.0","eslint-plugin-react":"7.32.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^4.9.4"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"_id":"react-modal-global@2.3.2","gitHead":"9a45d13e84935ead79f96adfe6c4574a9eebc5c5","_nodeVersion":"21.1.0","_npmVersion":"10.2.0","dist":{"integrity":"sha512-x8yxS4Zfz2hlloo6sJYJRgDdDy20oYRfKx6lM0eCWfaiuVIDeCZ6fgr666WI+EmNwa13AT2SBnrywlY674sD1g==","shasum":"638509ed8ce591782db1f8b8ee503c05a01d038c","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.2.tgz","fileCount":7,"unpackedSize":37435,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDs2CeaPrR7KPI/nxKNZeFPl5k5z8OIYvbkhuuHrztYqAiEAhNvfYq3hwf1TvuRqS9x5i406mrwI1coNtRa8tH9SLjE="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.2_1699707368873_0.07495596920468262"},"_hasShrinkwrap":false},"2.3.3":{"name":"react-modal-global","version":"2.3.3","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"eventemitter3":"^5.0.0","type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^6.1.4","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^8.6.0","eslint-plugin-react":"7.33.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^4.2.2","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^5.2.2"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"_id":"react-modal-global@2.3.3","gitHead":"4b16c9b946818699e0c6d924500a4c77eb398f39","_nodeVersion":"21.1.0","_npmVersion":"10.2.0","dist":{"integrity":"sha512-zd+rJL5QSgU5HbDtUN2D80tHy4EQ2p9cmL6+qDH25wrQAZzDL/VTzHBmrOAO6oBWa4uztyeq/wQLhd7dJ7zehQ==","shasum":"71b376edc16e6f6f9b521bf18f59754896bae8e0","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.3.tgz","fileCount":7,"unpackedSize":36519,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCr+D0K69ebKSQDjEIFNjzXzruIyvQyp+/GhOPOypxljgIhAIkz2MSfI6LaJ5r1tIUJnqRqKCug5DwFZUTS22yRxA0L"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.3_1699862405817_0.2086218362151786"},"_hasShrinkwrap":false},"0.0.0-experimental-2023-03-12":{"name":"react-modal-global","version":"0.0.0-experimental-2023-03-12","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^6.1.4","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^8.6.0","eslint-plugin-react":"7.33.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^6.1.0","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^5.2.2"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"_id":"react-modal-global@0.0.0-experimental-2023-03-12","readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was insipered a lot by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-modal-global-examples-47yoil)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} /> \n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems \n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md","gitHead":"6cfce7f7b454138a4cf7b5e100a6eb8f718f4bf3","_nodeVersion":"21.1.0","_npmVersion":"10.2.0","dist":{"integrity":"sha512-pnyME7OO1Bw4eVoBDDZN+1fxv1O+qRz/+qHVIW9+PcRz90Pxc9ufcZ73I3LZRIDK4Oa1jJhfyrWs/4MUJTsrNA==","shasum":"12cdac4ea65127978f672d80b6fdcbba365464ff","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-0.0.0-experimental-2023-03-12.tgz","fileCount":7,"unpackedSize":37004,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDiEkkrwDt3YgB5O/dR/txqY1cz6LAGqaqLvSqbflGIIAiBVj5TyWbbPIAL4CV7DHFdK2bveMZqCrJ40dJ6quCI1eQ=="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_0.0.0-experimental-2023-03-12_1701631657341_0.21711034457500156"},"_hasShrinkwrap":false},"2.3.4":{"name":"react-modal-global","version":"2.3.4","description":"Highly reusable React Modal that can be run from useEffect.","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"type-fest":"^4.0.0"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@rollup/plugin-typescript":"^11.1.1","@testing-library/jest-dom":"^6.1.4","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^8.6.0","eslint-plugin-react":"7.33.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","rollup":"^2.77.0","rollup-plugin-dts":"^6.1.0","sass":"^1.53.0","tslib":"^2.4.0","typescript":"^5.2.2"},"scripts":{"build":"rollup --config","test":"react-scripts test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"_id":"react-modal-global@2.3.4","gitHead":"3c6a00f774bab6ef0944fc378b763017956680b6","_nodeVersion":"21.1.0","_npmVersion":"10.2.0","dist":{"integrity":"sha512-FujRhbleS3ZH282ahxn3FhEaXAm4Qj0IfNe7vou+E9o5034ddDRPGexGeHv68d6m4MsG4ZgX1xai1rNHt0jSWw==","shasum":"5da1d41046795c190a4b04e56b6e052c3ab0d7b9","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.4.tgz","fileCount":6,"unpackedSize":33888,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDbFbZIOnJJ1SJb/aJ7nH8WQIaT4OIzDd8gfFnK9LGmsAiEA5LcRfNymY//69gVq7gyO2vTXGjUSwEVpXNTRjV76Iow="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.4_1704136645358_0.14132490920219487"},"_hasShrinkwrap":false},"2.3.4-vite":{"type":"module","name":"react-modal-global","version":"2.3.4-vite","description":"Uncontrollable Global React Modal","main":"dist/index.ts","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"type-fest":"^4.0.0"},"devDependencies":{"@testing-library/jest-dom":"^6.1.4","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/node":"^20.12.12","@types/uglify-js":"^3.17.5","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^9.2.0","eslint-plugin-react":"7.33.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","sass":"^1.53.0","typescript":"^5.4.5","uglify-js":"^3.17.4","vite":"5.2.11","vite-plugin-dts":"^3.7.3"},"scripts":{"build":"vite build && tsc","minify":"uglifyjs --compress --mangle --output dist/index.js -- dist/index.js","test":"bun test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"engines":{"node":">=18","vscode":"^1.22.0"},"_id":"react-modal-global@2.3.4-vite","gitHead":"2b4ca1125dd85a1386c2349ecf9e233e05167a98","_nodeVersion":"22.2.0","_npmVersion":"10.7.0","dist":{"integrity":"sha512-OtuWG5YG7ONTIg62UXWwptrmw/y8qNrczOfuFmdYlmnsHz6ihpv2m+PqAl+YYeKGy94YGPHi1S5ak4oiZD3+QA==","shasum":"cfca9469799e46ae8f457fe64f96130efaeef71a","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.4-vite.tgz","fileCount":22,"unpackedSize":77616,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGKYQRzSIGxPvbi2zl/6pVt57SHEoeYmAQ107ZynrGMlAiEAoBAENsPAoXXtKyapZCMFKMEuzHVpLkD+B1Dd/Y9DUr4="}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.4-vite_1716910989809_0.12210090113379546"},"_hasShrinkwrap":false},"2.3.7":{"type":"module","name":"react-modal-global","version":"2.3.7","description":"Uncontrollable Global React Modal","main":"dist/index.js","types":"dist/index.d.ts","peerDependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"dependencies":{"type-fest":"^4.0.0"},"devDependencies":{"@testing-library/jest-dom":"^6.1.4","@testing-library/react":"^14.0.0","@types/jest":"^29.4.0","@types/node":"^20.12.12","@types/uglify-js":"^3.17.5","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^6.9.1","@typescript-eslint/parser":"^6.9.1","eslint":"^9.2.0","eslint-plugin-react":"7.33.2","eslint-plugin-react-hooks":"4.6.0","eslint-plugin-simple-import-sort":"^10.0.0","eslint-plugin-unused-imports":"^3.0.0","sass":"^1.53.0","typescript":"^5.4.5","uglify-js":"^3.17.4","vite":"5.2.11","vite-plugin-dts":"^3.7.3"},"scripts":{"build":"vite build && tsc","minify":"uglifyjs --compress --mangle --output dist/index.js -- dist/index.js","test":"bun test","test:coverage":"npm test -- --coverage *","prepublish":"rimraf build && npm run build"},"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"author":{"name":"FrameMuse"},"license":"MIT","bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"homepage":"https://github.com/FrameMuse/react-modal-global#readme","jest":{"testMatch":["**/?(*.)+(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["/layouts"]},"engines":{"node":">=18","vscode":"^1.22.0"},"_id":"react-modal-global@2.3.7","gitHead":"bb0de24568a8920a0a6755d2ed36ee0df615c88e","_nodeVersion":"22.2.0","_npmVersion":"10.7.0","dist":{"integrity":"sha512-fKPGFcoVemu2KqdIrJyCSiNIaQPUwL+fNRHEMrEeSWiJ4IbwTB/Z6q1Qy3SZSfVEAjFmJ/jsWkmipWSHUSnU0Q==","shasum":"01690f42578c3f4a682b02c739b813038bdce5b8","tarball":"https://registry.npmjs.org/react-modal-global/-/react-modal-global-2.3.7.tgz","fileCount":22,"unpackedSize":77908,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTXRob537leS2sK4H8myjKRpfScjU27ftcikBzfgTj7AIhAI0pXpFueNqwvcqJiLEe2UfPgrTtbiI7By5M/WsONZDw"}]},"_npmUser":{"name":"framemuse","email":"minicablestone@gmail.com"},"directories":{},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-modal-global_2.3.7_1716911816691_0.4439292583731176"},"_hasShrinkwrap":false}},"time":{"created":"2022-07-21T18:25:12.239Z","0.9.0":"2022-07-21T18:25:12.460Z","modified":"2024-05-28T15:56:57.054Z","0.9.1":"2022-07-21T18:27:41.095Z","0.9.2":"2022-07-21T18:31:44.229Z","0.9.3":"2022-07-21T18:47:42.955Z","0.9.4":"2022-07-21T18:52:07.611Z","0.9.5":"2022-07-21T19:08:05.021Z","0.9.6":"2022-07-21T19:14:31.417Z","0.9.7":"2022-07-21T19:17:27.184Z","0.9.8":"2022-07-21T19:17:56.101Z","0.9.9":"2022-07-22T10:11:48.419Z","0.9.10":"2022-07-23T14:07:57.973Z","0.9.11":"2022-07-23T14:09:56.844Z","0.9.12":"2022-07-23T14:11:32.058Z","0.9.13":"2022-07-23T14:26:04.259Z","0.9.14":"2022-07-25T19:15:02.369Z","0.9.15":"2022-07-25T19:17:08.414Z","0.9.16":"2022-07-25T19:29:03.139Z","0.9.17":"2022-07-28T15:12:50.613Z","0.9.18":"2022-07-29T12:07:50.600Z","0.9.19":"2022-07-29T12:08:50.250Z","0.9.20":"2022-08-04T20:07:19.335Z","0.9.22":"2022-10-25T19:31:23.577Z","0.9.23":"2022-10-25T19:34:02.311Z","0.9.24":"2022-10-25T19:43:43.117Z","0.9.25":"2022-10-26T09:21:21.824Z","0.9.26":"2022-10-26T10:50:48.142Z","0.9.27":"2022-10-26T10:56:03.515Z","0.9.28":"2022-10-26T10:58:39.505Z","0.9.29":"2022-10-26T10:59:33.939Z","0.9.30":"2022-10-26T11:07:50.477Z","0.9.31":"2022-10-30T20:46:01.315Z","0.9.32":"2022-12-12T17:18:02.421Z","0.9.33":"2022-12-29T00:26:51.430Z","1.0.0":"2023-02-12T00:10:16.738Z","1.0.1":"2023-02-13T23:17:35.826Z","1.0.2-rc1":"2023-02-17T13:04:33.237Z","1.0.2-rc2":"2023-02-17T13:07:29.586Z","1.1.0-rc1":"2023-02-17T18:28:13.227Z","1.1.0":"2023-02-20T10:02:04.800Z","2.22.2023-alpha":"2023-02-22T03:53:53.953Z","2.22.2023-alpha-1":"2023-02-22T03:57:53.433Z","2.22.2023-alpha-2":"2023-02-22T04:01:23.366Z","1.2.0-rc1":"2023-03-18T05:36:53.147Z","1.2.0-rc2":"2023-03-18T05:52:00.002Z","1.2.0-rc3":"2023-03-22T08:50:53.570Z","1.2.0-rc4":"2023-03-22T08:58:52.302Z","1.2.0-rc4a":"2023-03-22T09:03:54.613Z","1.2.0-rc4b":"2023-03-22T09:07:50.790Z","1.2.0-rc4c":"2023-03-22T09:11:11.511Z","1.2.0-rc5":"2023-03-22T19:21:07.564Z","2023.3.25-experimental-1":"2023-03-24T21:27:29.342Z","1.2.0":"2023-03-25T23:55:21.684Z","1.2.1":"2023-03-28T16:59:42.152Z","2023.4.1-experimental-1":"2023-04-01T01:59:35.473Z","1.2.2":"2023-04-04T04:02:18.631Z","1.2.3-rc1":"2023-04-17T13:36:15.841Z","1.2.3-rc2":"2023-04-17T14:37:19.932Z","1.2.3-rc3":"2023-04-17T14:51:41.915Z","1.2.3-rc4":"2023-04-17T15:01:22.342Z","1.2.3-rc5":"2023-04-17T15:03:05.047Z","1.2.3-rc6":"2023-04-17T15:10:45.696Z","1.2.3":"2023-04-17T16:37:38.182Z","2023.5.21-experimental":"2023-05-21T15:50:39.088Z","2023.5.21-experimental-2":"2023-05-21T20:50:59.851Z","2023.5.22-experimental":"2023-05-22T16:48:48.688Z","2023.5.22-experimental-2":"2023-05-22T19:33:50.573Z","2.0.0":"2023-05-22T20:21:58.189Z","2.1.0":"2023-05-23T12:07:27.054Z","2023.5.26-experimental":"2023-05-26T07:00:01.920Z","2023.5.26-experimental-2":"2023-05-26T07:07:46.496Z","2023.5.26-experimental-3":"2023-05-26T07:13:25.192Z","2023.5.26-experimental-4":"2023-05-26T07:18:37.692Z","2023.5.26-experimental-5":"2023-05-26T07:36:50.259Z","2023.5.26-experimental-6":"2023-05-26T07:45:31.884Z","2.2.0":"2023-05-26T08:21:55.685Z","2.2.1":"2023-05-27T20:20:54.980Z","2.3.0":"2023-08-23T07:10:39.806Z","2.3.1":"2023-11-10T09:04:51.051Z","2.3.2":"2023-11-11T12:56:09.079Z","2.3.3":"2023-11-13T08:00:05.968Z","0.0.0-experimental-2023-03-12":"2023-12-03T19:27:37.613Z","2.3.4":"2024-01-01T19:17:25.525Z","2.3.4-vite":"2024-05-28T15:43:09.989Z","2.3.5":"2024-05-28T15:49:00.663Z","2.3.6":"2024-05-28T15:52:11.416Z","2.3.7":"2024-05-28T15:56:56.888Z"},"maintainers":[{"name":"framemuse","email":"minicablestone@gmail.com"}],"description":"Uncontrollable Global React Modal","homepage":"https://github.com/FrameMuse/react-modal-global#readme","keywords":["react","modal","global","dynamic","component","popup","drawer","dialog","ts","typescript"],"repository":{"type":"git","url":"git+https://github.com/FrameMuse/react-modal-global.git"},"author":{"name":"FrameMuse"},"bugs":{"url":"https://github.com/FrameMuse/react-modal-global/issues"},"license":"MIT","readme":"<h1 align=\"center\">📦 React Modal Global</h1>\n<h3 align=\"center\">Open React modals Anywhere (including non-React Context) 🚀</h3>\n\n<p align=\"center\">\n  <a href=\"https://codecov.io/gh/FrameMuse/react-modal-global\">\n    <img src=\"https://codecov.io/gh/FrameMuse/react-modal-global/branch/main/graph/badge.svg?token=1FRUN6AQDA\" />\n  </a>\n</p>\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/latest.svg\" />\n  </a>\n  <a href=\"https://www.npmjs.com/package/react-modal-global\">\n    <img src=\"https://img.shields.io/npm/v/react-modal-global/experimental.svg\" />\n  </a>\n</p>\n\n## Features\n\n- 🌍 Can be used in `useEffect` hook or any other global scope\n- 💧 [Reactish](#open-as-it-is) - Open modals `Modal.open(ModalComponent, { id: \"2\" })` as you would render components `<ModalComponent id=\"2\" />`\n- 🪢 [Context](#using-modal-context) - you can access params passed to `open` method in the modal component via `useModalWindow` hook\n- 🔃 [Queueing](#queueing) - you can open several modals at once\n- ✅ [Data preservation](#data-preservation) - data will persist after closing last modal and if same modal will be request to open, it will be restored\n- 📚 [Layouts](#modal-layouts) - you can create your own layouts for each modal type (Dialog, Popup, Drawer).\n- 🎛️ [Customization](#modal-controller) - you can extend `ModalController` class and create your behavior\n- 🦑 [Forking](#layer-depth) - you can fork modals and create \"layer depth\"\n\n## Motivation\n\nI was looking for a way to use modals in `useEffect` hook without using `useState` in each component and passing them to modal. I found a lot of packages with various features, but they all have some disadvantages:\n\n- They are not global - you can't open them from anywhere (including non-react context)\n- They are not context-aware - you can't access passed data from a component\n- They are not queue-aware - you can't open several modals at once\n- They are using \"`title`, `desc` / `header`, `body`\" pattern - which is not convenient\n\nSo I decided to create this package that would solve all these problems at once.\n\nI was inspired by packages like [react-toastify](https://npmjs.com/package/react-toastify) and [react-modal](https://npmjs.com/package/react-modal).\n\n## Playgrounds\n| Title | Playground |\n| --- | --- |\n| Example of layouts usage | [![Edit react-modal-global](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/react-modal-global)        |\n| Example of usage with ChakraUI (by [@laurensnl](https://github.com/laurensnl)) | [![Edit react-modal-global](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/chakraui-nextjs-react-modal-global-h0g21f) |\n\n\n## Usage\n\nPlease follow steps below to use this package in your project.\n\n### Create `Modal`\n\nTo start you need to create `Modal`. `ModalController` controls behaviour of the modals and is used in `ModalContainer`.\n\n```tsx\nimport { ModalController } from \"react-modal-global\"\n\nexport const Modal = new ModalController()\n```\n\n### Add container\n\n`ModalContainer` is a display container for modal components (it should be placed in the root), modal components will appear here as you open them.\n\n```tsx\nimport React from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { ModalContainer } from \"react-modal-global\"\n\nimport Modal from \"./Modal\" // Your modal.\n\nfunction App() {\n  return (\n    <>\n      {/* ... Other components ... */}\n      {/* It's better if `ModalContainer` goes after all other components */}\n      <ModalContainer controller={Modal} />\n    </>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById(\"root\"))\n```\n\n### !!! STYLES !!!\n\nNotice that you have to have styles to keep modal closed, otherwise modal will not work as expected.\n\nYou can write your own styles or use provided be the library by importing it\n\n```tsx\nimport \"react-modal-global/styles/modal.scss\" // Imports essential styles for `ModalContainer`.\nimport \"react-modal-global/styles/layouts.scss\" // Imports optional styles for `PopupLayout` and `DrawerLayout`.\n```\n\n### Create new Modal component\n\nModal component is actually a React component. Note that this should be exactly component factory not an element.\n\n#### React component\n\n```tsx\n// Arrow function component\nconst ModalComponent = () => <>:3</>\n// Plain function component\nfunction ModalComponent() {\n  return <>:3</>\n}\n// Class component\nimport { Component } from \"react\"\nclass ModalComponent extends Component {\n  render() { return <>:3</> }\n}\n```\n\n#### Using `modal context`\n\nThis allows a component to access modal window context inside it to see what props were passed in `open` method.\n\nThis also can be used to close modal window from inside (e.g. close on button click). Or you can listen to `close` event and run a cleanup function.\n\n```tsx\nfunction ModalComponent() {\n  const modal = useModalWindow() // Getting modal context of a modal window related to this component.\n\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={modal.close}>close</button>\n    </>\n  )\n}\n```\n\n#### Advanced usage\n\nModal components can be templates for other modal components.\n[See example here](#layout-concept)\n\n#### Naming advice\n\nRecommended naming is [Popup, Dialog or Modal] + [Name of a modal] => DialogPurchase.\n\n### Modal component usage\n\n#### Open 'em\n\nThis is how you disaply your modal components\n\n```tsx\n// Import default styles.\nimport \"react-modal-global/styles/modal.scss\"\n\nimport { Modal } from \"react-modal-global\"\n\nimport PopupLogin from \"./PopupLogin\"\n\nfunction HomeView() {\n  function showLoginPopup() {\n    Modal.open(PopupLogin, { /* Probably your options? */ })\n  }\n  return (\n    <>\n      <h2>Title</h2>\n      <p>Content text</p>\n\n      <button type=\"button\" onClick={showLoginPopup}>Show login popup</button>\n    </>\n  )\n}\n```\n\n#### Open as it is\n\nAlthough you can create your own layout (i.e. component) to pass `title`, `description` and other required/optional props. This library encourages using only component and its props to open modals as just how you would use it in a tree.\n\nSo instead of\n```ts\nModal.open(PopupGeneral, {\n  title: \"Login\",\n  description: \"Please login to continue\"\n})\n```\n\nInclude them in the component itself. Of course you will need to create more components, but this is the way to go.\n\n```ts\nModal.open(PopupLogin)\n```\n\nOr you can create types of your modal components and pass them to `open` method.\n\n```ts\nModal.open(PopupAuth, {\n  type: \"login\" // or \"register\"\n})\n```\n\nEventually, this is up to you to decide, it always depends on your case.\n\n\n### Modal layouts\n\nTo use various modal types (Dialog, Popup, Drawer), you create your own `layout` for each one, advised naming is [Type][Name] => `DrawerLayout`.\n\n[Take a look at this example](https://codesandbox.io/s/react-modal-global-examples-47yoil)\n\nTo create your first `Popup` modal try this\n\n```tsx\nimport { FormEvent } from \"react\"\nimport { useModalWindow } from \"react-modal-global\"\n\nimport PopupLayout from \"../modal/layouts/PopupLayout/PopupLayout\"\n\nfunction PopupMyFirst() {\n  const modal = useModalWindow()\n\n  function onSubmit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault()\n\n    const target = event.currentTarget\n    const ageInput = target.elements.namedItem(\"age\")\n\n    alert(ageInput) // Show age\n    modal.close() // Then close `this modal`\n  }\n  return (\n    <PopupLayout>\n      <form onSubmit={onSubmit}>\n        <h2>My first popup modal</h2>\n        <input name=\"age\" placeholder=\"Enter your `first popup modal` age\" />\n        <button type=\"submit\">See my age</button>\n      </form>\n    </PopupLayout>\n  )\n}\n\nexport default PopupMyFirst\n\n```\n\n#### If using several containers\n\nInstead of wrapping your modal components manually you can pass `template` attribute to `ModalContainer`, for example, `PopupLayout`\n\n```tsx\n<ModalContainer controller={Modal} template={PopupLayout} />\n```\n\n## Layout concept\n\n### Description\n\nLayout is a component that wraps modal component and allows to customize modal look and controls (close button, header, footer, etc.).\n\nLayouts are used to create various modal types (Dialog, Popup, Drawer) and to customize modal controls.\n\nFor example, you can create your own `PopupLayout` to use it in your `Popup` modals.\n\n[See example here](./examples/PopupLayout)\n\n### Aria\n\nLayouts should not have `aria-modal` attribute and `role=\"dialog\"` because they are already set in `ModalContainer` component.\n\nYou should manually add `aria-labelledby` and `aria-describedby` attributes to your layout.\n\n## Modal controller\n\n### `Open`\n\n`Modal.open` is a method that opens a modal. See [usage](#modal-component-usage) for example. See [options](#modal-options) for more details.\n\n```ts\nModal.open(ModalComponent, { /* options */ })\n```\n\n### `Close`\n\n#### `close`\n\n`Modal.close` is a method that closes a modal by its instance. This will only close one modal, since any duplicates are filtered.\n\n```ts\nModal.close(ModalWindow)\n```\n\n#### `closeByComponent`\n\n`Modal.closeByComponent` is a method that closes a modal by its component. It will close all modals that use this component.\n\n```ts\nModal.closeByComponent(ModalComponent)\n```\n\n#### `closeById`\n\n`Modal.closeById` is a method that closes a modal by its id. It will close all modals that have this id.\n\n```ts\nModal.closeById(\"insane-id\")\n```\n\nSince all modal ids are set to `-1` **by default**, you can close all modals that don't have a custom `id`\n\n```ts\nModal.closeById(-1)\n```\n\n### Modal options\n\nYou can use options when opening a modal with `Modal.open()`.\nAvailable options\n\n| Option | Description |\n| --- | --- |\n| `id` | Specifies id of a modal. In react it's used as a `key`. May be used to find and close specific modal or else. |\n| `closable` | Specifies if a modal closing is controllable internally. If `false`, it's supposed to mean that user should do a **specific** action to close. |\n| `label` | Specifies `aria-label`. |\n| `layer` | Specifies how modals should overlap. |\n\n## Modal container\n\nThe `ModalContainer` component is a container for all modals, but it's not required to use it.\n\nSo if you're not happy with the default container, you can create your own.\n\nIt depends on `ModalController` and `ModalContext` to work.\n\n## Other features\n\n### Queueing\n\nIf you open a modal while another modal is already opened, it will be queued and will be opened after the previous one is closed.\n\n### Data preservation\n\nData will be restored if you open a modal with the same component and props after it was closed.\n\nIt also works with `Modal.replace` method, which can replace props with new ones while keeping the same component and data.\n\n### Layer depth\n\nSometimes you need to open a modal on top of another modal, for example, you have a modal with a login form, and you want to open another modal with a phone confirmation on top of it but keeping the login form visible and state preserved.\n\nThis is where `layer` depth comes in handy.\n\n```tsx\nModal.open(ModalComponent, {\n  layer: 1 // Default is 0\n})\n```\n\nNote that `layer` depth is not really a z-index, it's just a number that specifies the depth of a modal, it's used to determine which modal should be opened on top of another.\n\n---\n\nPlease consider contributing to this feature, I will be happy to see your PRs or just a [feedback](#contribute).\n\n## Other modal ideas\n\nThere are more than one way to create modals in React.\n\nTwo the most popular are \"React Tree Modal\" and \"Common Consumer Modal\" (this is how I call it).\n\n### React Tree Modal\n\nThis is mostly known in React community, it's a modal that is rendered in a tree. There is a library called [react-modal](https://npmjs.com/package/react-modal) that implements this approach.\n\nBut this way has some problems, one of them is that you have to create a component, which will control your modal state (open, closed) every time for every modal, and it's not convenient.\n\n### Common Consumer Modal\n\nThis is an approach just consumes \"`title` and `description`\" or \"`header` and `body`\" props and renders them in a common container.\n\nThis approach lacks of flexibility, but it's easier to use.\nThere also may be problems\n- styling, because you can't style a modal component itself, you can only style a container\n- multiple languages, because you can't apply its own translation to each modal window separately, you will have to pass it to a method, which is not convenient\n\n## Contribute\n\nNeeds feedback, please contribute to GitHub Issues or leave your message to the [discord server](https://discord.gg/DCUWrRhvnt).\n","readmeFilename":"README.md"}