{"_id":"react-interactive","_rev":"47-6eb07acb45b65c65d6f8d3cbf6c49fc5","name":"react-interactive","description":"Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.","dist-tags":{"latest":"1.1.2","next":"1.0.0-next.10"},"versions":{"0.0.0":{"name":"react-interactive","version":"0.0.0","description":"React interactive component","main":"lib/index.js","scripts":{"build":"rm -rf lib && babel src -d lib","prepublish":"npm run build"},"files":["lib","src"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","click"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.11.4","babel-eslint":"^6.1.2","babel-preset-es2015":"^6.9.0","babel-preset-react":"^6.11.1","babel-preset-stage-1":"^6.5.0","eslint":"^3.2.2","eslint-config-airbnb":"^10.0.0","eslint-plugin-import":"^1.12.0","eslint-plugin-jsx-a11y":"^2.0.1","eslint-plugin-react":"^6.0.0","react":"^15.3.0"},"gitHead":"6bc658bfb2aeb277a1ef6d20a7029be53eff0dd0","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.0.0","_shasum":"e257915969871ff5aa77eebaf51008255f4b0d5c","_from":".","_npmVersion":"3.9.3","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"e257915969871ff5aa77eebaf51008255f4b0d5c","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.0.0.tgz","integrity":"sha512-GQ6YshmfGoGLYlUfzBqos7ZjJ3hqkiFtI6e+9u9rYiXypkQO0vOWMSCp36WTGYTodAVtdxRF15RtTcMX07yZPw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDx133Y2VK5tuWad3SAUKYrv79bTgRQk3rsElh2hQvDuAiEA+xvFR9FVUYCX+KSvOYaVWZRsMw5iEUWn6UtUsxboQO0="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.0.0.tgz_1470373802436_0.5266262467484921"},"directories":{}},"0.1.0":{"name":"react-interactive","version":"0.1.0","description":"React interactive component","main":"lib/index.js","scripts":{"build":"rm -rf lib && babel src -d lib","prepublish":"npm run build"},"files":["lib","src"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.14.0","babel-eslint":"^6.1.2","babel-preset-es2015":"^6.14.0","babel-preset-react":"^6.11.1","babel-preset-stage-1":"^6.13.0","eslint":"^3.5.0","eslint-config-airbnb":"^11.1.0","eslint-plugin-import":"^1.15.0","eslint-plugin-jsx-a11y":"^2.2.2","eslint-plugin-react":"^6.3.0","react":"^15.3.1"},"dependencies":{"detect-it":"^1.0.0","object-assign":"^4.1.0"},"gitHead":"1c81f5b36aa35772d1fedd8cf1102d7dc79204c7","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.1.0","_shasum":"bf4b55773a23fc7284199167f7284b2d0c64a744","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"bf4b55773a23fc7284199167f7284b2d0c64a744","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.1.0.tgz","integrity":"sha512-05zPmz09qShQqt21nEbkFMcLgxYTxJ8KqX/dGdzmAy55/C0vkutQBmk9+AroNEpcXgytAgX+BpECZYmTulPyIA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF78veMhQC3kWWpq3U6SbgPRoUM4BUjqtsPKgjISwDN0AiEAnqYQiTgAdZp0EC7xaFzU3ZmcDKpxwc/RknJWgOnZ8TA="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.1.0.tgz_1476832513287_0.532085130456835"},"directories":{}},"0.2.0":{"name":"react-interactive","version":"0.2.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.18.0","babel-eslint":"^7.1.1","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","babel-preset-react":"^6.16.0","babel-preset-stage-1":"^6.16.0","eslint":"^3.10.2","eslint-config-airbnb":"^13.0.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^2.2.3","eslint-plugin-react":"^6.7.1","react":"^15.4.0","webpack":"^1.13.3"},"dependencies":{"detect-it":"^2.0.0","object-assign":"^4.1.0"},"gitHead":"1c9b09e0bf04d490771ce1d32e3e111e48a1c663","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.2.0","_shasum":"a8a03621eaa16ff8ab01e97673fab439c5b7bddf","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"a8a03621eaa16ff8ab01e97673fab439c5b7bddf","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.2.0.tgz","integrity":"sha512-kegKQkMYvUc5oLh5vzTyb8vnlDqh0Kf2DoD/zu+65/I5PhouJCR6G6vUDaMFsGID9t2LltWW6dmK1+eWAUKCxw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICM1aVXTWojvGNsJzorRgkd/c6qL12mlyO+UuZsWZPPAAiEA3AE7ptkdzVH8LOyScmBAlxg4Nil+tv22eV7ISEg7pDA="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.2.0.tgz_1479750566899_0.510253062704578"},"directories":{}},"0.3.0":{"name":"react-interactive","version":"0.3.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.18.0","babel-eslint":"^7.1.1","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","babel-preset-react":"^6.16.0","babel-preset-stage-1":"^6.16.0","eslint":"^3.10.2","eslint-config-airbnb":"^13.0.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^2.2.3","eslint-plugin-react":"^6.7.1","react":"^15.4.0","webpack":"^1.13.3"},"dependencies":{"detect-it":"^2.0.0","object-assign":"^4.1.0"},"gitHead":"a7918b32937d4f070cf2f19e78d1e5070a67c9a8","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.3.0","_shasum":"0f8ede79f0a4c9df1ff5eafd9375413502fd0f8f","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"0f8ede79f0a4c9df1ff5eafd9375413502fd0f8f","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.3.0.tgz","integrity":"sha512-cBiTHyUmOsE5U6ejPiifdAUzbgggnfdhZjagUxF1TOi5u0No9Drt2tMO6lI3tegfxJvWbf6KRxPr1LmYTN96Bg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkJKjns8VnQOp+1Z09uF3SNNEipCz1EN/GAFRzUWtMVQIhAKaOgJNN2ANOOGhmuqMoU2orjwkbZMdhp8g3OyOPAdpU"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.3.0.tgz_1479963592007_0.138542833738029"},"directories":{}},"0.3.1":{"name":"react-interactive","version":"0.3.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.18.0","babel-eslint":"^7.1.1","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","babel-preset-react":"^6.16.0","babel-preset-stage-1":"^6.16.0","eslint":"^3.10.2","eslint-config-airbnb":"^13.0.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^2.2.3","eslint-plugin-react":"^6.7.1","react":"^15.4.0","webpack":"^1.13.3"},"dependencies":{"detect-it":"^2.0.0","object-assign":"^4.1.0"},"gitHead":"35739377359594589dcafbd13f9a9ce2b816297f","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.3.1","_shasum":"cefc34c51f9e2671ae28204678c3b7cb900be038","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"cefc34c51f9e2671ae28204678c3b7cb900be038","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.3.1.tgz","integrity":"sha512-WnObojd4E3ST+nd0Grz/1/Ps/KBm4fUBuyDRGOaDeIesV7fdxnIJur7nTO+maA9MQt019j/yl/FqSLlkSCe38Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFGCIGdV9sHMcZJrv9AxHqRtum5ylGpTIoqRW+YWBBeHAiBD4UWmOwmcvQSBKh2+NJjm7mxQhsx8dzGUMZyP3BlzTg=="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.3.1.tgz_1480366033237_0.7970758231822401"},"directories":{}},"0.4.0":{"name":"react-interactive","version":"0.4.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.18.0","babel-eslint":"^7.1.1","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","babel-preset-react":"^6.16.0","babel-preset-stage-1":"^6.16.0","eslint":"^3.10.2","eslint-config-airbnb":"^13.0.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^2.2.3","eslint-plugin-react":"^6.7.1","react":"^15.4.0","webpack":"^1.13.3"},"dependencies":{"detect-it":"^2.0.0","object-assign":"^4.1.0"},"gitHead":"e0e7dbeeaea5af99d9924950d675e6c97697e755","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.4.0","_shasum":"9aca09445804bc924f1d5df411e6ff6fc92e45bb","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"9aca09445804bc924f1d5df411e6ff6fc92e45bb","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.4.0.tgz","integrity":"sha512-/VGxMPR4FYxJhnuuzAUFD0SS90njCGo7OwWneVGFaYpidZDqGcEb1DWXz5nUXNEn8S0lnEHiH9yjRpfkhj+xqQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDi6vMR7QYLM7BdE/67RxBHXrOACdhu3ZYDxWaD2VJMsgIgBM51CrjDC4R/cA0pTDEe9gFPB+d3kshEoqc1vkp5LA4="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.4.0.tgz_1480468658868_0.7964298706501722"},"directories":{}},"0.4.1":{"name":"react-interactive","version":"0.4.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.18.0","babel-eslint":"^7.1.1","babel-loader":"^6.2.7","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.18.0","babel-preset-react":"^6.16.0","babel-preset-stage-1":"^6.16.0","eslint":"^3.10.2","eslint-config-airbnb":"^13.0.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^2.2.3","eslint-plugin-react":"^6.7.1","react":"^15.4.0","webpack":"^1.13.3"},"dependencies":{"detect-it":"^2.0.0","object-assign":"^4.1.0"},"gitHead":"bf20a2a80d4af526ce7e27fe33f53a972d1edf8f","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.4.1","_shasum":"9912b99725cfc2bc7480f953e7ae5f127bf372e8","_from":".","_npmVersion":"4.1.1","_nodeVersion":"6.2.0","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"9912b99725cfc2bc7480f953e7ae5f127bf372e8","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.4.1.tgz","integrity":"sha512-IzWpnuKRZc7z3ss72+yk29bcZjxjiMz3Un4BnJw/0nlSXfm6ofQtcMTh+267siCaj9hQ24134suqoHL42z0y4g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG/SlJOlARy7ynoU+8TzAnIns8tpJoIHVJdqtdBpZ3xWAiEAn43jEDp6lZLcLHMS7ecSuxAEnTzDXNGBOssVW4ZRxAc="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.4.1.tgz_1484712071370_0.16822544671595097"},"directories":{}},"0.5.0":{"name":"react-interactive","version":"0.5.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.24.0","babel-eslint":"^7.2.1","babel-loader":"^6.4.1","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.24.0","babel-preset-react":"^6.23.0","babel-preset-stage-1":"^6.22.0","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","react":"^15.4.2","webpack":"^2.3.2"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1"},"gitHead":"5de05c63342ccc5c2dca6d1e865248f2789f679f","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.5.0","_shasum":"ec16757483bd56f26f73f7ac7061ecbbbabb2481","_from":".","_npmVersion":"4.2.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"ec16757483bd56f26f73f7ac7061ecbbbabb2481","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.5.0.tgz","integrity":"sha512-81o/4AlwZDs1gTGBem9vnIbOgE9MTWqoh90puwy/NvTI9VUuZX7VjuUiqzYv7QAC57cpS04U4Cpw8XQmUg5isw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCDEvez+lXPwUsa8t1/bHf9ASuSHLxHc/7sBdCumkyFLQIhANnVOnYHKC8a7Rfyui5nurVnV7M7IW1hBegGa3bY2GC5"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.5.0.tgz_1491071556226_0.6885280064307153"},"directories":{}},"0.5.1":{"name":"react-interactive","version":"0.5.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.0.0"},"devDependencies":{"babel-cli":"^6.24.0","babel-eslint":"^7.2.1","babel-loader":"^6.4.1","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.24.0","babel-preset-react":"^6.23.0","babel-preset-stage-1":"^6.22.0","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","react":"^15.4.2","webpack":"^2.3.2"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1"},"gitHead":"c2dc51bedfd4618728fc0bbd6815ef7eda84cbe9","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.5.1","_shasum":"d21eb20556698c52428234416754f44ad7018600","_from":".","_npmVersion":"4.2.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"d21eb20556698c52428234416754f44ad7018600","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.5.1.tgz","integrity":"sha512-hkhHWvnF5xzBWdP+NZGdqPe2L9CCi71+VTcD8SDbO3Hm6zlWxaUw6OpVaJYz3X6/s784C5cZek5MFMqnRagbqg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHzNNS6sTFUfqb6/Rix37xmQoYgmn5qAqYZyvRZciQzCAiEA24aaa1nKhUPfbCkWJwgL6WE9OEy+vMB1SDE98a1kgL4="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.5.1.tgz_1491171320353_0.8353282189927995"},"directories":{}},"0.6.0":{"name":"react-interactive","version":"0.6.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.0","babel-eslint":"^7.2.1","babel-loader":"^6.4.1","babel-plugin-add-module-exports":"^0.2.1","babel-preset-es2015":"^6.24.0","babel-preset-react":"^6.23.0","babel-preset-stage-1":"^6.22.0","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","react":"^15.4.2","webpack":"^2.3.2"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"80f185242fcc856916fba05c62ca8a7bb843ea6e","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.0","_shasum":"ac6aa92c59254d57a686fdda2211d5ded9deca4f","_from":".","_npmVersion":"4.2.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"ac6aa92c59254d57a686fdda2211d5ded9deca4f","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.0.tgz","integrity":"sha512-sa3wkLIrd8T92TV6EkMuCnoHxuXcZo/kCbMm8ElxOg0SwOWDh8H1VlGhBaaa9k4Xe8vvj1zt9WGgNG/40S+DBg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAs0euklTj+G1c6eZL7blQ7CGp5ETbRcJrRMV2G/to4qAiEA0zZkBUMGQp7Y8g7PWl7JhZvx3or/UTnYvVp7lcmEepA="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.0.tgz_1493439446856_0.6487218327820301"},"directories":{}},"0.6.1":{"name":"react-interactive","version":"0.6.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src --watch -d lib"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"8a7b7c9ed4736050ab103fa35d49e07b2b541a58","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.1","_shasum":"37e89ccee4751293d9a3fc6d9625fd7819868bc4","_from":".","_npmVersion":"4.2.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"37e89ccee4751293d9a3fc6d9625fd7819868bc4","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.1.tgz","integrity":"sha512-tD2Fufj7pXE5UIrn+5JMB4zUTMtyZTlPt8MytEXZ4IMEpnfG6REZz8wNKxl0JNnRwHHhmkUARfo9gXZEsYqDGQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCUdt3LO5rDHBpVswsJvVIM6NqD7QymsZ95+aKMUQxMsQIhAIjRE8omzSqztjcfEXNP+OmaRmm0CKJLnzuf/w2NyzA7"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.1.tgz_1493607263678_0.17353541497141123"},"directories":{}},"0.6.2":{"name":"react-interactive","version":"0.6.2","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src --watch -d lib"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"95cf7153429c8177de20639bdcd3d401a4a8866a","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.2","_shasum":"4ad660a5a6904c5a33e1c6517d7abbed9a72182c","_from":".","_npmVersion":"4.5.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"4ad660a5a6904c5a33e1c6517d7abbed9a72182c","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.2.tgz","integrity":"sha512-zSMOYMHk1DwDaYC9o9GN0qo6JxwZGSCpK88Zk+0tGsRMJHF9Esfvw6w0yMtzCaK8fwiOJI74PQHlOIrmqS7LtQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDE/2vR511YJGObVvEqz129UjnSYbDdONXvZ7trIOnLuAIgEsZzZAfdkwuc2paPCBPf7Hy4yGLPslUy6sZfmh6kbfA="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.2.tgz_1493685143179_0.4351211367174983"},"directories":{}},"0.6.3":{"name":"react-interactive","version":"0.6.3","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"9452d14d04a7ddcad854ac4a56de653b64aca7c4","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.3","_shasum":"b024c71b3e920192a7b4f602d2a9a4263717f2cf","_from":".","_npmVersion":"4.5.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"b024c71b3e920192a7b4f602d2a9a4263717f2cf","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.3.tgz","integrity":"sha512-WbC7tLIbUiATFwnAXYPGHItFjxE4Tk3/HW2qV/prD8DvICgKVcS2FZxXKH8xjqdiogLNln5OQ0Lg3ZwB8yoEHg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEfydCuzUjoMBStplgWomMbJC0QLa8FAHg1qQA72GOVcAiEA32G6s8e063Ubkm6pQhLusUdKb/D8tUW9TQykhklITTw="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.3.tgz_1493840931666_0.3389625921845436"},"directories":{}},"0.6.4":{"name":"react-interactive","version":"0.6.4","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^2.1.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"b532960661e41b93d36c9198a6b53bdc1a738852","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.4","_shasum":"cccc502cb1e8c46e7e37cfddbcffb5ae54fd3101","_from":".","_npmVersion":"4.5.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"cccc502cb1e8c46e7e37cfddbcffb5ae54fd3101","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.4.tgz","integrity":"sha512-7J5bxJ9nwXK5H9vyB0M6oa0xOIsQuI0olA7Z6weTiwpEJgsT/fSg5Y81CHUhY9BbJX57zUtHTpm2CkZVYOzxzA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDkOcj+Feiq6xH2VkEH+RB6GTnuaJAbZlHi0Q8kjjcWFwIhALEI54uPEqIZqO4s/2skNz0mYytqbBACIvR1aIRpCMbc"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.4.tgz_1493851045557_0.6171758626587689"},"directories":{}},"0.6.5":{"name":"react-interactive","version":"0.6.5","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^3.0.0","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"6fcc17e81ba7314ed3fdd792c71a763f835ecac3","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.5","_shasum":"a1295eaebd1dfc02ca2d2e0bba828ebbad8a8e74","_from":".","_npmVersion":"4.5.0","_nodeVersion":"6.9.5","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"a1295eaebd1dfc02ca2d2e0bba828ebbad8a8e74","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.5.tgz","integrity":"sha512-6J9JzgLNSZRTe6AfwyRtl4bLDVSSl5dRIAB6vHajZpllflhVxYCB9Hf0MIaN9dYJPfjhzAjuSwuspOnshuE0Ig==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQbo1Wzxu2zrk0ZtJnZCOr76g5UrKis0FkRl0PVG5PsAIhAMFAH8onfrCCzpu9Wbm6Ue2MMwU+UDtSdoBUrXrTFgaJ"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/react-interactive-0.6.5.tgz_1493867381764_0.951937208417803"},"directories":{}},"0.6.6":{"name":"react-interactive","version":"0.6.6","description":"React Interactive","main":"lib/index.js","scripts":{"build":"npm run build-lib && npm run build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"npm run build","dev":"npm link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.24.1","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^3.19.0","eslint-config-airbnb":"^14.1.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^4.0.0","eslint-plugin-react":"^6.10.3","webpack":"^2.4.1"},"dependencies":{"detect-it":"^3.0.0","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"70a3d1826e063491bea925368d350ce1f2d12daf","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.6.6","_shasum":"20f8b656b0a0ea6db4648f9903c876940b717b34","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.1","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"20f8b656b0a0ea6db4648f9903c876940b717b34","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.6.6.tgz","integrity":"sha512-KsPRVAMZGJBIAnGqiNVPvaEXNEKo7/kig0urqG2ITVwGfb2Lylw0XdjtfYik7PZ52Uzbz3qKST7Pytn+fBiz7Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCb8KM7FWpcsfAfTSsJZmsMEDLPGYP8dVnYPHUidu6KMQIgRlPv6CZMSDV6ZEYzBqKwav7eSCXDqKOHsvcToMW2jY4="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive-0.6.6.tgz_1502751277740_0.6099264165386558"},"directories":{}},"0.7.0":{"name":"react-interactive","version":"0.7.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.5.3","webpack":"^3.5.5"},"dependencies":{"detect-it":"^3.0.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"8f0dfd5cc0a1826a4c674c32f7c58b5d2e71945f","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.7.0","_shasum":"5c26e37e2b12fd9ad3cbf2eaf314fdacdeb5d9c6","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.1","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"5c26e37e2b12fd9ad3cbf2eaf314fdacdeb5d9c6","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.7.0.tgz","integrity":"sha512-+NPxYCDyo+wJub7/Rk8+JCRqx2yFNuP3YxazT5gS/s/9qGTXbXiKSRDoPWulTy6fSe5MfDyfp5yM+TuzPaPLxQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDM7FX5G8d+CAm+N2HjSquhTgScZNBC74IhAny0jki3DAIhAILi/iK6bxcqRn508qKDobtBk3wHslh05c7eoK3GUDfM"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive-0.7.0.tgz_1502957802727_0.4595247234683484"},"directories":{}},"0.7.1":{"name":"react-interactive","version":"0.7.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.5.3","webpack":"^3.5.5"},"dependencies":{"detect-it":"^3.0.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"12cf4f4fb822e170a3be7bf2276f4601103ad773","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.7.1","_shasum":"8c3e167104c1967096e6d19ad5f7c8bf13881f53","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.1","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"8c3e167104c1967096e6d19ad5f7c8bf13881f53","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.7.1.tgz","integrity":"sha512-dv/ZTyhFs0Ijl0s0R7BSMch5/zrIYdMv7C3Y95pkDwCpYt2AJpCiVMVDLlzcWz9BXD6tlwEtM7hNsm2MWOu8hQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXuqzLvC2ksZ6Kv949MIZWIDlHuSNdnlswdWwwyuIRQwIgPqK/byP3eD2v/Z6D6hsnHb3OEI03mdoFIBiXC4kMnyQ="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive-0.7.1.tgz_1502997091996_0.937561061931774"},"directories":{}},"0.8.0":{"name":"react-interactive","version":"0.8.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":"^15.5.0"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.0.0","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.5.3","webpack":"^3.5.5"},"dependencies":{"detect-it":"^3.0.1","object-assign":"^4.1.1","prop-types":"^15.5.8"},"gitHead":"068d699e09dd0da362d2cdbbbe9fb5871b839c4f","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.8.0","_shasum":"1f488043f50108e14830df17553d896aa095805a","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.1","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"1f488043f50108e14830df17553d896aa095805a","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.8.0.tgz","integrity":"sha512-1rY220ebBcIEKJGcO4wKYF5/fx5E0Pa3T4U88SAAFPVKgfdSOwzrf+jmH70GKug7LgYAU+O+YuQVe1BuYeIPBA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD4sRgUKSNaEKegxvvSC2qYJAaU/iMioREcfVkDlZhjsQIhAM2RKjRW3ffU7UGRbMa3JxlgM25IdMZPk/nm0FbRdnG8"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive-0.8.0.tgz_1503031945170_0.6909811061341316"},"directories":{}},"0.8.1":{"name":"react-interactive","version":"0.8.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"files":["src","lib","dist"],"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":">=15"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.5.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.3","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"36144b82bde3d4a1258932ec36b437105a48af56","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.8.1","_shasum":"6e3ba6f3e59378d4381e9104acdce82040241af4","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.11.1","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"shasum":"6e3ba6f3e59378d4381e9104acdce82040241af4","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.8.1.tgz","integrity":"sha512-i8nW1ttUEFSFDVByzW1bju8mlIqBDpP6t9C+MYWNOZjTiU5O/g2iYrYUmqppfWKG3zUet9luiPKSHvwfpHbZcA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGbwPZaUGnCL+o1LFPimeDraq2kksepOtwKcrsY83XhoAiBxEr5wBKIKfhnxajzWaeCwAXze5pEgu1ZLw0by/NoJ6g=="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive-0.8.1.tgz_1506455019186_0.8064943042118102"},"directories":{}},"0.8.2":{"name":"react-interactive","version":"0.8.2","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":">=15"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.3","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"65b802b7915d1241c24cbba8770e6b066182c243","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.8.2","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"integrity":"sha512-hWE1EI2Mtqvq0F6SULL5fcOdusRJLwQWLkScdO9rOahjZt/DcgnCiB04GHFw2ByeX8O0zKERJw20qBvSI9cIcQ==","shasum":"725396e8091a230c0e22fac5ffd076b42f080318","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.8.2.tgz","fileCount":25,"unpackedSize":405133,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcOl/7CRA9TVsSAnZWagAAK5YP/RAMzJadwDk7GKFN+qBR\no9w2XoCt0oz9s6Jkr9FVjNITOKjLQAtXgP+lCMUgdvkZ0dIE8w14PZMQc8y4\ncyhe3knsvCqu6f7sm7v83oDgFwHLS6X7BCu6+O2KLFKSp4Sd6UY5S0MJhR9x\n1TsL2Zomr4+LvnjII8wns1hs6D/teg/puJKnHyAyxHwzPDTWAdtpZAsYkDWa\nKq/zTjqXLUk1X8W/WqGY8cEvOEKJWky2mqhhMd32tHBtqQGIsg+2+czY3Vhs\nz54GzXcTTXvYkW0HNpS80PfcfoBYEERxMHGqzvQfU7HxQ9ZUxQ1SuXAjYeX/\nmzWStPMLlLutH9vHURiUnPgqTMiX2PWrJvd5sWUYkonIDH9J/pnOJHbROVny\nkO/wH4ioTuqCFhLUUozyQnkyuQdRXGq0oX5SYLDDodXuaS8P3OX9TKwXNB45\n48EIH/ABE/xxKHXvSC5WMEqxwwZic/RM0cL+XShASk/klnn/DshS+Wl+uo58\n5oKZmcUCdCpYGcOW9K72nG5Fcz/eu84UWyNQv0HyvyP+JcE3gBbgDSs+/4c/\npNsLlkgwdxE0LHXbUcZ1XGpFAIBViFCRl4KB99IIYEEKqjmY3GE0A56GZhhB\niLX4OmCpcEIgYgiw9nbR3hckvq6gwqjMDCHTBt0Es+rAWqLhZ6EAHHyT09al\njEcX\r\n=tx+A\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCT1Jl/opyZkH2QF5LqG8745rCoiD2SrGoXv2uqs1D+/gIhAN82/x3nK70rpiKsto57Qs1RKENbcofZy0tsjfq4Lek/"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.8.2_1547329530206_0.060560823784898465"},"_hasShrinkwrap":false},"0.8.3":{"name":"react-interactive","version":"0.8.3","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":">=15"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.3","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"57e686c8ee3f45230e458152ea456038c14c1ff8","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.8.3","_npmVersion":"5.6.0","_nodeVersion":"8.11.3","_npmUser":{"name":"rafrex","email":"code@rafrex.com"},"dist":{"integrity":"sha512-mmRvA9aKP7zu9kVfP1AX1egX8tFlnE3DDXq92z0JTZezfOpmeQBzr77O1+mTV54OOmn+M2t6c5kFD5VnuFoM7A==","shasum":"c3c6c3f99b2e5efc20a9ccc54504cf2c03984d5b","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.8.3.tgz","fileCount":25,"unpackedSize":404826,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcOtRsCRA9TVsSAnZWagAAsVMP/0xv3tk8kQHRJZKFxISq\nhfBD06sVdyNG7AMvbk5kK5PFU/u5qsAHiQgmZ4VBkmI+I/+u9/Cwk1GP2YO/\nphS327sXBXGQaz0DOAqdq0kgUNlGBaXE4puui7ANEuhui0N8yxbKiSDJ37nQ\ntu2aw1tDWmpjlGRtZLtQPBUYfoqRsFYS1VEMEXiBw4lILTIJKBCSaQ8HLeI5\ngim3HXyBTdvYd3MEsjr3TKVDZ0FpaU2YdQmbphmUVAV9ErOgNeKeAzWSnTwS\nmyhnDiM3uh5N9vhMhhObcpMWSvg8/XzbfsWJLAebKK8rpVkT6LdLQd5HlmGG\n0Ivtct1R/I44gSmdPGvgScatS1y9P6jxLSUmzY0EXsiRaaYP42A16oWbNAyY\npqjlMwWSr016Da7hlMT5C0djD7uexr3YdES0wuh0ytIcvjFG5VME4seE1vYI\nJ+TCjlm+WLZZsbIk15TBDFSagtURs2qgYA3VSP9NgbKraap9CGV6ReVgqA6V\nhGQWIIm2Z5GHrE5ofQuDPweL42WkfSlyOx6n0Wl+XiEZgXjtpu/Roe+xg3ho\nExf2iIcJMNKo8mJCXiexnuhljQhqXKfFEy80/vSTgkhk9e0NuVQPLrNLCZwi\nu3c8IaNurgO7EZcJ3sFbv7LcPBXxVHixPeJ7SJM9DLpmGorAKfxKWYxBq34C\nt2SR\r\n=9ieV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCNgN6xQCyZ1ymg44zlDpsL6Pw73/xycsU0jQLAMSd0hQIgPU1wvekTw5lQ8MhYII1JGsZnc8EquqJna6CsLXjQ6Js="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.8.3_1547359339839_0.4170444597544949"},"_hasShrinkwrap":false},"0.9.0":{"name":"react-interactive","version":"0.9.0","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.3","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"ca1a38e6b4c791757585ce671de59605f6f53db6","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.9.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"rafrex","email":"rafael@rafgraph.dev"},"dist":{"integrity":"sha512-Hh8WI6smBi5DaUXzK6z5pHVLB8jMKIQhDqOfxymN4zG5us7OKLq5VR4EsuPuyvJwKgH1MAA3vxdyjs56SjmyRQ==","shasum":"d5405b367e43cc066b56a62340f163208b4c6a20","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.0.tgz","fileCount":25,"unpackedSize":405177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdem+0CRA9TVsSAnZWagAAi2cQAKMWgvub66u7bAX0ozr4\nymEpuvekqtkmb8uHIuTgMRZSbZ1ZxGD7sXoskOV0i8IogGLNz4bM1jr6SmKP\nnSHq5AQVI1KaOQ+RY7Ma7QdaZPjEwvTClFBNbVcqcJYWJrIzxD2AYUVbHxeN\n0Tisok91jz5wEdQWPWx6OXfwOGrNQejmCsRrj3Kxax73lzrdtSt8Evn6xxx3\nXPpkI0naeU4cZK7lGzhF0raQ+5The1xqfJfUTqfFm1sb+gLI8ax9KJEsZAZH\nGrra68XTwgBiisgdVsjd1iFjqaaYplslsTBnkxgSzGlFWCXWZjvC4VrWTw6D\nDVChmKkk2383ruBF0/YNqUwJwczs+K4bTahbr0N9ITAFrt90YWWx0aF9zgWD\nsRQgHGV06jI87gFi8XpFNtbsK20UjbVwTLCIVAZVQyvOTKeJqlbgSkuQokPx\n4E6T59IPx8SX5i0djLIjgawFf8JN/CTE6Er0UiDzBwO0iSF1fAJlqsr8z9vc\niw9c4Jy7IRzSyVRNjhUz9c88I8Byyua6zL2vlRKLsXjUcSrQCYAc71eaABUh\n6djOI2Zok2f0CDH65qFsuLD67Tvx1HXsag5GJz9rxgpojwlRhEQqI/Vqv9g+\nXESqzIjy7pLp2BQpw4+2eUJLM5oWS3UFzWMtUy79+ZboEtVBbSrEEJeF0e0t\nDuyv\r\n=tft2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD6F75aiepQXYOUhyoQFHtS7Gc8SBQ+9R0Whx2rpWWmwQIhAJCLPWKjOU8r7R+7ZdPSdCxS02PLrGCaVbstp4ahWalO"}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.0_1568305075681_0.4945168305743488"},"_hasShrinkwrap":false},"0.9.1":{"name":"react-interactive","version":"0.9.1","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafrex/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"code@rafrex.com"},"license":"MIT","bugs":{"url":"https://github.com/rafrex/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.3","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"7384c7892a41357d9a4c51fb1b472c5d7b5c19d0","homepage":"https://github.com/rafrex/react-interactive#readme","_id":"react-interactive@0.9.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"rafrex","email":"rafael@rafgraph.dev"},"dist":{"integrity":"sha512-ED5RhSARGBJcoCjkVPoe3LBV6tlYEFqx8WHaGTxFPm9a/JW9pv601/QtgnFhQo/4CGqDBCjRWmO+bUMdHitHdw==","shasum":"1a5522218ee4a1737cd894334d0b1c052b3b1df7","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.1.tgz","fileCount":25,"unpackedSize":404870,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdjA6QCRA9TVsSAnZWagAAdfIQAJGYrDnMIWGh1OVVMUOX\nWJCPN3qJt43tcC5zN1OYo1qt9ue2JJV20BLnUcjpBqJm6Em5cgWmkjW9BW0A\nodh6u2z5z94nDs+bNH4znvMWEe5HKTbCj6At39y5kMZtoxPEVD24TqG/K/5E\nAwOuWbg0dxfBFS2mI/mdfWvmISLI9mVNfYDXRGvdG0vSbWbvVl2qS8lFB1ts\nZ3phm6305J5OYyzCKYck+WkuQCXkB2/fEURfrlYVv5Cm2G7/+bwIaz2UhMnO\nqkkTsYVEE+fz0mQMD8VnA3Nc7+9p64h0px09Fjili7LFRjaJT8aoq8zk47bA\npMV8qkhBNZ/r4mL/BjCGgN5pfSRtwxaASv1yfVbFsJQzlkGiSCdskAV7iiE5\nd7mkKv4la9PPwa5L/bP2mtXVOJa7BSoQy2LsF0pa1kgnNMILTOPQka2kwTwh\n38RutKaBgTDQ4C0u7i0YuueeIa0A/BAqK32+CqQuspPxZRYJg8bpd1E+HHFU\nQxaHIlnP2QeMSgGKtLlHX5t17JmBMlSWeP2fpH7MnsnXzWxrK4Me3SI+6nEs\n+BpEKLJvO/jaNPparVsq6xUUhJLq+kVXHFdEgkUPcffAfygJ/3lOV/ERINne\nZZOSrxly0T6eJcO/FAA2Y8iUki4SjY5BFlTYbGf4EMj3t+A5uowCur6qUaLU\n2hC7\r\n=J2Ta\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD74RRvr6jNUUqQvLe4K+X+10ZcTQvCyt2jhgS4RIFhBgIgaO6UgENtVphMhMIA8ErvOX3D0jdZBhdL3+tcdCuq19k="}]},"maintainers":[{"name":"rafrex","email":"code@rafrex.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.1_1569459855827_0.43242720566007775"},"_hasShrinkwrap":false},"0.9.2":{"name":"react-interactive","version":"0.9.2","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^3.0.6","object-assign":"^4.1.1","prop-types":"^15.6.0"},"gitHead":"3619860794de1dfcfd9d8763dae69f095b781fe6","homepage":"https://github.com/rafgraph/react-interactive#readme","_id":"react-interactive@0.9.2","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-webn58hG7AGDeubeNnCQnUMFDpzYXK60Ovqo6qmAZ5+kaF7XtVzD/RcxsqLoIo81tOgeVyhULPg+rzRkakZjWw==","shasum":"b1044b83b86f8711450ac98d4bf5dc6553f58af9","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.2.tgz","fileCount":25,"unpackedSize":405349,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfW7QSCRA9TVsSAnZWagAAPi0P/3RXNfZ2l2yA6AQj2PXx\nW3ZH+ZYOV84ZXL5BR0OgmDdKf51epMP2RJPHfquWUqqBXyaQ/djlT57M7cO2\nmzLa7eW6sijGXiHYN/0bGydfgxWTp1OQjb/WI13KN6WTAi/zFogu4stYhRcG\nwHu6CCxNKw/kDYwdbYigV3UGorGHDYFY2aawfWhRsVz0R+XiGkIYH2ZCR9FH\n3Xww+jqP0AZNIG793me01obd+ekwzInZGEaka2/oI2R+RnMY/pciK9OwkGuo\n+Hh/2DXV1Lvv60nmO1K4u6ImUsB2MMT/E4xciSkUxTlUcbKkAMLPRDi0X3MU\nfEU3a2aUQVQ16eWMvG2jTFL+7J2m5V1OBNnQrk5cziym+2tcQnu1CGiNy7f8\nUQBPvV2gCEXGRU5K2p31oHpK7aLxDlyRzsw55Zo9ePzt8+KcpLCRUZmxe5sk\nRuS1vS+HSHQDXtwbgkZDug3uFQc92yRI8Cv2vgTMIfCSgzmZ46biRpTFFKrO\nbtW0RGOqKUoCnT1zGdbPR38uww5CbFVdWt3b7HGME3yp5Iq4vFL+fweFEkZP\ndaG63fpH8S2nrS0wsetOBBpuMU5uarfL22Hg3bVN3RGC6bUDEhEvG4olqfsY\nBloC5uZ1Nvb5kjUkJb662ROIiR9JOd7hLPQQwkgTi6wTyKpPLBNwd5NLR6UI\nGqBk\r\n=xtrg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC0WtqU0amw0zGDsJeBqp8PE7Nl7lDaS8kYv6GpJv3apAiEA1TDhgF/kURjjtC1U/2WbiN0seGdeltmnK+WdcgbjDYU="}]},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.2_1599845393630_0.00949435086410122"},"_hasShrinkwrap":false},"0.9.3":{"name":"react-interactive","version":"0.9.3","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublish":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^4.0.0","object-assign":"^4.1.1","prop-types":"^15.6.0"},"prettier":{"singleQuote":true,"trailingComma":"all"},"gitHead":"9b10481c79c3982799c5183d6f4059a870292d73","homepage":"https://github.com/rafgraph/react-interactive#readme","_id":"react-interactive@0.9.3","_nodeVersion":"14.15.0","_npmVersion":"7.2.0","dist":{"integrity":"sha512-TO6ETo98q7WE8ZSgl8W9Hv8D0ezFaVCjK6kvoYYge9sp61kBxgt+fOz1uMzUmKr5/AOQHX6H7zxcQHtyDFbjKQ==","shasum":"8df741514f13f183cd130ce795a73852ff5a8027","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.3.tgz","fileCount":25,"unpackedSize":400780,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf22TnCRA9TVsSAnZWagAA/GIP/2p7ngpMzCCP0fd+mnVO\nBh+SZmiWZfpwWHWSeIEWPumucBEKRQTkxhDaGlmzIliYND2HIdz7KUOZ6fMf\nyaMjAsyJzi63eProxaXV73K377V8zgn27avfxXo0J1ioJ2P2G1iTDL5ui0mN\nieF35CsARiLQd0OJoU7UhuqaEA+qonf9V7NJTTnHURaHtMiDdLbbJ7ZrWhOV\nx8YGH4RL/szCOENKucvwHegKq2793xC37ft0rb3tbUQtl3jNiv6K/jLa6aqJ\ncTQ1kkTx22YssfW+vjJvw/6Ni1jPf1g26ogtZjL/rWrfD8CoShgvG9xQIepg\n2FPJMmQqyvPMALsbt8Y2t5ecDeCxZjg57T5vHoYjD6IfvYG2+u2sdpGxygQp\ngt9OTwshSLlRVpCSCGL7kgkYgu3eGTPyAxDSfpNdk2Y4fXO/54o5pDCxSeql\nhG9T072kTJzhlztiMl2EgdsXRFgdCa0QIPFWJhUZlEEKIXdLzCCvxulYAqH2\nL8Nil6qdS9DRrZ7yEklz6kr2eIIYTeNdI/hXulpFdoYQ+NxKmEzblWeTbgtb\nSHdu6wuhGEzMggHs8toyIQimBgNDBW7ma50B65KanZ3V1PCFQC34NlJuY3RZ\nWteZAvczplze7/FkMipEC+ZhLlDOJKnnJe+JZrKCV0kJkhgBpD+0CZhl3Nks\nvSyN\r\n=+hm8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDoA7bHO+I5FQ5M7EScNx2Z+z8AP88CFQG7rpNu0vtZUAiEAz8QS+/GYZp0L17bKT8XupfrDwzifreATLqJ8rDL3wWw="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.3_1608213734882_0.5399000084814165"},"_hasShrinkwrap":false},"0.9.4":{"name":"react-interactive","version":"0.9.4","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublishOnly":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^4.0.0","object-assign":"^4.1.1","prop-types":"^15.6.0"},"prettier":{"singleQuote":true,"trailingComma":"all"},"gitHead":"36e2842d4910d39752f3d4925e50263cdc7896db","homepage":"https://github.com/rafgraph/react-interactive#readme","_id":"react-interactive@0.9.4","_nodeVersion":"14.15.0","_npmVersion":"7.2.0","dist":{"integrity":"sha512-oqLZGSuocELs+59mGwW1DdnFPXEa7iejftyqbIhV247TmZswqGKI09Z5VYtJ1gFJMi9V6XE/yhuWbSvaeiW9HQ==","shasum":"076f993c2b740f2867bca93b67f515e5b13d0346","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.4.tgz","fileCount":25,"unpackedSize":400453,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf22XaCRA9TVsSAnZWagAAbdMP/jCqW9j/dTRUCtg90S0e\n6FnapNdid9grscXAiua6oF/yioTVMzfJofFjU9ogui7JzuJVfiO8nHQLt6zN\n34HYkC9Z/wwmmFVJQmI8z5yMMLtzGJib98yPXE6p9nONt/urZJgGiHrsseYx\nAmTXQh0hokuUeeE6hfkVK2UOUxWF3/9nx/6tcYMA8PKwtGeN7CKew7LNePRO\nl/aOZ4aotzjOc72fEwHxsklEbf/vuFYZadJcsWeO0Vba2XNSybOQ4scQjq+j\nY2AkBXMW0j5ZOvDUMGf4gH8EMjuQ1cLJGGd/kzmsPDtqCzCyOGPYepkA2+WB\nYObekzftlXpCcBzDeGII52HhOLZjkratzoPa0zhg/F7ha52WkB52oqj8NCDk\nNna85qnvNd7ivp1wvKFw0UCzThDmBJSzD6XWggPSIDUxIF5u+1hoaUeO8bt0\nkXv/Kz2lJQtuxWI4TfVkxhJKbCZrXOrdKPGkbxy43sSAzY/nCEcZIaj/dnTP\nkIdK/qg0KUdmKYbTG6r/+3ZzOcMls0xZ5YkthbYB4LGBit9+LaPWk+I4z5Dc\nbzb6ah0yM89Iv+/JKOlric1Y373XpfFr+MCwywM5sCqciY9v9UFFFYjj8Gf/\nsM7Y+/UrXQBggpxiQh8qc/8xb+Mn7F6WXtNPSdoYx+VgiBBgtJboJHCAIkin\nI+rr\r\n=4KEn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD3tKJ1/JZLULQZxqzfV3xK9JSvFcf8QoxCUIkbZbQ5ngIgG5r3mWvxr6z5Z7JZNN6FLL8yvE9T4ErZmNy0Ix50ESA="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.4_1608213978214_0.9361135640682305"},"_hasShrinkwrap":false},"0.9.5":{"name":"react-interactive","version":"0.9.5","description":"React Interactive","main":"lib/index.js","scripts":{"build":"yarn build-lib && yarn build-dist","build-lib":"rm -rf lib && babel src -d lib","build-dist":"rm -rf dist && webpack src/index.js dist/ReactInteractive.js && webpack -p src/index.js dist/ReactInteractive.min.js","prepublishOnly":"yarn build","dev":"yarn link && babel src -d lib --watch"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"peerDependencies":{"react":">=16.3"},"devDependencies":{"babel-cli":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^7.1.2","babel-plugin-add-module-exports":"^0.2.1","babel-preset-env":"^1.4.0","babel-preset-react":"^6.24.1","babel-preset-stage-1":"^6.24.1","eslint":"^4.4.1","eslint-config-airbnb":"^15.1.0","eslint-config-prettier":"^2.3.0","eslint-plugin-import":"^2.1.0","eslint-plugin-jsx-a11y":"^5.1.1","eslint-plugin-prettier":"^2.2.0","eslint-plugin-react":"^7.2.1","prettier":"^1.15.3","webpack":"^3.6.0"},"dependencies":{"detect-it":"^4.0.0","object-assign":"^4.1.1","prop-types":"^15.6.0"},"prettier":{"singleQuote":true,"trailingComma":"all"},"gitHead":"7e650781e6fce321ec297e39f8101f21ebbba8ab","homepage":"https://github.com/rafgraph/react-interactive#readme","_id":"react-interactive@0.9.5","_nodeVersion":"14.15.0","_npmVersion":"7.2.0","dist":{"integrity":"sha512-6c5F3L3JHZ8AAjqwx2wXjADpqPsihiM0tPlCfIcJ8AoIydDf6BCC93B7ieye4GOleKkEVrF48Qdj0q1XghCwxA==","shasum":"0582b94e71fd84c9e16aa5bfa67a8ecc9ad750cb","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-0.9.5.tgz","fileCount":25,"unpackedSize":400447,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf3SAaCRA9TVsSAnZWagAAfH0QAKRYQZoJU7RJ5J9jzjLk\n+S38vi+5fK2eZNYeWhJrXoANjUwyvIYspCwDvqeANiNGmcooGYELDxTxDhct\nc7k8tsZVWg5czYSYVE2MpK/xQNRalBWPUKop0YTGKoTs074TgzskSnjohJyf\nu8HYxK0PPYaM4o1pe4ADYbAKj19Hb9HSHgNLrV9Anx7+sDCDU4TaFeeJWw1a\nxdVbgAbNq0ix2OtuxjzF27feghHPXc3P77mP2z1Bo+U3osS8Cjr8CAoTq+W5\nLz6DIpyQOs5FC3QTKaZr7BjZHQMZ9uQ1PyV7+t9jbCcvbFGcSTCoAFIsoPgZ\n0R/RwjHN/q5WHtS7kTT6RZkOMPxtFxjOXduW5X1kibshpnOFsd45Q1Y7glyF\nvka3UWTxHc9ZXE9kNPl8iAVkGjU1eluJ+j5DMPvFn+OhI7eeUTckoo6FMc6d\n4dNNYZp0PlSZ6arRZq92oBN5cw/YbQm+CNc4DywJRgzd2F6fqa1rzItHWQsi\nNY6WPjhTWKb4Zhq7jKCTBJH7rbngVd45JpGcjsttg1WuIpzxyIBcqXP0/rHN\nf2/BLjYXtWRSgb//5h7jRq1t5TGqVBJDtCaQ1umjQFLXvUiVmZ2BlygZ30Bw\nqIwDbA90jo/M+rIzIRJAWbVq1ONxdpBsWScUNwOIOIiRu/dZ0KUk2q6SRcik\nW4fv\r\n=TBFV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHjnsKfyMXULdMHdZk30xEk1aCY/XCR8zhYP1c8ZTj1mAiAVjKeOak8wzXgpwBcAC4ofB3eT9wfP7wlx43KpanuHag=="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_0.9.5_1608327193508_0.7602971561910743"},"_hasShrinkwrap":false},"1.0.0-next.0":{"name":"react-interactive","version":"1.0.0-next.0","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.6.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.2","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `mouseActive`, `touchActive`, `keyActive`\n  - `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n**[Live demo for React Interactive](https://react-interactive.rafgraph.dev)**, code is in the [`/demo`](/demo) folder, or [open in codesandbox](https://githubbox.com/rafgraph/react-interactive/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### What the Interactive component is rendered `as`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThis is the state object used internally by React Interactive to determine how the `<Interactive>` component is rendered. The state object is also passed to the `onStateChange` callback and `children` (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusFromKey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive accepts a style prop for each state (`hover`, `mouseActive`, `touchActive`, etc), as well as `commonActiveStyle` and `commonFocusStyle` props for easy inline styling. For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n}\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  commonActiveStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst handleInteractiveStateChange = ({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Styling children based on interactive state\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to it's children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`useWebkitTapHighlightColor`](#usewebkittaphighlightcolor-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\nNote that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n```js\nconst AsComponent = React.forwardRef((props, ref) => (\n  <button {...props} ref={ref} />\n))\n\n<Interactive as={AsComponent}>My Component</Interactive>\n```\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the state changes with both the current and previous states (passed in as a single argument of the form of `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current state of the Interactive component (note that the function must return a `ReactNode` that React can render). See [Styling children based on interactive state](#styling-children-based-on-interactive-state).\n\n```js\n<Interactive as=\"button\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>`.\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `commonActiveClassName`   | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `commonFocusClassName`    | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `commonActiveClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `commonFocusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `commonActiveStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `commonFocusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `commonActiveStyle`\n- `[input]ActiveStyle`\n- `commonFocusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible . To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `useWebkitTapHighlightColor`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive removes browser added `WebkitTapHighlightColor` styles because it is generally better to use the `touchActive` state to style touch interactions (you have more control when using the `touchActive` state). If you want to use `WebkitTapHighlightColor` then pass in a `useWebkitTapHighlightColor` prop.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = (e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on a React Interactive component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of the props that the `as` prop accepts and the props that are specific to React Interactive.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveComposableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the `<Interactive>` component.\n\n#### Composing `as=\"button\"` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsTagNameProps extends InteractiveComposableProps<'button'> {\n  additionalProp?: string;\n}\n\n// as=\"button\" without ref\nconst ComposeAsTagNameWithoutRef: React.VFC<ComposeAsTagNameProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// as=\"button\" with ref\nconst ComposeAsTagNameWithRef = React.forwardRef<\n  HTMLButtonElement,\n  ComposeAsTagNameProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n#### Composing `as={Component}` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsComponentProps\n  extends InteractiveComposableProps<typeof MyComponent> {\n  additionalProp?: string;\n}\n\n// as={Component} without ref\nconst ComposeAsComponentWithoutRef: React.VFC<ComposeAsComponentProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as={MyComponent} />;\n\n// as={Component} with ref\nconst ComposeAsComponentWithRef = React.forwardRef<\n  React.ElementRef<typeof MyComponent>,\n  ComposeAsComponentProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as={MyComponent} ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap something that has a CSS `:hover` state. The `:hover` state sticks until you tap someplace else on the screen. The reason for this is back in the early days of mobile, the web relied heavily on hover menus, so on mobile you could tap to see the hover menu. Sites are no longer built this way, so now the sticky hover feature has become a bug. React Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"4d76169cd956c76dc6dc2eab5a7f29ddb0771415","_id":"react-interactive@1.0.0-next.0","_nodeVersion":"14.16.0","_npmVersion":"7.6.3","dist":{"integrity":"sha512-hUwUHclldBaLwdVLDjCHyq1QAnpoqTwJKgwnfOmkp4UdCXrkOrJ0pLa/f2ZxVq1i2vWeL1tycFg2qgleyd1Q4Q==","shasum":"dd000eb935d3aba5e3e162bf2d9ce6f86bcaedda","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.0.tgz","fileCount":13,"unpackedSize":222656,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZMkCCRA9TVsSAnZWagAA8dcP/1D+VjGM+WycZa6MIWJ/\nZsfsvj7UPmT6fAvnDna0R0tB/BG0P+llfNWQs6gDagxpM2EKHGnb6yBf4Zgb\nG1u1eWxcuNjoOP+BwoxYXtuH7KqacU1Ahxcv0wTWY11pglIdYEWDC/2zNIAD\n75oe6CvkPtJ4bMO1uCsuhBoeLqoON28bEMTo/aNsLU4UkpUQatooKuEplEyF\np+0d56dH60ulBd5mcnA6UPFxMOVWVnFncL6azM14qi/8+VQtnqlr8iUuddCD\nVMmfEeSRCp1UWasE3MvQclC/pZ74Lw1BFQexS8DV6FaCmR2yjyLpQizXLPS+\nU1UTqy4yx+HWgM/y6yd0560jyqG/LUY8W1GLWrgxHD7WCemZLq9lw9LZtLl5\n5iqTp0QUKuOYBjp091yxaxdZ1JLq5Wtuw1M1u/rjW7X3RIw32sZ2hrZMZ2w8\n3OKLfQ/md+NzJnrCniJ426bIaSqu3SyQiec/Nm7TjFACDwIkCAn/JWuY/dr7\n++rlBmjTvhRZVEM6Wli5FpDoekX0I9sxw/O7LZ78285trDQ5BqKXVXM+rAhk\n6RvYO0RAXw8uHtPHvYcyldfMAwM+uJCKEeVxi3ytZAMagdYLHHKym8i7TDIv\n29D/Ovd/xVDJIKs6ShVXQaFIa6S9lYcGiG/wbEsoTlVPbFHx7DAhWQPHehQS\nMkK0\r\n=NeY4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGovUd1ZjV+FOK4V8+kxcgKaEEeIH0sjYRYtDO9in3VYAiEAyk8yRMqFR9l6nURDnHXIPaT8S8IcB/BfBWDHjvvA8n8="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.0_1617217793824_0.18404003980094807"},"_hasShrinkwrap":false},"1.0.0-next.1":{"name":"react-interactive","version":"1.0.0-next.1","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.6.0","react-polymorphic-types":"^1.0.3"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.2","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n**[Live demo for React Interactive](https://react-interactive.rafgraph.dev)**, code is in the [`/demo`](/demo) folder, or [open in codesandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### `<Interactive>` component rendered `as`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThis is the state object used internally by React Interactive to determine how the `<Interactive>` component is rendered. The state object is also passed to the `onStateChange` callback and `children` (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusFromKey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive accepts a style prop for each state (`hover`, `mouseActive`, `touchActive`, etc), as well as `commonActiveStyle` and `commonFocusStyle` props for easy inline styling. For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n}\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  commonActiveStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst handleInteractiveStateChange = ({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Styling children based on interactive state\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to it's children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`useWebkitTapHighlightColor`](#usewebkittaphighlightcolor-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\nNote that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n```js\nconst AsComponent = React.forwardRef((props, ref) => (\n  <button {...props} ref={ref} />\n))\n\n<Interactive as={AsComponent}>My Component</Interactive>\n```\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the state changes with both the current and previous states (passed in as a single argument of the form of `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current state of the Interactive component (note that the function must return a `ReactNode` that React can render). See [Styling children based on interactive state](#styling-children-based-on-interactive-state).\n\n```js\n<Interactive as=\"button\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>`.\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `commonActiveClassName`   | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `commonFocusClassName`    | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `commonActiveClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `commonFocusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `commonActiveStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `commonFocusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `commonActiveStyle`\n- `[input]ActiveStyle`\n- `commonFocusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible . To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `useWebkitTapHighlightColor`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive removes browser added `WebkitTapHighlightColor` styles because it is generally better to use the `touchActive` state to style touch interactions (you have more control when using the `touchActive` state). If you want to use `WebkitTapHighlightColor` then pass in a `useWebkitTapHighlightColor` prop.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = (e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on a React Interactive component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of the props that the `as` prop accepts and the props that are specific to React Interactive.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveComposableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the `<Interactive>` component.\n\n#### Composing `as=\"button\"` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsTagNameProps extends InteractiveComposableProps<'button'> {\n  additionalProp?: string;\n}\n\n// as=\"button\" without ref\nconst ComposeAsTagNameWithoutRef: React.VFC<ComposeAsTagNameProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// as=\"button\" with ref\nconst ComposeAsTagNameWithRef = React.forwardRef<\n  HTMLButtonElement,\n  ComposeAsTagNameProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n#### Composing `as={Component}` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsComponentProps\n  extends InteractiveComposableProps<typeof MyComponent> {\n  additionalProp?: string;\n}\n\n// as={Component} without ref\nconst ComposeAsComponentWithoutRef: React.VFC<ComposeAsComponentProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as={MyComponent} />;\n\n// as={Component} with ref\nconst ComposeAsComponentWithRef = React.forwardRef<\n  React.ElementRef<typeof MyComponent>,\n  ComposeAsComponentProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as={MyComponent} ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap something that has a CSS `:hover` state. The `:hover` state sticks until you tap someplace else on the screen. The reason for this is back in the early days of mobile, the web relied heavily on hover menus, so on mobile you could tap to see the hover menu. Sites are no longer built this way, so now the sticky hover feature has become a bug. React Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"6bd0afa149645a57a7ff611af3fa8011800d59bc","_id":"react-interactive@1.0.0-next.1","_nodeVersion":"14.16.0","_npmVersion":"7.6.3","dist":{"integrity":"sha512-/cfcN58dUBtTfLo31wif4E95QwOHNoA0g16OBREIMROiB7dMdUtSMDTacChD6gAVcrSsOCdwV3iAqYfkZobsUw==","shasum":"58abdaac75b712b0a591882b94dbbb0637b1fc41","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.1.tgz","fileCount":13,"unpackedSize":211249,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZk+nCRA9TVsSAnZWagAA42cP/0KxTXwG7qtsG5C1fCd9\nPn+H0gJkOLfqtC74/GZ4PSNMX4c/3CYCrZm1wJ/+5yAgEfLOEyACTR+1iRH2\n/KQBS7GJM9TvdTquSVrE/tFiun+e0ooFt7ILsIqqalchDgs2n4APSS/gitBm\nIqtc26QTdgkF2eIw6jhYT/g52Jn85bQWBeDPAvtDFocRZRRMtB/sC9l8qgjc\nh1AxQPkxdgVaVxj0xzSa91FK1b12RamIHFsonxr122x65c1Y2geB7PwOek1D\nm7Lm+dMucMSWbUm1O7R3S3fq3R+s4CO71kpduDYouX9NF5yfOqR7dRYyrrPh\n5jIwCtGyG1qmQz81xek6PfRSYTGQkkOlB14yPXQYOaKsZHLaTdh1BaFIf1E/\njlEFcP1aK/vlCOX11V+LFBxQKk9UYR91pxSUUcA5QR2j49rEtQDjGhbqydTI\n6SOQ+kItqJF8VvGs883gaiB7GbHGvdZoNaxZeNWitA7iVBFMu+Ugvj8SjupC\n4mQTCIgBtbGrOqD2juzDnD7lXtmyQkXaa6y21Exr5VQJmQLCUKbUO+0AnRBY\nA9nppboPjn8QEUyHk2SRpAvQGc2w2YhFquSOX//o7igoypzePwhXYVek7W+g\ng1uZ9tTfLI19LEK7I4ePeNaXEWMsvNVDRQztaq7+0b8Vzg22hufpvuWwjj7S\nU5Pv\r\n=o+rG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG0wA1TI6g507j6yLKCeGvshB7z/RXpWBImQf1cwq2JdAiAS/OpjWbR+zN1RJDsQAg+bYi40ICpumTTT0lJoGef+vA=="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.1_1617317799183_0.2710155213191683"},"_hasShrinkwrap":false},"1.0.0-next.2":{"name":"react-interactive","version":"1.0.0-next.2","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.6.0","react-polymorphic-types":"^1.0.3"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.2","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n**[Live demo for React Interactive](https://react-interactive.rafgraph.dev)**, code is in the [`/demo`](/demo) folder, or [open in codesandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### `<Interactive>` component rendered `as`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThis is the state object used internally by React Interactive to determine how the `<Interactive>` component is rendered. The state object is also passed to the `onStateChange` callback and `children` (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusFromKey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive accepts a style prop for each state (`hover`, `mouseActive`, `touchActive`, etc), as well as `commonActiveStyle` and `commonFocusStyle` props for easy inline styling. For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n}\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  commonActiveStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst handleInteractiveStateChange = ({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Styling children based on interactive state\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to it's children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\nNote that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n```js\nconst AsComponent = React.forwardRef((props, ref) => (\n  <button {...props} ref={ref} />\n))\n\n<Interactive as={AsComponent}>My Component</Interactive>\n```\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the state changes with both the current and previous states (passed in as a single argument of the form of `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current state of the Interactive component (note that the function must return a `ReactNode` that React can render). See [Styling children based on interactive state](#styling-children-based-on-interactive-state).\n\n```js\n<Interactive as=\"button\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>`.\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `commonActiveClassName`   | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `commonFocusClassName`    | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `commonActiveClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `commonFocusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `commonActiveStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `commonFocusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `commonActiveStyle`\n- `[input]ActiveStyle`\n- `commonFocusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible . To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = (e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on a React Interactive component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of the props that the `as` prop accepts and the props that are specific to React Interactive.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveComposableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the `<Interactive>` component.\n\n#### Composing `as=\"button\"` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsTagNameProps extends InteractiveComposableProps<'button'> {\n  additionalProp?: string;\n}\n\n// as=\"button\" without ref\nconst ComposeAsTagNameWithoutRef: React.VFC<ComposeAsTagNameProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// as=\"button\" with ref\nconst ComposeAsTagNameWithRef = React.forwardRef<\n  HTMLButtonElement,\n  ComposeAsTagNameProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n#### Composing `as={Component}` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsComponentProps\n  extends InteractiveComposableProps<typeof MyComponent> {\n  additionalProp?: string;\n}\n\n// as={Component} without ref\nconst ComposeAsComponentWithoutRef: React.VFC<ComposeAsComponentProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as={MyComponent} />;\n\n// as={Component} with ref\nconst ComposeAsComponentWithRef = React.forwardRef<\n  React.ElementRef<typeof MyComponent>,\n  ComposeAsComponentProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as={MyComponent} ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap something that has a CSS `:hover` state. The `:hover` state sticks until you tap someplace else on the screen. The reason for this is back in the early days of mobile, the web relied heavily on hover menus, so on mobile you could tap to see the hover menu. Sites are no longer built this way, so now the sticky hover feature has become a bug. React Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"abfe315026d716e23acf690b84b5c0ce733ca303","_id":"react-interactive@1.0.0-next.2","_nodeVersion":"14.16.0","_npmVersion":"7.6.3","dist":{"integrity":"sha512-COQqxp1HFDFLBVMuLKR4Zgde89pQfyo1qO9TJ1W3zlBjAJnscLm5DtC4+sg5QVUEOzh2f6Vo/TlGItmSo/NGGg==","shasum":"96285a52b8458ca94bede40192a2cb92d310105f","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.2.tgz","fileCount":13,"unpackedSize":209773,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZlymCRA9TVsSAnZWagAA+p4P/RyO88ZC/Bg+45ePqwIf\nJx9K9ZzEKe5glL5Oopl8wwp6KLjBmdWkW+KgMDV/MmnfBX9J2SA3snHEgRah\nrPM826K0tgvC8s5IrxWE5/EFYhGRSbcQx37AVkdpVdSpqZZNZFCYrImJH9ZE\naTfUkNze+04XOShkwk0ymumODCosqG4OgUhlbZ7HrdMJmTFQkAwwUnLJLWb2\nL+9A+OucWMm2+E903lzFh31uz3UxxWRgB2bpj4m80buaybWzqTnsPJeRTPvv\n4Dz6K+SM6qL4ovYdiZEsw2Nah1w7e0kguaxnyQ2vCRcss1JlE1MRCZDJz4vv\nUQrm7wBAZKJBGHbMWSrA2ItLk/NDRd5gE3lpEaa5rkdpeaZCRbtolDdgL1Jd\ncmRqmeAyLgvT9TBl72Dld8itmMB9+nzOkgjcGDBr9/+mcSAeHycFcrGnBpPK\nMYdK/8eiL/C8mepqYT3p78h66JnmJiDV8bO7TCLLmlivMb2DjplpAXLEhAR+\nl77ILU7///Vi9A5rV+rd9SkdE4UIMNPbvte/iCabgZzN0yBiOGeEl2pkkv8w\nQCW5XPDZQEjnqIlBy9syyjouKjciyySFhoUGj321EajzckxE6rLE8TITgYAf\njXPwBkiXQmgBzcwF0MJ3zeRuR6EUr+6NvVJozx3yhsxaKM7FPZ15CdCBnTE6\ndqAt\r\n=kRJc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDSj2Mw0Xeh5ayQfEe4+DuFp1ToiEldNRAB0ChYdMNpXgIhALbRF2qgbEdCIL9TTbNwvbOIk2/bAihqrStmzrSeeaX1"}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.2_1617321125615_0.2765573958905434"},"_hasShrinkwrap":false},"1.0.0-next.3":{"name":"react-interactive","version":"1.0.0-next.3","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.6.1","react-polymorphic-types":"^1.0.3"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.2","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n**[Live demo for React Interactive](https://react-interactive.rafgraph.dev)**, code is in the [`/demo`](/demo) folder, or [open in codesandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### `<Interactive>` component rendered `as`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThis is the state object used internally by React Interactive to determine how the `<Interactive>` component is rendered. The state object is also passed to the `onStateChange` callback and `children` (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusFromKey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive accepts a style prop for each state (`hover`, `mouseActive`, `touchActive`, etc), as well as `commonActiveStyle` and `commonFocusStyle` props for easy inline styling. For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n}\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  commonActiveStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst handleInteractiveStateChange = ({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Styling children based on interactive state\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to it's children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\nNote that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n```js\nconst AsComponent = React.forwardRef((props, ref) => (\n  <button {...props} ref={ref} />\n))\n\n<Interactive as={AsComponent}>My Component</Interactive>\n```\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the state changes with both the current and previous states (passed in as a single argument of the form of `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current state of the Interactive component (note that the function must return a `ReactNode` that React can render). See [Styling children based on interactive state](#styling-children-based-on-interactive-state).\n\n```js\n<Interactive as=\"button\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>`.\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `commonActiveClassName`   | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `commonFocusClassName`    | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `commonActiveClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `commonFocusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `commonActiveStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `commonFocusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `commonActiveStyle`\n- `[input]ActiveStyle`\n- `commonFocusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible . To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = (e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on a React Interactive component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of the props that the `as` prop accepts and the props that are specific to React Interactive.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveComposableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the `<Interactive>` component.\n\n#### Composing `as=\"button\"` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsTagNameProps extends InteractiveComposableProps<'button'> {\n  additionalProp?: string;\n}\n\n// as=\"button\" without ref\nconst ComposeAsTagNameWithoutRef: React.VFC<ComposeAsTagNameProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// as=\"button\" with ref\nconst ComposeAsTagNameWithRef = React.forwardRef<\n  HTMLButtonElement,\n  ComposeAsTagNameProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n#### Composing `as={Component}` with pass through props\n\n```ts\nimport { Interactive, InteractiveComposableProps } from 'react-interactive';\n\n// the same props interface is used for composing with and without forwardRef\n// note that InteractiveComposableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface ComposeAsComponentProps\n  extends InteractiveComposableProps<typeof MyComponent> {\n  additionalProp?: string;\n}\n\n// as={Component} without ref\nconst ComposeAsComponentWithoutRef: React.VFC<ComposeAsComponentProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as={MyComponent} />;\n\n// as={Component} with ref\nconst ComposeAsComponentWithRef = React.forwardRef<\n  React.ElementRef<typeof MyComponent>,\n  ComposeAsComponentProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as={MyComponent} ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap something that has a CSS `:hover` state. The `:hover` state sticks until you tap someplace else on the screen. The reason for this is back in the early days of mobile, the web relied heavily on hover menus, so on mobile you could tap to see the hover menu. Sites are no longer built this way, so now the sticky hover feature has become a bug. React Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"1c9412f79dfdfb1b4ad1d5d1488590eeb413e9e2","_id":"react-interactive@1.0.0-next.3","_nodeVersion":"14.16.0","_npmVersion":"7.6.3","dist":{"integrity":"sha512-gyMWMCB4jEPsFIaIPX6Pz78Ohcr64B0KHR5/WZvkAcR1i/6XWMJB//J75P14XF/AKBs6IOrFfdovdRPSCOWTFw==","shasum":"26094d6fb60fd70db03e97df77f1c5c5687e33fc","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.3.tgz","fileCount":13,"unpackedSize":207726,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZ1rlCRA9TVsSAnZWagAAD+gP/14b2rCPMfB7yo6RrCbI\nvjsdIPwCNeR7fILqiXMZhuRvdEuQ5qPcAQ8PEqIWVxU+vqm/ExcVLwZXV1M5\nRZibfg704yLS4nJTZRTnn6bBMbTC8XKEnzKpqd8nc0jfYHteEPdqVHQQHb7R\nlzMI5uAqB/obv8p44l6l5vOGGcVdwwc8SHK/nM77MxZfy8Lvd9uCPAdMtveO\nvib1rKVofQWMctosN/NmnM4utlMyrYqgdep/G6X2H8UnPdjBQb+eyGRuECpR\nG/UQP1RhM7s7HXVJiLNsA9V/d7z7R5GOT17hfLwAmPhOXwLVTn92m5cKdXU9\n+BBYCLJof6CuQyQmKFxNqg6UHtj+BvwQFYiWYrew3QUDC41Ui0gvfFxdJESI\nEtoHmrBI+Z6Fomt1aLwYL/JIpfQ0DTH9Na0N3H1QS1xXUifU6zP1eUv0oBul\nAIinBSj6yeibq+/OckRlSAkyLzsW9Lsv/ZIZbXQ40xlxe/UB7V+qsjwTE7ep\nQ8BRDF9QcwxaO5v7MORNsWIHnBipDdrfhXvPg9a1SjCXdl7IiDlNsjf2awKy\nTmMOgcf8gilZptftP7OEsDLK+zWvhVay3rdT/xzu2Dgu3LUFHqcXvSZWQG/j\n2S8iQoKd6EPgZ63c9zKYQSe3TLyUxWuvcfYcJf299fTrZqKNC4WjJjAa4XKX\njhuo\r\n=96Vu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9LAE8dP5k48lMmI9dsIC6gQXurzSS/gxHtKHuy6qYKAIhAMDIrQVoFRtvd7I2de9JEy2m1dJPIYtyqy9cUiAUmSxE"}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.3_1617386213378_0.09247979023921027"},"_hasShrinkwrap":false},"1.0.0-next.4":{"name":"react-interactive","version":"1.0.0-next.4","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.2","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the classes added for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n}\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\nconst handleInteractiveStateChange = ({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state of (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = (e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n}\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the entire `<Interactive>` component interface, but sometimes it is necessary.\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface WrapperProps\n  extends InteractiveExtendableProps<'button'> /* OR InteractiveExtendableProps<typeof Component> */ {\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof MyComponent>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"ca2d64e68f0a5896648fc5a926023886e4e1c432","_id":"react-interactive@1.0.0-next.4","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-WJUAPM1SmEjQaMeHxpnvQ6nScW0s/4iFp5L4BoJdEEoRi7T1oclAa/gx8duXquY4yi3qjdmo8ZrEeWmFGQVlWg==","shasum":"24e99afb8401b0eaa9f85aff9bef1683a237dee1","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.4.tgz","fileCount":12,"unpackedSize":222436,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgalJ/CRA9TVsSAnZWagAAG8EP/iFw4e2m3LnlVOEzsJup\nIVimpPSoA0Xy68W6aqn8wMzEjjbm6rbZtA6hgCdZ7KM5CmE0Wf6iAol+IGfy\nUDzc9sTMVFG3GT8/qPPn2SI5XaIQmXuCN7ycN8loHePQ0jJTfeBj62qtsNXB\nLyzfh8yZ+k1SUjBPbOt+5W0aP/CADG67frUswvNYIv8CxqvA6R4oKqjrJw2z\nmopEzDhZEW3/LrEpjUOUGbtVhyF5baYY9AYuASAC1JSy8rupxB2P88QpkC0L\nKixYMj6PC9sd2pPERBSsuhI0On9PXrWmvPVPHTcriOkriLvc3Zey4AQbHXdF\nupBPuxO3flW4GeTMgBYlSFRnoXi/fNSqXmU4dcCUrF+AnBYcfCgUz2WeaUWH\nZ530shFdxW2dwR+AP6+z8LkYgIPyvmpGrvePoDfPYvUgYvpRvj3Up8PPIJUO\nImHeddZo4OPVdEQI6+JXxtNkROLiXxCGvFAKpeMvitblOlRX4VlVq8sn39rA\nOnsKwjouO0LKtDQiKLVo9km8F+6k43VlwdCEIGNlxT7Q7ZEHAf4CrdlBSYDI\n3vfs0ysDQR1eSXk7QER9WyG5VIt2AyvSszujBc3hSmb/RZ9wpJR+DJoBIntH\nvT8qXyFyZ8o0XiP3tuV6qMT2kncnV/wN9JLFU8a6u/vbfOR0c9bAy4dTZ2UV\nTTnU\r\n=Wcdc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFvJ+dsMD3foG7g3bm4RzryTuKdf7XWQBqvoctnYhTN/AiAf8oHpuEpJnZ+DfFSCh7/figh6Z/bzXTVB904s3IhKNg=="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.4_1617580670486_0.026595918512990036"},"_hasShrinkwrap":false},"1.0.0-next.5":{"name":"react-interactive","version":"1.0.0-next.5","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["eslint","prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the classes added for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\n...\n\nconst handleInteractiveStateChange = React.useCallback(({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state of (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = React.useCallback((e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\n// called from someplace else in your code\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the entire `<Interactive>` component interface, but sometimes it is necessary.\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface WrapperProps\n  extends InteractiveExtendableProps<'button'> /* OR InteractiveExtendableProps<typeof Component> */ {\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof MyComponent>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"2a5dd4534df50e1e767cb429495d8a9227bad611","_id":"react-interactive@1.0.0-next.5","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-WhKHZpiDwlGOVOwSmkfr8ffpBuaParW2Xgn3QJrbhFm319lsq90d1aqojj9LSRr9VLK2YgDoayPEms9wIXsb5g==","shasum":"af70e9b533731577e4333aa5c942c410f42a5e08","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.5.tgz","fileCount":12,"unpackedSize":222591,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJga9VaCRA9TVsSAnZWagAAdTMP+wVROQDWQCyfOidZ5I67\nwYXVvp1F5lbghf6RqvtGl+iz3n5uGT4+sCoIftd+UbYRg+Q9AXOawNPoqRQF\n3CPPmsvs+qtMUpNi6fVeqNar4MEvMjnpSGlcYdJLaA66HDdSGuKm/X/mMgna\nrGc8XAKydZhDBqZ9l9+qoUNj6llteHjyv8PpFjbBruihPZE+GSFZkhSOge81\nfK1tF9sQ+EF6dmS8SHEnxTPZj4lLRZYZUkdfhSzahGQTUxKUXw1KgPeAtLFJ\nWmx3Fv4DBvRjUZ6NACZCCGJPgXOYxt6ndA2whiPGIqc5taHYCCJDHB7GWys0\nZ+DKK2sYRN9pG+Gpw5JnsI9BXMD6jDv3o8NiBZkVgkemStwZODijiNcSwCQs\nfk1VAvW5WcngO6xo4JQ5y6F3BqYAc3PP9LkD16rLaIN6oLIWyn7xBhKuLWjT\nmwMMrb5EeUPsjBZqfqLpqL5KAbAP/W19NSUIidU8J26wSAO9VSnLJbSqumyT\nNVkL7uLtfprs8kBtqKFcOc/1BMs8Mz4c4MZbXiJpcKC0qdUCaQ0EbgIQkAE5\nsNNwauUX3lWnXXMMBNCr7lAd9MnKsi+MmUsA0y7QcB08QolDpDhdxemejO0J\noELCXgwGbf4FVZX7V9+BptdNaFOBj+mETb9m9QmrQdKWf6YsLB980gN2bC5k\nXHbp\r\n=JTbY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCMcyXK5b8LWPyf+V+lzGTyyJWJb28HYO8nIAx5CXGDQIgWHAjXMcNPmKCzcfKiJ1ZEMufUmIIlJXZwzT2Ho8PR3w="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.5_1617679705638_0.21117236104983372"},"_hasShrinkwrap":false},"1.0.0-next.6":{"name":"react-interactive","version":"1.0.0-next.6","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive@next?color=purple)](https://bundlephobia.com/result?p=react-interactive)\n\n<!--\nbadge is only for @latest (v0) which doesn't have types, when v1 is published add this badge\n![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue) -->\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the class names for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\n...\n\nconst handleInteractiveStateChange = React.useCallback(({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state of (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = React.useCallback((e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\n// called from someplace else in your code\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the entire `<Interactive>` component interface, but sometimes it is necessary.\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface WrapperProps\n  extends InteractiveExtendableProps<'button'> /* OR InteractiveExtendableProps<typeof Component> */ {\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof MyComponent>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"6e67b620adae838993a1dddb4c69928db70d16c2","_id":"react-interactive@1.0.0-next.6","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-CMFiWcjUMGT6CxA3B78UMj/gUAS1gKkr+fPYPk2zvLJ9wFuwMWXg6tKR5PzPecJmIuujg2w3BtXQ6FMwSV2bWA==","shasum":"85c07c2c35036f8595e8c5462b352333e88e609c","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.6.tgz","fileCount":12,"unpackedSize":223046,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgcKWfCRA9TVsSAnZWagAA5sIP/ih4oDj+pY9c/M7pfl98\nR7Ctk8ckjIgAODd63MBD1F9q11TYin8L9Gr1/OqqmPlnua7zUooXjb0GMt92\n7FCXJ/HmcnD4DMX9OUT9w8WPlaeimvdkf9w9Mt8HiQEHSepBoIvddziO0fny\nx3C0jq2hSd2RN3ycCbFvQhcwCnelDf8Dp/taN2mOwiZ3SDVFYj9cx2VjcU7Y\n3+fQVJHtvCl2SxY2jw0H9colBs+2P8CcofSvH49t73ktfS1cSvTox7l3ozc0\nh9Zqk6j7CK17c1/dQUn0MyZWFtgWDzz/cy6brZueyTG9fbu9WGW4DZKKaJy0\nLVfaoWhCE0BBtIIAr1e9+Dfv1Ia6xvIIsWoIt1j9XL6OrLqcN0AAUTU9ls7x\nKsd9/aYq3rX4z3xXYd7z+C4HLojrWiame4DkZ3aVCP6pSm1tvuwB7T6tlY4L\nc1Zaxgl6eozsyqs6BRyg6HClnFq/qzVlKetP2CjacXbbySOQXNkvf1D1itvr\np60UYlw/MD+LozOFDQa1KxxHS+PNou7bzHELLaOQGxX0zaxAFHp7/wN4srV/\nb4YZIMNlXMA1/7tXpSnd3uCpNop4QT4QVtC8j548FGTqIl6yxDbCruHgwd5y\nwbnnWfFf9W5YGgRTxMgPKNNGxpdBiP11GSNBiiT0//RzyjXg9PzI8gw/ZHPo\nwsHl\r\n=b/eF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDubx84765VrAh/STTSa4nwnX97Js+E9+sChrCIehhA+wIhAP7zAAcbV8DDAQFv1xcPvq9REydcaLeblwjY1BC+TFzn"}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.6_1617995166413_0.38178916908953653"},"_hasShrinkwrap":false},"1.0.0-next.7":{"name":"react-interactive","version":"1.0.0-next.7","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive@next?color=purple)](https://bundlephobia.com/result?p=react-interactive)\n\n<!--\nbadge is only for @latest (v0) which doesn't have types, when v1 is published add this badge\n![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue) -->\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the class names for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\n...\n\nconst handleInteractiveStateChange = React.useCallback(({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state of (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = React.useCallback((e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\n// called from someplace else in your code\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the entire `<Interactive>` component interface, but sometimes it is necessary.\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface WrapperProps\n  extends InteractiveExtendableProps<'button'> /* OR InteractiveExtendableProps<typeof Component> */ {\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof MyComponent>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"1c9166d652951fff5a69ba9e4904619d8b4321a7","_id":"react-interactive@1.0.0-next.7","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-MFHqIua78Pn+jjqH7l1uz4fLfZ22iqkU5zUtNrFDbHzEn1lP/Aypfi1IFZZXFYBs4p5+GREafbsZjxippSqzXw==","shasum":"b059ccc294be300974d240f830087ef601c89fbd","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.7.tgz","fileCount":12,"unpackedSize":226962,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgeGQcCRA9TVsSAnZWagAADFUP/2X17sMLM6jUWzLDP6Mh\nnPcJoskgsfqZr/G72MAzy+TW8lSdOV78GdrVo3rLSd80DJcImRP6GckbGAPy\nH2AYTdWBovGVrGT1GOHGpAHGtfX86/dKBJALBftAkEygKVx80ixyInLVAcpB\nJfyiruiEDQvbZTH3ESXDK+iCtNzmDioxorGq+U+NQyii4iepThNrHk7i4DRm\nMfUs8ZUAGxm7MUv9W696219MzHkfo6GikyysNa0T0Mzo8KdkGxedzBrcDuwJ\nA45MlHfqMgcNNmnaEDfevNVVvoViT8diKStAANhdi4d/2Pc7Z3U29RN7xFdE\nLxHA10croOuoilllYZZOXoe/cVm5dEFRKLTVFSr1/WndsUQzqjK3kFljatDA\nuPauFIHMKQIjrxjxyylQGlnyYYmQfQmonsWl9axzrPofGqT4aaZ7jYHlxqot\n2kPOtF3vQqt0As+ZJcktGG1sVt2jcRpHPhDAe75ZrclfjBZTXs7eGj5v6c0z\nsiDDuP2zUiZyNP1KydSRl0XME+I9COBhRZv3tm/SeZHEe8hegXrfgx6ltB0D\nap0m+3jzDc76AOoWjr/4Jt/vuXVea5xSu8/yeEvAWsIt4bjZK2u4FgSHiSim\ndWKx1HRe5VvmyOU8V50Dp9RjGkAS0yp7nCYPrHxEhsPrF0S8Q+j3mDOnJMPX\nUOEv\r\n=+w6c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHJkF/veXJmyZQK2QxKvIBztsLvj0jnf9Jau0d4TblEPAiEAv2aG42Cxyyhm4taIp0aERzFleAk+tVteelqAfLVpCV0="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.7_1618502683635_0.06562479602521498"},"_hasShrinkwrap":false},"1.0.0-next.8":{"name":"react-interactive","version":"1.0.0-next.8","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.3"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive@next?color=purple)](https://bundlephobia.com/result?p=react-interactive)\n\n<!--\nbadge is only for @latest (v0) which doesn't have types, when v1 is published add this badge\n![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue) -->\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the class names for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\n...\n\nconst handleInteractiveStateChange = React.useCallback(({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"p\">\n  {({ hover, active, focus }) => (\n    Some text where only one word is{' '}\n    <span style={{ color: hover ? 'green' : undefined }}>highlighted</span>{' '}\n    when the paragraph is hovered.\n  )}\n</Interactive>\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state of (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\">\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen then pass in a `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = React.useCallback((e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\n// called from someplace else in your code\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```TS\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```TS\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nSometimes when creating components that wrap an `<Interactive>` component you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that usually it makes more sense to create a limited interface for components that wrap `<Interactive>` instead of extending the entire `<Interactive>` component interface, but sometimes it is necessary.\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props\n// when using forwardRef the ref type will be added by the forwardRef function\ninterface WrapperProps\n  extends InteractiveExtendableProps<'button'> /* OR InteractiveExtendableProps<typeof Component> */ {\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => <Interactive {...props} as=\"button\" />;\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof MyComponent>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => (\n  <Interactive {...props} as=\"button\" ref={ref} />\n));\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"ddac99f42c01f4eb143e44001e768c293bab832f","_id":"react-interactive@1.0.0-next.8","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-4iCEnFqj4dhELb1Xdr1WKddiM8ILngVuI+VS71CDZorTkG9gGLST+yKyOm1q5302I7COIzYsw9DlKxaNXuC3RA==","shasum":"f743ddd25f19ce74461c34b5db1210415822268a","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.8.tgz","fileCount":12,"unpackedSize":226801,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgeH5BCRA9TVsSAnZWagAAV/sP/0c0VMUl9jdU8QvlbrAd\ndpHURQ+TnChvnjVbVlqiMwzV3mVQ4ufO3NKSpDm4QxbdBTrC1NSc6z2J8Q6W\nWxK5I3pA2aIst2ueJaaaTdOHnFgdDUx/32HRZ9cd8nXPQ9O8XiuXjo5vE8MS\n/K4mEXbx9OjBHKUhykTFhSF9Rx7tLpTFuUePPe7eJQKqCFL1oMC+cRbKU+I0\nyUN18JZIGH3jqgY0KkF4pXriMgIPZUkeCLd9wwjQJZ6CYoiUVyjFKNnGhoG/\nKT4gKcq98wTWCFxIXxJ44vB5YX/Gc/CV4wr42E01vlKepyX4nQ9kHFdQB/j2\nrpRp3fiqf3yeLFSRFeneZg/4zX1WVgxdf04CXduTugs9iFGPqECSgEBMAq1J\n6OfLHp+bJ+V/7rtoscW1LQl9MNZE5HwJ7H1uUK8T3KC54UbD0hIKhljyhqKt\nT2zbio81rok27oaWo0x923Ids7Ag1Px4YIx8gBXKfICGjc5qMd6EwAn0ybp6\nztjasHJZo4DolkGQ4nhKhE+5KKlY6wLzgZ2Io4p9IIsu7ENkLWscNm3lHwUD\nBBrwjW/ZNxZC8ohWjkBxtKRtaYkE8k762cZ8fpNpv3cMXAcGgLaXAScqAywY\nMIQep8DYEVSGIaGygVN2EwePpEgnSeXiSK+49hyEAdDCa/Wnhuyxfwn/72RN\nPlkY\r\n=jhHo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE2rSkUqDqDvW5NRY9iwBncHZZqfz5Ql52iMr+xgp8xvAiBYCGM4GBMKRusfYR7KiRLF7BDK+iQlBdzohC8J5TczTg=="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.8_1618509376782_0.5493845422558457"},"_hasShrinkwrap":false},"1.0.0-next.9":{"name":"react-interactive","version":"1.0.0-next.9","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive@next?color=purple)](https://bundlephobia.com/result?p=react-interactive@next)\n\n<!--\nbadge is only for @latest (v0) which doesn't have types, when v1 is published add this badge\n![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue) -->\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`createInteractive`](#using-createinteractive) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript)\n\n---\n\n## Basics\n\n> v1 is in pre-release so use the `@next` tag to install it, v0 is available [here](https://github.com/rafgraph/react-interactive/tree/v0.9.5)\n\n```shell\nnpm install --save react-interactive@next\n```\n\n```js\nimport { Interactive } from 'react-interactive'\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n...\n\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as=\"a\" href=\"https://rafgraph.dev\">My Link</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky hover bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the class names for each state can be changed using props).\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n// add a className to target the element in CSS\n<Interactive as=\"button\" className=\"my-button\">My Button</Interactive>\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/).\n\n> React Interactive also includes a `createInteractive(as)` function and some common predefined DOM elements, for example `Interactive.Button`, for easy use with CSS-in-JS. For more see [Extending `<Interactive>`](#extending-the-interactive-component).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive.Button, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\n...\n\n<StyledButton>My Button</StyledButton>\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  hoverStyle={hoverAndActiveStyle}\n  activeStyle={hoverAndActiveStyle}\n  focusFromKeyStyle={focusFromKeyStyle}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\n...\n\nconst handleInteractiveStateChange = React.useCallback(({ state, prevState }) => {\n  // both state and prevState are of the shape:\n  // {\n  //   hover: boolean,\n  //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n  //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n  // }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\n...\n\n<Interactive as=\"div\" tabIndex={0}>\n  {({ hover, active, focus }) => (\n    `Current state - active: ${active}, hover: ${hover}, focus: ${focus}`\n  )}\n</Interactive>\n```\n\n---\n\n### Extending the `<Interactive>` component\n\nSometimes it is useful to extend the polymorphic `<Interactive>` component with a predefined `as` prop, but without additional logic. This is especially useful when using React Interactive with CSS-in-JS libraries and other polymorphic components.\n\nReact Interactive provides a `createInteractive(as)` function that returns a fully typed `<Interactive>` component with the `as` prop predefined. Also, some common DOM elements are available using `Interactive.Tagname` (for example `Interactive.Button`). For more see [Using `createInteractive`](#using-createinteractive).\n\n```js\n// using with CSS-in-JS\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { styled } from '@stitches/react';\nimport { Link } from 'react-router-dom';\n\nconst StyledButton = styled(Interactive.Button, {...});\nconst StyledRouterLink = styled(createInteractive(Link), {...});\n\n...\n\n// onStateChange is an <Interactive> prop\n<StyledButton onStateChange={...}>Interactive Button</StyledButton>\n<StyledRouterLink onStateChange={...}>Interactive Router Link</StyledRouterLink>\n\n```\n\n```js\n// using with another polymorphic component\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\nimport { SomePolymorphicComponent } from '...';\n\nconst InteractiveRouterLink = createInteractive(Link);\n\n...\n\n<SomePolymorphicComponent as={Interactive.Button} />\n<SomePolymorphicComponent as={InteractiveRouterLink} />\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\n<Interactive as=\"button\">My Button</Interactive>\n<Interactive as={Link} to=\"/some-page\">My React Router Link</Interactive>\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\n<Interactive as=\"div\" tabIndex={0}>\n  {({ hover, active, focus }) => {\n    //   hover: boolean,\n    //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n    //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n    ...\n    // must return something that React can render\n  }}\n</Interactive>\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen, pass in the `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `createInteractive`\n\nReact Interactive exports a `createInteractive(as)` function that returns a fully typed `<Interactive>` component with the `as` prop predefined.\n\nThis is the same as wrapping `<Interactive>` and passing through props like `<Interactive {...props} as={SomeAs} ref={ref} />`, but by the time you add ref forwarding and typing this can become verbose, and it may be something you need to do frequently in your app. So React Interactive provides a `createInteractive` convenience function that makes extending `<Interactive>` quick and easy.\n\nAlso, some commonly used DOM elements are available using `Interactive.Tagname` to make things even easier (they are created using `createInteractive('tagname')`).\n\nYou can use the predefined `as` components with JSX (instead of using the `as` prop), or you can use them with CSS-in-JS libraries and other polymorphic components to avoid `as` prop conflicts. For more see [Extending the `<Interactive>` component\n](#extending-the-interactive-component).\n\n```js\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n// these are the already defined DOM elements\n<Interactive.Button />\n<Interactive.A href=\"...\" />\n<Interactive.Input type=\"...\" />\n<Interactive.Select />\n<Interactive.Div />\n<Interactive.Span />\n\n// for other DOM elements and components use createInteractive(as)\nconst InteractiveNav = createInteractive('nav');\nconst InteractiveRouterLink = createInteractive(Link);\n\n<InteractiveNav />\n<InteractiveRouterLink to=\"...\" />\n```\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\n...\n\nconst handleClickEvent = React.useCallback((e) => {\n  switch (eventFrom(e)) {\n    case 'mouse':\n      // click event from mouse\n      break;\n    case 'touch':\n      // click event from touch\n      break;\n    case 'key':\n      // click event from key\n      break;\n  }\n}, []);\n\n...\n\n<Interactive\n  as=\"button\"\n  onClick={handleClickEvent}\n>\n  My Button\n</Interactive>\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\n...\n\nconst myButtonRef = React.useRef(null);\n\n// called from someplace else in your code\nconst focusButton = () => {\n  if (myButtonRef.current) {\n    // so the <Interactive> component will enter the focusFromKey state\n    setEventFrom('key');\n    myButtonRef.current.focus()\n  }\n};\n\n...\n\n<Interactive\n  as=\"button\"\n  ref={myButtonRef}\n  focusFromKeyStyle={{ outline: '2px solid green' }}\n>\n  My Button\n</Interactive>\n```\n\n---\n\n## Using with TypeScript\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts.\n\n```ts\n<Interactive\n  as=\"a\" // render as an anchor link\n  href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n>\n  My Link\n</Interactive>\n```\n\n---\n\n### Exported `types` from React Interactive\n\n```ts\ntype ActiveState = 'mouseActive' | 'touchActive' | 'keyActive' | false;\ntype FocusState = 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n\n// type for the state object used by React Interactive\n// InteractiveState is passed to children (when children is a function)\ninterface InteractiveState {\n    hover: boolean;\n    active: ActiveState;\n    focus: FocusState;\n}\n\n// type used for the argument passed to the onStateChange callback\ninterface InteractiveStateChange {\n    state: InteractiveState;\n    prevState: InteractiveState;\n}\n\n// type used for props passed to an <Interactive> component, see below for usage\ntype InteractiveProps<T extends React.ElementType = 'button'>\n\n// type used when wrapping/extending an <Interactive> component, see below for usage\ntype InteractiveExtendableProps<T extends React.ElementType = 'button'>\n```\n\n---\n\n### Typing `onStateChange` callback and `children` as a function\n\n```ts\nimport {\n  Interactive,\n  InteractiveState,\n  InteractiveStateChange,\n} from 'react-interactive';\n\n...\n\n// use the InteractiveStateChange type to type the argument\n// passed to the onStateChange callback\nconst handleInteractiveStateChange = React.useCallback(\n  ({ state, prevState }: InteractiveStateChange) => {\n    // ...\n  },\n  [],\n);\n\n// use the InteractiveState type to type the argument\n// passed to children (when children is a function)\nconst childrenAsAFunction = React.useCallback(\n  ({ hover, active, focus }: InteractiveState ) => (\n    // ...\n  ),\n  []\n);\n\n...\n\n<Interactive\n  as=\"button\"\n  onStateChange={handleInteractiveStateChange}\n>\n  {childrenAsAFunction}\n</Interactive>\n\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`.\n\n```ts\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  ...\n};\n\n...\n\n<Interactive {...propsForInteractiveButton} />\n<Interactive {...propsForInteractiveAsComponent} />\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nWhen creating components that wrap an `<Interactive>` component, sometimes you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`.\n\n> Note that if all you need to do is extend `<Interactive>` with a predefined `as` prop but without additional props and logic, [use `createInteractive(as)`](#using-createinteractive) instead.\n>\n> ```ts\n> import {\n>   Interactive,\n>   InteractiveExtendableProps,\n>   createInteractive,\n> } from 'react-interactive';\n> import { Link } from 'react-router-dom';\n>\n> // this works fine, but it's not necessary\n> const InteractiveLink: React.VFC<InteractiveExtendableProps<typeof Link>> = (\n>   props,\n> ) => <Interactive {...props} as={Link} />;\n>\n> // do this instead\n> const InteractiveLink = createInteractive(Link);\n> ```\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props,\n// when using forwardRef the ref prop type will be added by the forwardRef function\ninterface WrapperProps extends InteractiveExtendableProps<'button'> {\n  // OR extends InteractiveExtendableProps<typeof Component>\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => {\n  // your logic here\n  return <Interactive {...props} as=\"button\" />;\n};\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof Component>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => {\n  // your logic here\n  return <Interactive {...props} as=\"button\" ref={ref} />;\n});\n```\n\n---\n\n## CSS sticky hover bug\n\nThe CSS sticky hover bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n","readmeFilename":"README.md","gitHead":"35de76eba6fcf8c0b59a1f96a22437ea0e6796f7","_id":"react-interactive@1.0.0-next.9","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-8eHoarDEDUdAnyOfhW8ahiWnBaeyD8D8jurfoxcHWWV/vK+oL0PQT779HT8kfbTe62VKPRlUsSrcbhW47dx/Ug==","shasum":"73d983a31d63c234cfe668e37adbae1969b77c58","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.9.tgz","fileCount":12,"unpackedSize":244119,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgfldnCRA9TVsSAnZWagAAPlIP/joKl8AW+AjqEydVtTUi\nBI15UcYQ7M/zPgAyKLgYmtoLjY2CJwHMgn0uM5OQLY9EpfGJ+WyD8XTK9Dfm\nAJPO7ZHru2CPZ0wWfiXc3gr0abFrqp/R6fFSR3AXb1ZCrROz+69rAC5I/q8g\nt440rYstzWYv4qfBDyRKh0KYqKIDbcLKswLd73OLcMC/naxdgeOdw1Gl5y3b\ngGlRCJmUxR5WoZzlOm1cNXcj9aFVoM95u/4qxXXUbZJQcsZgZWhKaUW3R1i7\nsJMhsEHD1S7drwgMDEG2A1Lw/61vBztCxcjed75zWNo/XKsduMzrokoBZj0g\nGu/YrtsheeFe7U+INOEBgh9lWrC4jutus41qFGSYRj2+F90dyUY4vqyEtWO4\nmfNVVynFB00ynt+E2bLGwtxGLFVjaMHcOas3IsJhigviOL2s8X4gkZBXynSF\n0YgoMVW9Lv6kmLih3xVdCnbwYhLTRmZR1+P6vgG2VQsXVf2G8Xr4PhOMSH5Q\nKlThtlh/CHlKHuqTNK4dCBc6OWdAzjISmJ38Cx3O2GODRRmMHO0R4/Kdwayf\nn3fRS+zKZZCWNTT4lx2sGhzRCLFabC4X564n6XE3vWPnwq3eBnzXWnvSgpVJ\n+E0vyNTobhesaJgjiaR9kw3qifg3FiM5dJDQaX6/s7mUybZ7l66ixOIaopuF\n+CC7\r\n=TDZ1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICvVZUgXFb8r3mzmpsIh9ro0SpSF8xeyJ0pvY/XQ+K95AiEAlLnhSRd8kD+y7sZe4P8lQN0UPtZIj+WWyVbmy5Klils="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.9_1618892646654_0.2902890434368015"},"_hasShrinkwrap":false},"1.0.0-next.10":{"name":"react-interactive","version":"1.0.0-next.10","description":"Better interactive states than CSS pseudo classes and a callback for interactive state changes","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^0.7.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.3","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"gitHead":"73b5f7925cfd1afdc5587d60c9cbfe6bd3221f8d","_id":"react-interactive@1.0.0-next.10","_nodeVersion":"14.16.0","_npmVersion":"7.8.0","dist":{"integrity":"sha512-wQnRmcVH4rTahCTsF2uqxgqLIqHBUWtumoBjrzqZwMbnuK9Vj0Tfmn2mfdpLsQTiHmoqbjOYgIQ+JxTbP5Biyw==","shasum":"b17f297e6756930e377f4e5a69eca2764c5df316","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0-next.10.tgz","fileCount":12,"unpackedSize":252418,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJggHLOCRA9TVsSAnZWagAAUWMP+QA+5g2V3RkAQpIoZY+F\ndK1kIVZiVqHJzVA0CvBrLGJezgEthbac2CMQqbLPm3rTkOwhL2zNhK2VOhrp\noyDSiYDupp0nwmcL2RjqhFqG79FbbNPdsbsunJcgZUQ9cjfjOkKGBZQh9BkD\nNM9+BUOCXMb4tSz+Uyq7ePWROdljw8rvc2QjUdNHhIzzgbyrbTqy8LnOBI9r\nn/yGrsbdh6t/o7D4yyJt+zXpRMzBAdMGNU+h3HbFCBzPt56Km3Myd+JxYBdD\n5HWu6dISqNkmtUrSd7ZU2L7NwTsEbZanRqeb2SO+eEsd2YXEiYw8liIKg2li\nmcajv6sjghi2sG4gmRitMMJ1NCS+MkbOojdGipMCdqovq/DciChtdt2aA3Y3\n/memTv2xRsdQxS4DDuUc8F00lnFKZMUpzoBZ+UOS4Eibz/JSFl54INVVkv2U\nmiGhgWW950BgllzdsJRqCFl+unKYFt4XcuFtkScfrUSi+VHUSxj7ZQwgghtq\nl0ima2kyrKYWGekvtTzSVtqezG2T2mmA8X56UK9MPjrIHwa5ovp2+nRmQbbb\nmuGt7Z2NG8up60sWC9atyjJ79mj9UL5G2zxvWYxcRBXC6AVFifWIVclRNo+m\ngSBo1lVykJWfgO8+3i0PmNzTwHyc/CClrbJ93weayaPKbLiP3tU7Mh5la1+u\nrRmO\r\n=8fvy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHLRELTnMuRdj/02R9e/NruYX24b+UZayZEIZeoKv8+QAiEA5z9SR//3XpfAxfUdlR39LvZ7k+qEGILCVj0TaYlNxRI="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0-next.10_1619030734209_0.9977091858476914"},"_hasShrinkwrap":false},"1.0.0":{"name":"react-interactive","version":"1.0.0","description":"Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^1.0.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.4","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"gitHead":"30ede1d270699782d067d69d78b830b7699198ea","_id":"react-interactive@1.0.0","_nodeVersion":"14.16.1","_npmVersion":"7.11.2","dist":{"integrity":"sha512-0Ifw8V5AXKmJgD/R6fposB/ghGqrKZQFAMmooISveH402Vc/6htGs6GhnoEsmZc9R4ee4TuoF48/3cpQCoavaQ==","shasum":"e5ee66ea994d970e06c3e2394976300d197f274b","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.0.0.tgz","fileCount":12,"unpackedSize":261107,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgjYbwCRA9TVsSAnZWagAA1JYP/jOA9qgYP2EnTimM0Ock\nPSURm/LEgB53yyCTTUq84Gj4buE/qMyo/z9pqf5rDarNbZSUULRLsminXTE4\nE93z0mzShamvOER41HWDor5f2QxKBY6/5EFl+PXzy+Jm4utBGBei7XUspv1F\niJW7vvMSZHAd5bapTT2fjn8V1iDjlBmbF3wn3YTTH5W2yew6iXQrTnEO8QSD\njh6pFZhvWI17oj4x5YjwdyxdmIf574cKaheYbnqbzySp7u6Eo5GuARjSMq1q\nGeVHt5JVQSRQPgGZ3QyLhkwA7HBqAnSir/SjvtVikPaGpn8PqyUogL79cHjU\nKM98RHjBRtrkWsgHvX01Yu4kj4LWWiF8RoZwBAjSKF1cUPhwscCEFBYBpO7u\n5vqPFAeKAObWaRTX8E/hdUzkACV3+IpTvpwyp1luz3gPcZUhhguzN0IzMOtD\nz4EhzwZnnoh29VegL1qNp/aOxz3El4jYNMsTvwA2Ca7h9EQw0gxg3LQPUrXl\nkZGm4ltK5zVnC0S2K36Nl+TIes+TT63dCr91Pq2KTE9ZKH2LLzWnU9+CstfJ\nQUDmCr2fXd+pS/Vh5rTRUjPEF4ZhS2x0bmkBZYvwjU889PErMYPNBe3if3TV\nPorEviZGl7sMgY8wBWdynoQWE5TIolv6LUX/13T2kWHE2ITmJeTnPwfUIZDd\nG9k5\r\n=+4xF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD6tZUAxIRNJCGBLQELhoOpNvO9oG5G5Ik77tvCskY5UAIgXTnar+Rogcpn6eQYjI8rH1KiPjm25t/VwGpg8tbmfyg="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.0.0_1619887856124_0.5694560858194126"},"_hasShrinkwrap":false},"1.1.0":{"name":"react-interactive","version":"1.1.0","description":"Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^1.0.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.4","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"gitHead":"180e90f6f770a6fe807d63fc721d0e70a7b7a4ce","_id":"react-interactive@1.1.0","_nodeVersion":"14.16.1","_npmVersion":"7.11.2","dist":{"integrity":"sha512-PtJ27WjvvZxW13FLkT1sufayLwuxVYxzNXXyk7P2VEnaXxzBxmVmO3higNZE4XzarNwgRMAPpkn/2vH5/2j3yw==","shasum":"bb820dad2953b1b6079bde6dabaabd410adc6cf6","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.1.0.tgz","fileCount":12,"unpackedSize":254311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgjwhaCRA9TVsSAnZWagAABngP/0vjPvonzFQPibZYhSbe\nUvRZlTDUj8DYQi7E/WbVqbo7u7giAPQyKQ6gnQvlSkwzqpOQlgfsNHAEh5Ci\ndeg+mbxu6STDipPgMFuEZ50uERmccfr0+R1+lQlvHjNQnPVcZoWEFQQp3+fo\ntCTIcmXuF3zm3v9KyKEWXmt1BVMCYghkk5GyoaU81yFVY1zSfZZfiX9RbXhr\neW+142YV5TY+FUIrBbaAvfHyy/tPqoExSekiB//Jtab3hw5hkSn513PFBz3f\n6KAj6lsiboIh+8Z5ULh9p/A76MDZfFcI0Vm20SElkVov6oCfvVdmi6/poJq9\nqDl4SAEKZ7mYbaj7fTlsLAdT6k0GkNOncfKunO8NQpMwxghfvskMIrJsqshB\n4GraWOlqDcf1r9ddjVtr91bxUvhDzBZRBsfKrhtaUjWZo1euJVO/Ogq4DzfG\nSRe3y5pf6gmmzVzQokh+SudC0sz94J6Z2HhDWEDKyegMRE/CrM0xM6AGWBcG\nSj34mdnqjMMznIuUO7PUxxG4oXxh0/4sVaZLwqogNHeqm6aWh5oIfKG1Y+3b\nFxFUHPOeL14CBuENvSpRL1YVyVmkg5vZLxxNgQMqwOSuXRD81T2Pqk2D0lCp\nveAoGDfg+7gwFwso2Ks0YArQDfDOUahNVHaXj5Ash+gVXps6mHJ9X9irfZbs\nS5ci\r\n=zE+n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDVDuzldQjagrz3bOaXoc4d6T6WPGchMRT7Z9oqsKp1VAIgUgdtLxZOdWhnqUHM/az9u9DCkZUy/zH2m6sbwONEWZ4="}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.1.0_1619986522278_0.45760159334522177"},"_hasShrinkwrap":false},"1.1.1":{"name":"react-interactive","version":"1.1.1","description":"Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^1.0.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.4","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.5","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"],"rules":{"@typescript-eslint/no-unsafe-call":"warn","@typescript-eslint/no-unsafe-return":"warn","@typescript-eslint/no-unsafe-member-access":"warn","@typescript-eslint/no-unsafe-assignment":"warn"}},"jest":{"preset":"rollpkg"},"gitHead":"6e1360e07462ee6a97066f934d58616986bcda79","_id":"react-interactive@1.1.1","_nodeVersion":"14.16.1","_npmVersion":"7.11.2","dist":{"integrity":"sha512-P4snu3nW+hxtY5FLMw26hxq9NA4RoxDfYEetq/msm+BrnSKWsS+vSlWuubG0ZqffzW5NdFuGqHf0Lu1UzmbriQ==","shasum":"96d87d3c2b841736d21b6ca0324acbb665511dc8","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.1.1.tgz","fileCount":12,"unpackedSize":257000,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgkwCcCRA9TVsSAnZWagAA2JgP+wbdW1nCd1urf8Pi06IZ\nWjUjFf4qVqdBfPH7vG2zMZMxGX2zaRJmKmacPDZk/Wjp/hIveknTVAB34vHU\ntKWfq2WDxx18B/BI7h33FmArhfHJZGjrjF/sZcnBE+mABkpyqI6yOrFXhLr6\nArmu3FnbCLQYNlJ6hixzNSRa0hoTeA+zN7KMfH16I5gztgJuFG/2W6hR77pl\nUmbVwnDk8Zg5n6kUoClanjvEYt/o37gh3E0r2i9TWePs7NOVFQjUNVgJkphV\nqhMf4bmOrqTdJIp3uxL/09NCGAW4puaqu73CxoXo7q95zaZAwYHkNAWKYLQJ\n+WWznToRzb2JrRki2MzTBjaikEVQL/pooKVFAqwAQ18QSuCBaWe9ArpCDj2r\nKDvL1JuBesaDpJh8fieOm058i3DZapHk1PU/u6Rbry3F/DcD2kW1ZA5y8uLK\nqOI8vbeHbsIXn3Re1XdJpe9Yn/y285vpziTcTywpmhqGKOqLDkDWF0+scArb\nx+EGa9aKUzXPyAJrdt6JgywkoQHgvNb9bOazksFaMImWFG2UQKFDuM9i6guv\nXKJEoON9yuU75Q7vORQ37AHithrmFYUoQ400BXMZeLypRHePRUFJ0SDoWET1\nqsdQl2rfa/LC2aC/wLbQI1yJ9xw0mKhG1claumPDF9PRxnaX+U+p06D1V98Q\nfl/W\r\n=/8KI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCIJL51Yn3+oD13nK8nWKoZm8BRfPQ5Z4JOH1eS49HQzwIhAOos02DCPlueTkBll+3VHc3MJomntvEHkA1fKWxpElBi"}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.1.1_1620246684088_0.8289037751745254"},"_hasShrinkwrap":false},"1.1.2":{"name":"react-interactive","version":"1.1.2","description":"Better hover, active and focus states than CSS pseudo-classes, and a callback when the interactive state changes.","main":"dist/react-interactive.cjs.js","module":"dist/react-interactive.esm.js","types":"dist/index.d.ts","sideEffects":false,"scripts":{"build":"rollpkg build","watch":"rollpkg watch","prepublishOnly":"npm run lint && npm test && npm run build","lint":"eslint src","test":"jest","test:watch":"jest --watchAll","coverage":"npx live-server coverage/lcov-report","lintStaged":"lint-staged"},"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"license":"MIT","bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"homepage":"https://react-interactive.rafgraph.dev","dependencies":{"event-from":"^1.0.0","react-polymorphic-types":"^1.1.0"},"devDependencies":{"@types/react":"^17.0.4","lint-staged":"^10.5.4","pre-commit":"^1.2.2","react":"file:demo/node_modules/react","rollpkg":"^0.5.7","typescript":"^4.2.4"},"peerDependencies":{"react":">=16.8"},"pre-commit":"lintStaged","lint-staged":{"(src/**/*|demo/src/**/*)":["prettier --write --ignore-unknown"]},"prettier":"rollpkg/configs/prettier.json","eslintConfig":{"extends":["./node_modules/rollpkg/configs/eslint"]},"jest":{"preset":"rollpkg"},"gitHead":"3d31aeb59d333258cb8835098d5f569f7e2be1fa","_id":"react-interactive@1.1.2","_nodeVersion":"14.17.0","_npmVersion":"7.12.1","dist":{"integrity":"sha512-bMwbB5naxs3dFkbiA5eIocevLkeGWnN7L+0NtsaVAZtiGXDmXMiCC0H/eW00Q77kgxx0nL6f66NofaWlqgardA==","shasum":"0be7265a59d4a2de440f1a1c4ef02aef6caa69f1","tarball":"https://registry.npmjs.org/react-interactive/-/react-interactive-1.1.2.tgz","fileCount":12,"unpackedSize":262540,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrQ1ZCRA9TVsSAnZWagAAAMsP/jhBrSOfkDtBebX6tLXK\n0JrKRv/7lLnZW7nDaDTW3LpYBOv19HjZ0VfBmFUoZlk5IRfJz+0/Jv2g1N+S\nB9eAuOKIhu6FskbwP7Ch/wj/foTXMNmWG0i573SBDNirY9FPBX1eN5zT9PgE\nL5YWNIcgn+pXB5WYlDczommy2mDodCEG5Zq1Y/2GkscZtSY3+dJz04fMWFJO\nYgQPgAUK9Y+BMyL5r8O8LMzCz8EGTabcyYgjM6QbCU1UEeC1U/Tbw8nIeKzZ\na8v4VwNeC9MmzOhyeTCpvSisUljcPrXQyHYOLXPr9dsAZVrV3rVeuJJPVULX\nxqCVZvNIL+mW9hWoUZsZwzie/gASdxIo1K7Rj6fXnrNk+5Jms2mVCDHqH4Lj\nxvlvsCB1Db4bC8ZglWTkHs61om41eVuiNDai/WC9vLFf7qd1mhe++6B+UWXB\nPne79bDdRlJ1397NQ/aUnbsUsL4f++vJlYBhhU3bJu1gznvCZ9gTD8d0mfBo\nVOsnqgHVn6karUnmNLhuMBTlzaTYZGOmARLtbkolC0dPFAGFw+/SF3Hjmvmc\n+oo9K3XRpuOWOUYSbkmmKJ1dXiuZn3TCU1Cp3Hbf54QKQhhny7prgN3dkrUO\nea1jocSG/OOkUFbRkyfBjjzf+ziIdX9M5xDb+qLPWFUwGMoaGP1sxk8fPv+v\nYTZY\r\n=kskq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDaMgQGeZF3fRUSILoYBUKUigLxjNnKx/biJuniHh44ZAIhALh9Us3x41J34EHs2APxC4HPOhNslK6MU2dnAzksWk5O"}]},"_npmUser":{"name":"rafgraph","email":"rafael@rafgraph.dev"},"directories":{},"maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-interactive_1.1.2_1621953880541_0.7667575207480293"},"_hasShrinkwrap":false}},"readme":"# React Interactive\n\n[![npm](https://img.shields.io/npm/dm/react-interactive?label=npm)](https://www.npmjs.com/package/react-interactive) [![npm bundle size (version)](https://img.shields.io/bundlephobia/minzip/react-interactive?color=purple)](https://bundlephobia.com/result?p=react-interactive) ![npm type definitions](https://img.shields.io/npm/types/react-interactive?color=blue)\n\n- Better interactive states than CSS pseudo classes\n  - `hover`, `active`, `mouseActive`, `touchActive`, `keyActive`\n  - `focus`, `focusFromMouse`, `focusFromTouch`, `focusFromKey`\n- Callback for interactive state changes\n  - Know when the hover/active/focus state is entered/exited (impossible to do with CSS)\n- Style interactive states with CSS, inline styles, and CSS-in-JS libraries\n- Eliminates the [CSS sticky `:hover` bug](#css-sticky-hover-bug) on touch devices\n- Allows you to only add focus styles when focus is from the keyboard\n\n---\n\n### [Live demo app for React Interactive](https://react-interactive.rafgraph.dev)\n\nCode is in the [`/demo`](/demo) folder, or open the [demo in CodeSandbox](https://githubbox.com/rafgraph/react-interactive/tree/main/demo)\n\n---\n\n[Basics](#basics) ⚡️ [Props](#props) ⚡️ [`createInteractive`](#using-createinteractive) ⚡️ [`eventFrom`](#using-eventfrom) ⚡️ [TypeScript](#using-with-typescript) ⚡️ [FAQ](#faq)\n\n---\n\n## Basics\n\n[Install](#install), [`as` prop](#polymorphic-as-prop), [Interactive state](#interactive-state), [CSS](#styling-with-css), [CSS-in-JS](#styling-with-css-in-js), [Inline styles](#styling-with-inline-styles), [Interactive state changes](#reacting-to-interactive-state-changes), [Interactive state in `children`](#using-the-interactive-state-in-children), [Extending `<Interactive>`](#extending-the-interactive-component)\n\n---\n\n### Install\n\n```shell\nnpm install --save react-interactive\n```\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst App = () => <Interactive as=\"button\">My Button</Interactive>;\n```\n\n---\n\n### Polymorphic `as` prop\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button\"`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\nconst App = () => (\n  <>\n    <Interactive as=\"button\">My Button</Interactive>\n    <Interactive as=\"a\" href=\"https://rafgraph.dev\">\n      My Link\n    </Interactive>\n    <Interactive as={Link} to=\"/some-page\">\n      My React Router Link\n    </Interactive>\n  </>\n);\n```\n\n---\n\n### Interactive state\n\nThe state object used by React Interactive to determine how the `<Interactive>` component is rendered. The interactive state object is also passed to the [`onStateChange`](#reacting-to-interactive-state-changes) callback and [`children`](#using-the-interactive-state-in-children) (when `children` is a function).\n\n```ts\ninterface InteractiveState {\n  hover: boolean;\n  active: 'mouseActive' | 'touchActive' | 'keyActive' | false;\n  focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n}\n```\n\n- `hover` Mouse on the element (unlike CSS pseudo classes the `hover` state is only entered from mouse input which eliminates the [CSS sticky `:hover` bug](#css-sticky-hover-bug) on touch devices).\n- `active`\n  - `mouseActive` Mouse on the element and mouse button down.\n  - `touchActive` Touch point on the element.\n  - `keyActive` Element has focus and the enter key is down (or space bar for some elements).\n- `focus`\n  - `focusFromMouse` Element has focus and focus was entered from mouse input.\n  - `focusFromTouch` Element has focus and focus was entered from touch input.\n  - `focusFromKey` Element has focus and focus was entered from keyboard input (e.g. tab key).\n\n---\n\n### Styling with CSS\n\nCSS classes for the current state are automatically added for easy styling with CSS or CSS-in-JS libraries like Styled Components, Emotion, and Stitches.\n\n- Hover state adds a `hover` class.\n- Active state adds both an `active` class and an `[input]Active` class, e.g. `mouseActive`.\n- Focus state adds both a `focus` class and a `focusFrom[input]` class, e.g. `focusFromKey`.\n- For a full class list see [interactive `className` props](#interactive-state-className-props-string) (the class names for each state can be changed using props).\n- See [this CodeSandbox](https://codesandbox.io/s/react-interactive-css-style-example-ttl0t) for a live example using CSS.\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst App = () => (\n  // add a className to target the element in CSS\n  <Interactive as=\"button\" className=\"my-button\">\n    My Button\n  </Interactive>\n);\n```\n\n```css\n/* use compound selectors in CSS to style the interactive states */\n.my-button.hover, .my-button.active: {\n  color: green;\n}\n\n.my-button.focusfromkey: {\n  outline: 2px solid green;\n}\n```\n\n---\n\n### Styling with CSS-in-JS\n\nUse the added CSS classes to style the interactive states with CSS-in-JS libraries like Styled Components, Emotion, and [Stitches](https://stitches.dev/). Live examples in CodeSandbox are available for [Styled Components](https://codesandbox.io/s/react-interactive-styled-components-example-7dozj) and [Stitches](https://codesandbox.io/s/react-interactive-stitches-example-os981) (also the demo app is built using Stitches).\n\n> React Interactive includes a `createInteractive(as)` function with some predefined DOM elements, for example `Interactive.Button`, for easy use with CSS-in-JS. For more see [Extending `<Interactive>`](#extending-the-interactive-component).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { styled } from '@stitches/react';\n\nconst StyledButton = styled(Interactive.Button, {\n  '&.hover, &.active': {\n    color: 'green',\n  },\n  '&.focusFromKey': {\n    outline: '2px solid green',\n  },\n});\n\nconst App = () => <StyledButton>My Button</StyledButton>;\n```\n\n---\n\n### Styling with inline styles\n\nReact Interactive uses a separate style prop for each state for easy inline styling.\n\n- Hover state uses the `hoverStyle` prop.\n- Active state uses both an `activeStyle` prop and an `[input]ActiveStyle` prop.\n- Focus state uses both a `focusStyle` prop and a `focusFrom[input]Style` prop.\n- For a full list see [interactive `style` props](#interactive-state-inline-style-props-style-object).\n- See [this CodeSandbox](https://codesandbox.io/s/react-interactive-inline-style-example-6s8mn) for a live example using inline styles.\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst hoverAndActiveStyle = {\n  color: 'green',\n};\n\nconst focusFromKeyStyle = {\n  outline: '2px solid green',\n};\n\nconst App = () => (\n  <Interactive\n    as=\"button\"\n    hoverStyle={hoverAndActiveStyle}\n    activeStyle={hoverAndActiveStyle}\n    focusFromKeyStyle={focusFromKeyStyle}\n  >\n    My Button\n  </Interactive>\n);\n```\n\n---\n\n### Reacting to interactive state changes\n\nReact Interactive accepts an `onStateChange` prop callback that is called each time the state changes with both the current and previous states.\n\n```js\nimport * as React from 'react';\nimport { Interactive } from 'react-interactive';\n\nconst App = () => {\n  const handleInteractiveStateChange = React.useCallback(\n    ({ state, prevState }) => {\n      // both state and prevState are of the shape:\n      // {\n      //   hover: boolean,\n      //   active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n      //   focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n      // }\n    },\n    [],\n  );\n\n  return (\n    <Interactive as=\"button\" onStateChange={handleInteractiveStateChange}>\n      My Button\n    </Interactive>\n  );\n};\n```\n\n---\n\n### Using the interactive state in `children`\n\nReact Interactive uses the children as a function pattern to pass the current interactive state to its children.\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst App = () => (\n  <Interactive as=\"div\" tabIndex={0}>\n    {({ hover, active, focus }) =>\n      `Current state - active: ${active}, hover: ${hover}, focus: ${focus}`\n    }\n  </Interactive>\n);\n```\n\n---\n\n### Extending the `<Interactive>` component\n\nSometimes it is useful to extend the polymorphic `<Interactive>` component with a predefined `as` prop, but without additional logic. This is especially useful when using React Interactive with CSS-in-JS libraries and other polymorphic components.\n\nReact Interactive provides a `createInteractive(as)` function that returns a fully typed `<Interactive>` component with the `as` prop predefined. Also, some common DOM elements are available using `Interactive.Tagname` (for example `Interactive.Button`). For more see [Using `createInteractive`](#using-createinteractive).\n\n```js\n// using with CSS-in-JS\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { styled } from '@stitches/react';\nimport { Link } from 'react-router-dom';\n\nconst StyledButton = styled(Interactive.Button, {});\nconst StyledRouterLink = styled(createInteractive(Link), {});\n\nconst App = () => (\n  <>\n    <StyledButton>Interactive Button</StyledButton>\n    <StyledRouterLink>Interactive Router Link</StyledRouterLink>\n  </>\n);\n```\n\n```js\n// using with another polymorphic component\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\nimport { SomePolymorphicComponent } from '...';\n\nconst InteractiveRouterLink = createInteractive(Link);\n\nconst App = () => (\n  <>\n    <SomePolymorphicComponent as={Interactive.Button} />\n    <SomePolymorphicComponent as={InteractiveRouterLink} />\n  </>\n);\n```\n\n---\n\n## Props\n\n[`as`](#as-string--reactcomponent), [`onStateChange`](#onstatechange-function), [`children`](#children-reactnode--function), [`disabled`](#disabled-boolean), [interactive `className`](#interactive-state-className-props-string), [interactive `style`](#interactive-state-inline-style-props-style-object), [`useExtendedTouchActive`](#useextendedtouchactive-boolean), [`ref`](#ref-object-ref--callback-ref)\n\n---\n\n### `as`: `string` | `ReactComponent`\n\nDefault value: `\"button\"`\n\nReact Interactive accepts a polymorphic `as` prop that can be a string representing a DOM element (e.g. `\"button`, `\"a\"`, `\"div\"`, etc), or a React component (e.g. React Router's `Link`, etc).\n\n```js\nimport { Interactive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\nconst App = () => (\n  <>\n    <Interactive as=\"button\">My Button</Interactive>\n    <Interactive as={Link} to=\"/some-page\">\n      My React Router Link\n    </Interactive>\n  </>\n);\n```\n\n> Note that if `as` is a React component, then the component needs to pass through props to the element that it renders, including the `ref` prop using `React.forwardRef()`. Most libraries designed for composability do this by default, including React Router's `<Link>` component.\n\n---\n\n### `onStateChange`: `function`\n\nDefault value: `undefined`\n\nCallback function that is called each time the interactive state changes with both the current and previous interactive states (passed in as a single argument of the form `{ state, prevState }`). See [Reacting to interactive state changes](#reacting-to-interactive-state-changes).\n\n---\n\n### `children`: `ReactNode` | `function`\n\nDefault value: `undefined`\n\nIf `children` is a `ReactNode` (anything that React can render, e.g. an Element, Fragment, string, boolean, null, etc) then it is passed through to React to render normally.\n\nIf `children` is a function then it is called with an object containing the current interactive state (note that the function must return a `ReactNode` that React can render). See [Using the interactive state in `children`](#using-the-interactive-state-in-children).\n\n```js\nimport { Interactive } from 'react-interactive';\n\nconst App = () => (\n  <Interactive as=\"div\" tabIndex={0}>\n    {({ hover, active, focus }) => {\n      // hover: boolean,\n      // active: 'mouseActive' | 'touchActive' | 'keyActive' | false,\n      // focus: 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false,\n      // ...\n      // must return something that React can render\n      return `Current state - active: ${active}, hover: ${hover}, focus: ${focus}`;\n    }}\n  </Interactive>\n);\n```\n\n---\n\n### `disabled`: `boolean`\n\nDefault value: `false`\n\nPassing in a `disabled` prop is an easy way to temporarily disable a React Interactive component without changing the other props. When `disabled` is `true`:\n\n- The `disabledClassName` and `disabledStyle` props will be used for styling the disabled component.\n- `disabled` will be passed through to the DOM element if it is a `<button>`, `<input>`, `<select>`, or `<textarea>` (elements that support the `disabled` attribute).\n- The `href` prop will not be passed through to `<a>` and `<area>` DOM elements (this disables links).\n- `onClick`, `onClickCapture`, `onDoubleClick`, and `onDoubleClickCapture` props will not be passed through.\n- `tabIndex` prop will not be passed through.\n\n---\n\n### Interactive state `className` props: `string`\n\nDefault values: see below table\n\nCSS classes that are added to the DOM element when in an interactive state. These are merged with the standard `className` prop which is always applied. See [Styling with CSS](#styling-with-css).\n\n| Prop                      | Default value      |\n| :------------------------ | :----------------- |\n| `hoverClassName`          | `\"hover\"`          |\n| `activeClassName`         | `\"active\"`         |\n| `mouseActiveClassName`    | `\"mouseActive\"`    |\n| `touchActiveClassName`    | `\"touchActive\"`    |\n| `keyActiveClassName`      | `\"keyActive\"`      |\n| `focusClassName`          | `\"focus\"`          |\n| `focusFromMouseClassName` | `\"focusFromMouse\"` |\n| `focusFromTouchClassName` | `\"focusFromTouch\"` |\n| `focusFromKeyClassName`   | `\"focusFromKey\"`   |\n| `disabledClassName`       | `\"disabled\"`       |\n\nNote that:\n\n- `activeClassName` is added when in any active state. This is in addition to the specific `[input]ActiveClassName`.\n- `focusClassName` is added when in any focus state. This is in addition to the specific `focusFrom[input]ClassName`.\n- `disabledClassName` is added when the [`disabled` boolean prop](#disabled-boolean) is true, in which case none of the other interactive `className` props are applied.\n\n---\n\n### Interactive state inline `style` props: `style object`\n\nDefault values: `undefined`\n\nInline styles that are added to the DOM element when in an interactive state. These are merged with the standard `style` prop which is always applied. See [Styling with inline styles](#styling-with-inline-styles).\n\nInline style prop list:\n\n- `hoverStyle`\n- `activeStyle`\n- `mouseActiveStyle`\n- `touchActiveStyle`\n- `keyActiveStyle`\n- `focusStyle`\n- `focusFromMouseStyle`\n- `focusFromTouchStyle`\n- `focusFromKeyStyle`\n- `disabledStyle`\n\nStyle prop objects for each state are merged with the following precedence (last one wins):\n\n- `style` prop (styles that are always applied)\n- ===\n- `hoverStyle`\n- `activeStyle`\n- `[input]ActiveStyle`\n- `focusStyle`\n- `focusFrom[input]Style`\n- =OR=\n- `disabledStyle` (when disabled, only the `disabledStyle` prop is merged with the `style` prop)\n\n---\n\n### `useExtendedTouchActive`: `boolean`\n\nDefault value: `false`\n\nBy default React Interactive only stays in the `touchActive` state while a `click` event (from the touch interaction) is still possible. To remain in the `touchActive` state for as long as the touch point is on the screen, pass in the `useExtendedTouchActive` prop. This can be useful for implementing functionality such as show on `touchActive`, long press, etc.\n\nNote that anchor tags, `<a>`, on touch devices have their own device/browser specific behavior for long press (context/callout menu, dragging, etc). If you need to disable the native behavior for long press of links you can:\n\n- Set a `onContextMenu` event listener and call `preventDefault()`, to prevent the context menu from appearing.\n- Set `-webkit-touch-callout: none` style to prevent the iOS \"context menu\" from appearing (iOS doesn't support `contextmenu` events).\n- Set `draggable=\"false\"` on the `<a>` element (by passing it in as a prop).\n\n---\n\n### `ref`: object `ref` | callback `ref`\n\nDefault value: `undefined`\n\nReact Interactive uses `React.forwardRef()` to forward the `ref` prop to the DOM element. Passing a `ref` prop to an Interactive component will return the DOM element that the Interactive component is rendered as.\n\nReact Interactive supports both object refs created with `React.useRef()` and callback refs created with `React.useCallback()`.\n\n---\n\n## Using `createInteractive`\n\nReact Interactive exports a `createInteractive(as)` function that returns a fully typed `<Interactive>` component with the `as` prop predefined.\n\nThis is the same as wrapping `<Interactive>` and passing through props like `const MyWrappedInteractive = (props) => <Interactive {...props} as={SomeAs} ref={ref} />`, but by the time you add ref forwarding and typing this can become verbose, and it may be something you need to do frequently in your app. So React Interactive provides a `createInteractive` convenience function that makes extending `<Interactive>` quick and easy.\n\nAlso, some commonly used DOM elements are available using `Interactive.Tagname`, for example `Interactive.Button`, to make things even easier (they are created using `createInteractive('tagname')`).\n\nYou can use components with the `as` prop predefined with JSX (instead of using the `as` prop), or you can use them with CSS-in-JS libraries and other polymorphic components to avoid `as` prop conflicts (this is where they are most useful). For more see [Extending the `<Interactive>` component\n](#extending-the-interactive-component).\n\n```js\nimport { Interactive, createInteractive } from 'react-interactive';\nimport { Link } from 'react-router-dom';\n\n// these are the already defined DOM elements\n<Interactive.Button />\n<Interactive.A href=\"...\" />\n<Interactive.Input type=\"...\" />\n<Interactive.Select />\n<Interactive.Div />\n<Interactive.Span />\n\n// for other DOM elements and components use createInteractive(as)\nconst InteractiveNav = createInteractive('nav');\nconst InteractiveRouterLink = createInteractive(Link);\n\n<InteractiveNav />\n<InteractiveRouterLink to=\"...\" />\n```\n\n---\n\n## Using `eventFrom`\n\nReact Interactive uses [Event From](https://github.com/rafgraph/event-from) under the hood to determine if browser events are from mouse, touch or key input. The `eventFrom` and `setEventFrom` functions are re-exported from Event From and can be useful when building apps with React Interactive.\n\n### `eventFrom(event)`\n\nThe `eventFrom(event)` function takes a browser event and returns 1 of 3 strings indicating the input type that caused the browser event: `'mouse'`, `'touch'`, or `'key'`. For example, this can be useful to determine what input type generated a `click` event.\n\n```js\nimport * as React from 'react';\nimport { Interactive, eventFrom } from 'react-interactive';\n\nconst App = () => {\n  const handleClickEvent = React.useCallback((e) => {\n    switch (eventFrom(e)) {\n      case 'mouse':\n        // click event from mouse\n        break;\n      case 'touch':\n        // click event from touch\n        break;\n      case 'key':\n        // click event from key\n        break;\n    }\n  }, []);\n\n  return (\n    <Interactive as=\"button\" onClick={handleClickEvent}>\n      My Button\n    </Interactive>\n  );\n};\n```\n\n### `setEventFrom(inputType)`\n\n`inputType: \"mouse\" | \"touch\" | \"key\"`\n\nThis is useful when manually generating events. For example, when calling `focus()` on an `<Interactive>` component and you want it to enter the `focusFromKey` state.\n\n```js\nimport * as React from 'react';\nimport { Interactive, setEventFrom } from 'react-interactive';\n\nconst App = () => {\n  const myButtonRef = React.useRef(null);\n\n  const focusInteractiveButton = React.useCallback(() => {\n    if (myButtonRef.current) {\n      // so the <Interactive> component will enter the focusFromKey state\n      setEventFrom('key');\n      myButtonRef.current.focus();\n    }\n  }, []);\n\n  return (\n    <>\n      <button onClick={focusInteractiveButton}>Focus \"My button\"</button>\n\n      <Interactive\n        as=\"button\"\n        ref={myButtonRef}\n        focusFromKeyStyle={{ outline: '2px solid green' }}\n      >\n        My Button\n      </Interactive>\n    </>\n  );\n};\n```\n\n---\n\n## Using with TypeScript\n\n[Basics](#typescript-basics), [Exported `types`](#exported-types-from-react-interactive), [`onStateChange` callback and `children` as a function](#typing-onstatechange-callback-and-children-as-a-function), [Props passed to `<Interactive>`](#typing-props-passed-to-interactive), [Components that wrap `<Interactive>`](#typing-components-that-wrap-interactive)\n\n---\n\n### TypeScript Basics\n\nReact Interactive is fully typed, including the polymorphic `as` prop. The props that an `<Interactive>` component accepts are a union of its own props and the props that the `as` prop accepts. Live TypeScript examples are available in [TypeScriptExamples.tsx](https://github.com/rafgraph/react-interactive/blob/main/demo/src/other/TypeScriptExamples.tsx) in the demo app.\n\n```ts\nimport { Interactive } from 'react-interactive';\n\nconst App = () => (\n  <Interactive\n    as=\"a\" // render as an anchor link\n    href=\"https://rafgraph.dev\" // TS knows href is a string b/c as=\"a\"\n  >\n    My Link\n  </Interactive>\n);\n```\n\n---\n\n### Exported `types` from React Interactive\n\n```ts\ntype ActiveState = 'mouseActive' | 'touchActive' | 'keyActive' | false;\ntype FocusState = 'focusFromMouse' | 'focusFromTouch' | 'focusFromKey' | false;\n\n// type for the state object used by React Interactive\n// InteractiveState is passed to children (when children is a function)\ninterface InteractiveState {\n    hover: boolean;\n    active: ActiveState;\n    focus: FocusState;\n}\n\n// type used for the argument passed to the onStateChange callback\ninterface InteractiveStateChange {\n    state: InteractiveState;\n    prevState: InteractiveState;\n}\n\n// type used for props passed to an <Interactive> component, see below for usage\ntype InteractiveProps<T extends React.ElementType = 'button'>\n\n// type used when wrapping/extending an <Interactive> component, see below for usage\ntype InteractiveExtendableProps<T extends React.ElementType = 'button'>\n```\n\n---\n\n### Typing `onStateChange` callback and `children` as a function\n\nAlso see [TypeScriptExamples.tsx](https://github.com/rafgraph/react-interactive/blob/main/demo/src/other/TypeScriptExamples.tsx) in the demo app.\n\n```ts\nimport {\n  Interactive,\n  InteractiveState,\n  InteractiveStateChange,\n} from 'react-interactive';\n\nconst App = () => {\n  // use the InteractiveStateChange type to type the argument\n  // passed to the onStateChange callback\n  const handleInteractiveStateChange = React.useCallback(\n    ({ state, prevState }: InteractiveStateChange) => {\n      // ...\n    },\n    [],\n  );\n\n  // use the InteractiveState type to type the argument\n  // passed to children (when children is a function)\n  const childrenAsAFunction = React.useCallback(\n    ({ hover, active, focus }: InteractiveState) => {\n      // ...\n    },\n    [],\n  );\n\n  return (\n    <Interactive as=\"button\" onStateChange={handleInteractiveStateChange}>\n      {childrenAsAFunction}\n    </Interactive>\n  );\n};\n```\n\n---\n\n### Typing props passed to `<Interactive>`\n\nSometimes you need to type the props object that is passed to an `<Interactive>` component, to do this use the type `InteractiveProps<as>`. Also see [TypeScriptExamples.tsx](https://github.com/rafgraph/react-interactive/blob/main/demo/src/other/TypeScriptExamples.tsx) in the demo app.\n\n```ts\nimport { Interactive, InteractiveProps } from 'react-interactive';\n\n// props object passed to <Interactive>\n// InteractiveProps includes types for `as` and `ref`\nconst propsForInteractiveButton: InteractiveProps<'button'> = {\n  as: 'button',\n  type: 'submit', // button specific prop\n  // ...\n};\n\n// for as={Component} use InteractiveProps<typeof Component>\nconst propsForInteractiveAsComponent: InteractiveProps<typeof Component> = {\n  as: Component,\n  // ...\n};\n\nconst App = () => (\n  <>\n    <Interactive {...propsForInteractiveButton} />\n    <Interactive {...propsForInteractiveAsComponent} />\n  </>\n);\n```\n\n---\n\n### Typing components that wrap `<Interactive>`\n\nWhen creating components that wrap an `<Interactive>` component, sometimes you want to extend the `<Interactive>` component and pass through props to `<Interactive>`. To do this use the type `InteractiveExtendableProps<as>`. Also see [TypeScriptExamples.tsx](https://github.com/rafgraph/react-interactive/blob/main/demo/src/other/TypeScriptExamples.tsx) in the demo app.\n\n> Note that if all you need to do is extend `<Interactive>` with a predefined `as` prop but without additional props and logic, [use `createInteractive(as)`](#using-createinteractive) instead.\n>\n> ```ts\n> import {\n>   Interactive,\n>   InteractiveExtendableProps,\n>   createInteractive,\n> } from 'react-interactive';\n> import { Link } from 'react-router-dom';\n>\n> // this works fine, but it's not necessary\n> const InteractiveLink: React.VFC<InteractiveExtendableProps<typeof Link>> = (\n>   props,\n> ) => <Interactive {...props} as={Link} />;\n>\n> // do this instead, createInteractive also includes ref forwarding\n> const InteractiveLink = createInteractive(Link);\n> ```\n\n```ts\nimport { Interactive, InteractiveExtendableProps } from 'react-interactive';\n\n// the same props interface is used for wrapping with and without forwardRef\n// note that InteractiveExtendableProps doesn't include `as` or `ref` props,\n// when using forwardRef the ref prop type will be added by the forwardRef function\ninterface WrapperProps extends InteractiveExtendableProps<'button'> {\n  // OR extends InteractiveExtendableProps<typeof Component>\n  additionalProp?: string;\n}\n\n// without ref\nconst WrapperWithoutRef: React.VFC<WrapperProps> = ({\n  additionalProp,\n  ...props\n}) => {\n  // your logic here\n  return <Interactive {...props} as=\"button\" />;\n};\n\n// with ref\nconst WrapperWithRef = React.forwardRef<\n  HTMLButtonElement, // OR React.ElementRef<typeof Component>\n  WrapperProps\n>(({ additionalProp, ...props }, ref) => {\n  // your logic here\n  return <Interactive {...props} as=\"button\" ref={ref} />;\n});\n```\n\n---\n\n## CSS sticky `:hover` bug\n\nThe CSS sticky `:hover` bug on touch devices occurs when you tap an element that has a CSS `:hover` pseudo class. The `:hover` state sticks until you tap someplace else on the screen. This causes `:hover` styles to stick on touch devices and prevents proper styling of touch interactions (like native apps).\n\nThe reason for CSS sticky hover is that back in the early days of mobile the web relied heavily on hover menus, so on mobile you could tap to see the hover menu (it would stick until you tapped someplace else). Sites are generally no longer built this way, so now the sticky hover feature has become a bug.\n\nReact Interactive fixes the sticky hover bug by only entering the `hover` state from mouse input and creating a separate `touchActive` state for styling touch interactions.\n\n---\n\n## FAQ\n\n- **How do I manually set focus on an `<Interactive>` component?**\n  - Pass in a `ref` prop and call `focus()` on the element (this is standard React). To enter a specific `focusFrom[Input]` state use [`setEventFrom`](#seteventfrominputtype).\n- **How do I disable an `<Interactive>` component?**\n  - Pass in a [`disabled` boolean prop](#disabled-boolean).\n- **How do I use `<Interactive>` with another polymorphic component?**\n  - Use the [`createInteractive` function](#using-createinteractive).\n- **The `touchActive` state is exited even though my finger is still on the button, how do I prevent this from happening?**\n  - Pass in a [`useExtendedTouchActive` boolean prop](#useextendedtouchactive-boolean).\n- **Styling**\n  - **How do I style the interactive states with CSS?**\n    - See [Styling with CSS](#styling-with-css), and also [this CodeSandbox](https://codesandbox.io/s/react-interactive-css-style-example-ttl0t) for a live example.\n  - **How do I style the interactive states with inline styles?**\n    - See [Styling with inline styles](#styling-with-inline-styles), and also [this CodeSandbox](https://codesandbox.io/s/react-interactive-inline-style-example-6s8mn) for a live example.\n  - **How do I use Styled Components with React Interactive?**\n    - See [this CodeSandbox](https://codesandbox.io/s/react-interactive-styled-components-example-7dozj) for a live example.\n  - **How do I use Stitches with React Interactive?**\n    - See [this CodeSandbox](https://codesandbox.io/s/react-interactive-stitches-example-os981) for a live example.\n- **TypeScript**\n  - **How do I use React Interactive with TypeScript?**\n    - See [Using with TypeScript](#using-with-typescript).\n  - **What types are exported from React Interactive?**\n    - See [Exported types from React Interactive](#exported-types-from-react-interactive).\n  - **How do I extend an `<Interactive>` component including the TypeScript prop types?**\n    - See [Typing components that wrap `<Interactive>`](#typing-components-that-wrap-interactive).\n","maintainers":[{"name":"rafgraph","email":"rafael@rafgraph.dev"}],"time":{"modified":"2022-06-26T00:07:00.742Z","created":"2016-08-05T05:10:04.063Z","0.0.0":"2016-08-05T05:10:04.063Z","0.1.0":"2016-10-18T23:15:13.513Z","0.2.0":"2016-11-21T17:49:28.995Z","0.3.0":"2016-11-24T04:59:54.413Z","0.3.1":"2016-11-28T20:47:13.763Z","0.4.0":"2016-11-30T01:17:39.093Z","0.4.1":"2017-01-18T04:01:11.591Z","0.5.0":"2017-04-01T18:32:38.234Z","0.5.1":"2017-04-02T22:15:20.586Z","0.6.0":"2017-04-29T04:17:28.925Z","0.6.1":"2017-05-01T02:54:25.587Z","0.6.2":"2017-05-02T00:32:25.387Z","0.6.3":"2017-05-03T19:48:54.013Z","0.6.4":"2017-05-03T22:37:26.932Z","0.6.5":"2017-05-04T03:09:44.553Z","0.6.6":"2017-08-14T22:54:37.850Z","0.7.0":"2017-08-17T08:16:43.256Z","0.7.1":"2017-08-17T19:11:32.121Z","0.8.0":"2017-08-18T04:52:25.292Z","0.8.1":"2017-09-26T19:43:39.317Z","0.8.2":"2019-01-12T21:45:30.359Z","0.8.3":"2019-01-13T06:02:20.019Z","0.9.0":"2019-09-12T16:17:55.811Z","0.9.1":"2019-09-26T01:04:15.939Z","0.9.2":"2020-09-11T17:29:53.888Z","0.9.3":"2020-12-17T14:02:15.015Z","0.9.4":"2020-12-17T14:06:18.320Z","0.9.5":"2020-12-18T21:33:13.633Z","1.0.0-next.0":"2021-03-31T19:09:54.001Z","1.0.0-next.1":"2021-04-01T22:56:39.344Z","1.0.0-next.2":"2021-04-01T23:52:05.792Z","1.0.0-next.3":"2021-04-02T17:56:53.542Z","1.0.0-next.4":"2021-04-04T23:57:50.675Z","1.0.0-next.5":"2021-04-06T03:28:25.835Z","1.0.0-next.6":"2021-04-09T19:06:06.559Z","1.0.0-next.7":"2021-04-15T16:04:43.860Z","1.0.0-next.8":"2021-04-15T17:56:16.944Z","1.0.0-next.9":"2021-04-20T04:24:06.829Z","1.0.0-next.10":"2021-04-21T18:45:34.379Z","1.0.0":"2021-05-01T16:50:56.264Z","1.1.0":"2021-05-02T20:15:22.443Z","1.1.1":"2021-05-05T20:31:24.292Z","1.1.2":"2021-05-25T14:44:40.870Z"},"homepage":"https://react-interactive.rafgraph.dev","keywords":["react","interactive","touch","hover","active","focus","keyboard","accessibility"],"repository":{"type":"git","url":"git+https://github.com/rafgraph/react-interactive.git"},"author":{"name":"Rafael Pedicini","email":"rafael@rafgraph.dev"},"bugs":{"url":"https://github.com/rafgraph/react-interactive/issues"},"license":"MIT","readmeFilename":"README.md"}