{"_id":"bind-event-listener","_rev":"14-b81eba538693dde1451da67bde09a7c2","name":"bind-event-listener","dist-tags":{"latest":"3.0.0","alpha":"1.0.1-alpha.1","beta":"3.0.0-beta.1"},"versions":{"0.1.0":{"name":"bind-event-listener","version":"0.1.0","private":false,"description":"Making binding and unbinding DOM events easier","main":"dist/index.js","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"d6090c7fe28944a85ff2e6cceb969b1da4b13e14","_id":"bind-event-listener@0.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-UUXmuaUIltekQ2xD+74EbI+JK/RgILqC/xagRcEkHVX/++mfx/JL91xN3q8kbeBrihZvl9Wqqhou+nbfk7aMfA==","shasum":"cfb955561c79e0beb0574a915bf0ec9d2679a1bd","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-0.1.0.tgz","fileCount":14,"unpackedSize":9122,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe5qu+CRA9TVsSAnZWagAAzYIP/iqKoZGMDMvrhSXxccI+\nu0Kgzs6P31r4CbLZfaSd2ubLR91qxwPp3pRmaYpFvr++B1vfiDKh1sf3H+u6\n2CTomsaz1XHOI8YrWf6ztZT9nyqZwVt58Myf23t6DV6te5C5m8psH9rnAbKB\nab+A9r032JcFaVR7dLvEZbhnHclpVRD0v+3QfW4DNSJAM0UbXFYhhVQBU+CC\n7yYYkFFnbBzJ4PJiN0jaxzgGq44sDHQ2TC+dH/koAM4jynL2rzUKKcX29FbI\n97xs0expmYRa0FyDTbgPbB9z63YXmaUgg+RTmhgzFJF35XlEB/3xzCuRAvpp\nhnItOr+rRohi+3PQUqxTCay6nfDz3/H1iZ1KvSWay8MsVDJjo9bmPYnOaqQ+\nvTbM0DHq2dpp7a8yvumZ5/tVP2zq8B6VnAQ0HJ3beQCD1kUdA/xr2Hc6hboL\nxhHrM8ZUadCM15dAFBpGsx2APZCIuenP/40mUVIua4CppE9V0TPLxGPSmCp9\nCdpfd02Ot3qWqOpD2IaTq13fJrL9mAG7RbhgEBctXnJzOdjdoL7bhWGVIscy\nAlFx23nhfcLMhOkSRPIl+p0/G0Yt15HPJcPFGHW92DeTugLI7kRssOxm7sLv\nSIkKd+iSiIiSSQBJ6r43RCbvgArh3g2HV5EIByWXVIK4Hoz2m2KknQLZj/zl\nDr28\r\n=mTvR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDEJCl63RNooFRSHno9b3KY/m6V5s5o//U8/aEQQzcKSAiBgeV1lh9jRA9fR7vPOZDPg+oVxESQhAstc6GFfLblMsg=="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_0.1.0_1592175550343_0.5599253133253626"},"_hasShrinkwrap":false},"0.2.0":{"name":"bind-event-listener","version":"0.2.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.js","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"7bc5b856f0aaf8a9289b691f91076dfb6ef4255f","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@0.2.0","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-6sHASO2mN+4xSydCg2E/wcKJlOnqSYY6m8kPWncTn8vtFi7moRvvvuX4xIE+ihfyxa6RLd0pXHKOe7KnmJkdUw==","shasum":"d7afcff2c3e066382cd4f23d1f426d8e40f68771","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-0.2.0.tgz","fileCount":15,"unpackedSize":10388,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe5qydCRA9TVsSAnZWagAAmpwQAKMtGsrZHmTkcuvSOIyR\nyTsJLJGdmIMmL0wpkX/XYdsbyUBRvaEGFj2sFfjOWjzIHfDSZ3lQDSNtcxk0\nUm4TRa+XgxzgVoHLHQ/fbQnaQg1bEOnm9Xe6ANxsfsrsXc1xdnHYue45tSck\nqMxEicAGdGM5RSLRrGP3v+jA95oJe9h2KEdAfUapquUcPp8Rh7ct9Oq0U4Wv\nPSQJ71LhJiYnUUIFK9NK7bHWBg0JD5uxXidid0YX+gQK/oMI8fpZNgWKaJG5\nIrSGn8BIWdymsE9aXnj44fYSVtAXdou6V8SrUKhQecqaeVU8YtVVHRaHFM48\n4VScZIR9IXEXhUmJsy4eXidGS9HxMh/Op1EBoLOl5MhEZt9ZmnS7PgCTQih/\n81hqnjmoEGbMzFXGu7IIIkNVbwcqco1cx8FE686Beu8ckxKi5eQ+XcmwOc/J\nZkE7T0/lHc7bX34WwAnpy97hPiq1exUaCT72E1W6Gfn94c8GugAIQJ1q1jdf\nyX8vLfZcH8WQas5o+IONP/u32MYye07hsYpPT0qiUNsvoIv5on6pL8JFa7Lg\nJYIWETVqcA7BWknqA0vOrjhZT3KvxZYgpj/Yq5359HOe8B8oEulfblmdEMM2\nYAjHs+8nC0Fa817zsXfuBwLw33pVCJ2vsRhHk/xYmkVVSYBqOlLvGgBKl+HU\nxA3V\r\n=Pl0Z\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDHod8AjSM+3mzSF61Bakdd2fra1ctIrNti5EaGVns+wAiEAgFDTgrmcfQPxa5pkZpl920TSBCs41I7KRH+sfC/o4aY="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_0.2.0_1592175772996_0.16735351018502387"},"_hasShrinkwrap":false},"0.3.0":{"name":"bind-event-listener","version":"0.3.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.js","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"12d9a4fdee4fd3be727ece9b2f9e84fe8123cf88","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@0.3.0","_nodeVersion":"12.18.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-ewu8y3KinE3STqwTGoV02VLDO0Sh4Cqju8+mJlN/j5zk5sl6JwWxEdeth3sJdH1FfayWyVoD1eiuLW0Ob7BV6w==","shasum":"f84a0281e77fe5cd51d2e4020b8b9676765ad09d","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-0.3.0.tgz","fileCount":15,"unpackedSize":12977,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/A1HCRA9TVsSAnZWagAA/FkP/1Gb+VYqlGbaxeQJ48mr\n20w+41PlCvUQwxbSwxTV5C7KVdcv2nZ0Jb2V3DjyO/hk+91+PBwzQ1NT41D6\nHEzT15aclXgzsyanavRh6LaxH7qnrjqTsoiMOu08xr28wks8odOco0If9HxP\nYfbe6deRF8vq0HIGCgDqXh7fAS8Cvzxhavt6mTDNdZWvQLU8PUko+TMxfyOT\nwSvS9iHV+FNamqPrX5IH7C9tOaewvjKYXtMIj9UnNWpFhIkjS7hAwNL7/JIt\nIWmpXrbxnu9z+Sjj4RTopM0BnsEIFR5STDJgeaBrLBUvSi4dliZ8vWGjHLEQ\nx27OxPovN5+YBVnNQc4i7/sqAsk8xoXjH36R6qrdogaf/QteWdRULNS58wsH\nAUFAlfptAH3pu0OQ9791gdwyVAZFiBCwnYYRKzRzjlQARv5bc9/fxZYIh9Yx\nShD6+0oO6kRBJKwvDTcUU5tvyOdoIvNRymQGNXUJpppI9cTmDv7jsAASmTAG\nskIjawBbaDwTN3idKU7QbAKay9M0YmWJLud91vJMYJb7kw4tPwzqgQ5itn6F\nfozDojNEzu5xmqr0yB4b2bzRIBuukRlMRh5WaWKZes4wwqtJwFHPavu+XRS6\nqyZ28j9WlkSbILO09UIDIrpxJIc1BTNc/CUz4tEP6/Ya1ye7SDQA6rUsbFFb\nBqoG\r\n=zAHP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAXpxUsjA6oWAklNDBjRC+aSS65ZZdmr1MCDKe4pU9tdAiEA2n5xvQr+QR+3ywRglDecJvcQsHDvNsjHhF3SqtWbThk="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_0.3.0_1593576774644_0.5482788438142052"},"_hasShrinkwrap":false},"1.0.0":{"name":"bind-event-listener","version":"1.0.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.js","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"d06ac791bb53bf57cd06b773e7b3bb82f4d6d20b","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@1.0.0","_nodeVersion":"12.16.3","_npmVersion":"6.14.4","dist":{"integrity":"sha512-/Ab31w++NOcc3F8Kv4FFVsbTQ/6Cr3ULVkFktMbYAN5mT/GFelzDySf9BESUh6BscIc/TXAyT2ONUreV9PlvWA==","shasum":"651c3263cf1a3c9c14e8c0d259f3d0f2e4264b05","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-1.0.0.tgz","fileCount":15,"unpackedSize":12977,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDDHhCRA9TVsSAnZWagAAijUP/1mBij0unPnH0hXsoKBf\nd/+9Zxa8QCWZbL3WIoqc15MDswuarYzYSSUdcXj2LDMkRAxu6tYyOq8PLrdC\nyhabL8SU3K/AaYY0UcRDJQYB6V3/pLoE9KVseMnH0KStunouQtvfEputyrrm\nTg1lbdVG66jpuu+aCXW41b6UYFwwXCtwfXxemxvkx6vgssnQXamVAdnMxckF\nRYdJ6yAei8kxfIfNE/USigB1q7lvKPLEAGTDxeULmUfub4IT4BGuca0IMzaF\ntEGI/u6f2IwOwEmofBB5S8hq+n0zIteFr5HreBfnfbsDh1Iaefk+LE+4xv1r\nOWJ++cPeEl1m57OlLQWBtmsvfBGUCa3FHdo5bIw16XxdocU/Yuh+jrjzPzIV\nKGkY190wsXavmCl3Ca1ujTV5w6zxZPolcktSRTPKGcqpVf4j0T8Q62QWXnOz\ntzcvWSA22Q+jEu1/Clgd93v53AIRY5r7mDLGH9WgdcTzWhkb2OkjAgFWJ7rQ\nQwcUZaUQrVMCeKUxC/qXZq3x3WgI5J43B/8DZCCiR1H4d2E6oi+VqIbULSIB\naeXnfHa4jZMyQCsFc+1js7AXILgsHB6snvgQmjghyWLGHbeYdOOZ2l7tRr6q\nU1kKQWXsmU9nrj7H/B3q0m+2+ymp+cMMMOkvV5FamskwXrEo4qsJNvgBJXgf\nopk9\r\n=8sU8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHv7O8YkQYdnAWADgxZWmOtNOzhB4dG6HOSAOTinCTYoAiBt4uwzzWXQ8YtRo7KdL0Nmvx6onhgGx9jV7oiJ/LMhcw=="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_1.0.0_1594634720612_0.7595627078869447"},"_hasShrinkwrap":false},"1.0.0-alpha.1":{"name":"bind-event-listener","version":"1.0.0-alpha.1","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"readme":"# bind-event-listener\n\n[![npm](https://img.shields.io/npm/v/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n![types](https://img.shields.io/badge/types-typescript-blueviolet)\n\n> A utility to make binding and (**especially**) unbinding DOM events easier.\n> I seem to write this again with every new project, so I made it a library\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when you are all done:\nunbind();\n```\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bind(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { capture: true },\n  },\n  {\n    type: 'mouseover',\n    listener: onMouseOver,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n## Rationale\n\nWhen using `addEventListener()`, **correctly unbinding** events with `removeEventListener()` can be tricky.\n\n1. You need to remember to call `removeEventListener` (it can be easy to forget!)\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener('click', onClick, options);\n\n// You need to remember to call removeEventListener to unbind the event\ntarget.removeEventListener('click', onClick, options);\n```\n\n</details>\n\n2. You need to pass in the same listener _reference_ to `removeEventListener`\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n\n// Even those the functions look the same, they don't have the same reference.\n// The original onClick is not unbound!\ntarget.removeEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n```\n\n```ts\n// Inline arrow functions can never be unbound because you have lost the reference!\ntarget.addEventListener('click', () => console.log('i will never unbind'), options);\ntarget.removeEventListener('click', () => console.log('i will never unbind'), options);\n```\n\n</details>\n\n3. You need to pass in the same `capture` value option\n\n<details>\n<summary>Example</summary>\n\n```ts\n// add a listener: AddEventListenerOptions format\ntarget.addEventListener('click', onClick, { capture: true });\n\n// not unbound: no capture value\ntarget.removeEventListener('click', onClick);\n\n// not unbound: different capture value\ntarget.removeEventListener('click', onClick, { capture: false });\n\n// successfully unbound: same capture value\ntarget.removeEventListener('click', onClick, { capture: true });\n// this would also unbind (different notation)\ntarget.removeEventListener('click', onClick, true /* shorthand for { capture: true } */);\n```\n\n```ts\n// add a listener: boolean capture format\ntarget.addEventListener('click', onClick, true /* shorthand for { capture: true } */);\n\n// not unbound: no capture value\ntarget.addEventListener('click', onClick);\n// not unbound: different capture value\ntarget.addEventListener('click', onClick, false);\n\n// successfully unbound: same capture value\ntarget.addEventListener('click', onClick, true);\n// this would also unbind (different notation)\ntarget.addEventListener('click', onClick, { capture: true });\n```\n\n</details>\n\n**`bind-event-listener` solves these problems**\n\n1. When you bind an event (or events with `bindAll`) you get back a simple `unbind` function\n2. The unbind function ensures the same listener _reference_ is passed to `removeEventListener`\n3. The unbind function ensures that whatever `capture` value is used with `addEventListener` is used with `removeEventListener`\n\n## Usage\n\n### `bind`: basic\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when your are all done:\nunbind();\n```\n\n### `bind`: with options\n\n```ts\nimport { bind } from 'bind-event-listener';\n\nconst unbind = bind(button, {\n  type: 'click',\n  listener: onClick,\n  options: { capture: true, passive: false },\n});\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: basic\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: with options\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { passive: true },\n  },\n  // default options that are applied to all bindings\n  { capture: false },\n]);\n\n// when you are all done:\nunbind();\n```\n\nWhen using `defaultOptions` for `bindAll`, the `defaultOptions` are merged with the `options` on each binding. Options on the individual bindings will take precedent. You can think of it like this:\n\n```ts\nconst merged: AddEventListenerOptions = {\n  ...defaultOptions,\n  ...options,\n};\n```\n\n> Note: it is a little bit more complicated than just object spreading as the library will also behave correctly when passing in a `boolean` capture argument. An options value can be a boolean `{ options: true }` which is shorthand for `{ options: {capture: true } }`\n\n## Recipe: [`react`](https://reactjs.org/) effect\n\nYou can return a [cleanup function](https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect) from [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) (or [`useLayoutEffect`](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)). `bind-event-listener` makes this super convenient because you can just return the unbind function from your effect.\n\n```ts\nimport React, { useState, useEffect } from 'react';\nimport { bind } from 'bind-event-listener';\n\nexport default function App() {\n  const [clickCount, onClick] = useState(0);\n\n  useEffect(() => {\n    const unbind = bind(window, {\n      type: 'click',\n      listener: () => onClick((value) => value + 1),\n    });\n\n    return unbind;\n  }, []);\n\n  return <div>Window clicks: {clickCount}</div>;\n}\n```\n\n> You can play with this [example on codesandbox](https://codesandbox.io/s/bind-event-listener-useeffect-mnfi3)\n\n## Types\n\n```ts\nfunction bind(target: EventTarget, binding: Binding): UnbindFn;\n\nfunction bindAll(\n  target: EventTarget,\n  bindings: Binding[],\n  // AddEventListenerOptions is a built in TypeScript type\n  sharedOptions?: boolean | AddEventListenerOptions,\n): UnbindFn;\n\ntype Binding = {\n  type: string;\n  // EventListenerOrEventListenerObject is a built in TypeScript type\n  listener: EventListenerOrEventListenerObject;\n  options?: boolean | AddEventListenerOptions;\n};\n\ntype UnbindFn = () => void;\n```\n\n> Typescript built in DOM types: [raw view](https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.dom.d.ts), [pretty view](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts) (warning: pretty view seems to crash Github!)\n\n## Cheers 👋\n\nBrought to you by [@alexandereardon](https://twitter.com/alexandereardon)\n","readmeFilename":"README.md","gitHead":"7ef9bd2c6f204bdaac0737a806cf30badc4bbb07","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@1.0.0-alpha.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-Pw6/GLc50+1VMM/U8Zppgr4UdFdpE+127oH5LYKXhEpjnhuMhfaPlnEsprRcGpij8DvL7P1Kq4Agc53kyeNjLA==","shasum":"44f69241146746a9b3660ea2b58d40658f14e124","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-1.0.0-alpha.1.tgz","fileCount":15,"unpackedSize":13578,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDUKjCRA9TVsSAnZWagAAxwoQAJQkAnR2ngQ/LxssWTHl\nciw1xNjJBD6t6ix1YMpTiGNwlZWjXjzd0AnTFWq9G5dzjUPA98kR0wWe24nO\nrH+lWUdF4dLfoCotT3kDmiS8rWmPIvDkrvkuKrmAwFRIwHy4FFhpo7VSoqfN\njPxel3H7pQXjo9+MhIyXDa/GJauFNSp1ClFoiLqGqbX3s9nsteKv3qnSfrOl\n/0pJbrNoY+FKmQbBvbEGu0OBOixnWMySdNqSPrm7TKBnoEG1rjRSQlL3MiM6\nFaZC7yj2/pgzP0U9FjKPhvG6BfFra2ET1r3lNOBuvnvgDGHqCmAHQpM0WoNd\nQIYBsbAyU+mS3YCJ0+84rtC4mz9Q5CZWFTdn30g+YxjEZAinfKqtFVFrjM+a\nT49EkoDTMfDrSj4FYtrdahZW4IKg27B3HW4tU99YpdkEB+zvm2Tx58CM2YIq\ntXGdnDIAHHgXlLjo8bOYLICtkmQUD0SQ3WjQB0kU2TuLIreClLhOo0bPF4Os\nWhN8/p6iD59LUenZAbicCjuw3clQp9F37Xh5wD870ikFEBTG5unuGYfzGHNk\nz4dNwzf3hnp34MUPjZ0JL0kPb6p12jAA+ME4oQymr0B1KhrKgLqVOeq0/Grt\nedM/M+4EKg9cBp8TnOVdGk0LSLMdE1o54iS06Ldi+gMh7TioVthP8BQTNY+l\n/GHb\r\n=vRUQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDI3aIRDvPxZZTaOOYpOirU5Rv2PNKodG3ufkW81rNgxQIgaDCvWQeSGHA7qxOJgFjGw15dKfX0RalnSRTwHNVgesg="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_1.0.0-alpha.1_1594704546613_0.22590866390658637"},"_hasShrinkwrap":false},"1.0.1-alpha.1":{"name":"bind-event-listener","version":"1.0.1-alpha.1","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"readme":"# bind-event-listener\n\n[![npm](https://img.shields.io/npm/v/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n![types](https://img.shields.io/badge/types-typescript-blueviolet)\n\n> A utility to make binding and (**especially**) unbinding DOM events easier.\n> I seem to write this again with every new project, so I made it a library\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when you are all done:\nunbind();\n```\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bind(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { capture: true },\n  },\n  {\n    type: 'mouseover',\n    listener: onMouseOver,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n## Rationale\n\nWhen using `addEventListener()`, **correctly unbinding** events with `removeEventListener()` can be tricky.\n\n1. You need to remember to call `removeEventListener` (it can be easy to forget!)\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener('click', onClick, options);\n\n// You need to remember to call removeEventListener to unbind the event\ntarget.removeEventListener('click', onClick, options);\n```\n\n</details>\n\n2. You need to pass in the same listener _reference_ to `removeEventListener`\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n\n// Even those the functions look the same, they don't have the same reference.\n// The original onClick is not unbound!\ntarget.removeEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n```\n\n```ts\n// Inline arrow functions can never be unbound because you have lost the reference!\ntarget.addEventListener('click', () => console.log('i will never unbind'), options);\ntarget.removeEventListener('click', () => console.log('i will never unbind'), options);\n```\n\n</details>\n\n3. You need to pass in the same `capture` value option\n\n<details>\n<summary>Example</summary>\n\n```ts\n// add a listener: AddEventListenerOptions format\ntarget.addEventListener('click', onClick, { capture: true });\n\n// not unbound: no capture value\ntarget.removeEventListener('click', onClick);\n\n// not unbound: different capture value\ntarget.removeEventListener('click', onClick, { capture: false });\n\n// successfully unbound: same capture value\ntarget.removeEventListener('click', onClick, { capture: true });\n// this would also unbind (different notation)\ntarget.removeEventListener('click', onClick, true /* shorthand for { capture: true } */);\n```\n\n```ts\n// add a listener: boolean capture format\ntarget.addEventListener('click', onClick, true /* shorthand for { capture: true } */);\n\n// not unbound: no capture value\ntarget.addEventListener('click', onClick);\n// not unbound: different capture value\ntarget.addEventListener('click', onClick, false);\n\n// successfully unbound: same capture value\ntarget.addEventListener('click', onClick, true);\n// this would also unbind (different notation)\ntarget.addEventListener('click', onClick, { capture: true });\n```\n\n</details>\n\n**`bind-event-listener` solves these problems**\n\n1. When you bind an event (or events with `bindAll`) you get back a simple `unbind` function\n2. The unbind function ensures the same listener _reference_ is passed to `removeEventListener`\n3. The unbind function ensures that whatever `capture` value is used with `addEventListener` is used with `removeEventListener`\n\n## Usage\n\n### `bind`: basic\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when your are all done:\nunbind();\n```\n\n### `bind`: with options\n\n```ts\nimport { bind } from 'bind-event-listener';\n\nconst unbind = bind(button, {\n  type: 'click',\n  listener: onClick,\n  options: { capture: true, passive: false },\n});\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: basic\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: with options\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { passive: true },\n  },\n  // default options that are applied to all bindings\n  { capture: false },\n]);\n\n// when you are all done:\nunbind();\n```\n\nWhen using `defaultOptions` for `bindAll`, the `defaultOptions` are merged with the `options` on each binding. Options on the individual bindings will take precedent. You can think of it like this:\n\n```ts\nconst merged: AddEventListenerOptions = {\n  ...defaultOptions,\n  ...options,\n};\n```\n\n> Note: it is a little bit more complicated than just object spreading as the library will also behave correctly when passing in a `boolean` capture argument. An options value can be a boolean `{ options: true }` which is shorthand for `{ options: {capture: true } }`\n\n## Recipe: [`react`](https://reactjs.org/) effect\n\nYou can return a [cleanup function](https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect) from [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) (or [`useLayoutEffect`](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)). `bind-event-listener` makes this super convenient because you can just return the unbind function from your effect.\n\n```ts\nimport React, { useState, useEffect } from 'react';\nimport { bind } from 'bind-event-listener';\n\nexport default function App() {\n  const [clickCount, onClick] = useState(0);\n\n  useEffect(() => {\n    const unbind = bind(window, {\n      type: 'click',\n      listener: () => onClick((value) => value + 1),\n    });\n\n    return unbind;\n  }, []);\n\n  return <div>Window clicks: {clickCount}</div>;\n}\n```\n\n> You can play with this [example on codesandbox](https://codesandbox.io/s/bind-event-listener-useeffect-mnfi3)\n\n## Types\n\n```ts\nfunction bind(target: EventTarget, binding: Binding): UnbindFn;\n\nfunction bindAll(\n  target: EventTarget,\n  bindings: Binding[],\n  // AddEventListenerOptions is a built in TypeScript type\n  sharedOptions?: boolean | AddEventListenerOptions,\n): UnbindFn;\n\ntype Binding = {\n  type: string;\n  // EventListenerOrEventListenerObject is a built in TypeScript type\n  listener: EventListenerOrEventListenerObject;\n  options?: boolean | AddEventListenerOptions;\n};\n\ntype UnbindFn = () => void;\n```\n\n> Typescript built in DOM types: [raw view](https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.dom.d.ts), [pretty view](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts) (warning: pretty view seems to crash Github!)\n\n## Cheers 👋\n\nBrought to you by [@alexandereardon](https://twitter.com/alexandereardon)\n","readmeFilename":"README.md","gitHead":"31238fbaa212e4678290e62b8865d35f18198bc7","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@1.0.1-alpha.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-OjYL7Ds0qReUYzuKh7LE1MaOfw16BvAd6aNd8A6kAA4spIhc1CKknGCu24LTj9hQspNZdxG78kkSQJpXY9F6VA==","shasum":"bfca7e5ac5a343c8dd212d998e1ba7e97d299886","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-1.0.1-alpha.1.tgz","fileCount":15,"unpackedSize":13578,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDULrCRA9TVsSAnZWagAA2sAP/iSeq7GH8o0VYPHTiKID\nh5LQ2QKe9B67iSwoe3qRThXZlDJTz9NP61KF9LANl6w1d3HaCg5UMWRPTFdb\n5otV59A1SCiSTHU1CpoA0m6Vssbj7AT0oyahHKc/uvOVZ87YPar0rcp7e7Gs\nrxS+0MHAYQnYK0AVDdetGeIAVM7KWhUyxUxh8tVrQSq/h2yQDc0kMLo6xdFY\nOs064mk2Glo5bf4vRWnIaKODolFEosZkb6V3WJmDBwKtOu4S8K3A7mePoTuS\nOES69Bl0l+Vt0+OsRyrSlW7Ep301o21XuaDL4sOIqRcN6BTu7BLHH29W2GsW\n/BVq9wnbjO92mLa4y0bWBIK2o1mJrM8762VQJUN2UPDBBcvph39K1dy4qbqQ\nrb1+i8bjTVr2y1KFTJTYkMwwwhPlOdHRD+ILI34xCYNUFQj7cLJCKBh7zld+\n4sY2B0TyqQJiKgUkNfltkhZiz2M0jHKBngvi2JYRi+o4uO7WpjEx2WMGJDxl\nuZSA0YOehH1waazRupHx8xVGYNzK67E+J+C8HTZGMDYtcLpTWyl0/gi132V0\nO0HypnF0RCTR1yg5A3f1CAgf4bXs2x4NFQgKuA+MM6qDHxPmKi62kK9KhrrA\neGk2qLIROWAmfEAth7n6UFxdDGBQdctgSRtHTLPC3kbKX2GFZI2ZFsU7f1uH\nAoAj\r\n=eica\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD083ugAA92XcV0dBHzqbhiFYbm4WCpQTotd9msx/2uvQIgHyvOLgdJgp1zQXr9ty8Vear137WEb0wEB/2o8KmhIuw="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_1.0.1-alpha.1_1594704619316_0.9907018760809696"},"_hasShrinkwrap":false},"1.0.1":{"name":"bind-event-listener","version":"1.0.1","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"d8f586da14e81375f390fc02350ae002af10e515","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@1.0.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-97vNtDVrhyEneuzXZYmt2Iena9LL3lxsjyhvYD7OpSEMoWcRwQuPNXaGLZv75uSd4j2+t2doUlcLcYVNjtqXnQ==","shasum":"9d2c42c2d9441232e4304ea1f74c5c01b8322369","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-1.0.1.tgz","fileCount":15,"unpackedSize":13570,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDUcnCRA9TVsSAnZWagAA7loQAIGys3Yywx+DzYea5Z3v\nzI4fp8yuDYRH9FqkKnFkMBxF7qMO8/GLcTgou88plsxTVndk1Lim+vYH03E3\nVtREUdG0V6q8Q8G/Z6Z/JJ4+IJ8nrLHidNaRtqcUsvjVPEYntbMWUNXoKyok\nEIyvcaMqCiaPBHjorGHFtH0P3VuhG4lTEe2vFv+YiQS81ZxgiqozI3wk95Sn\nu6/SiamNEtoP9xE73nHXdVeFyYlVnmULGSnvT4+ili6QoPi0uR8eudc0YWQJ\nWf/55tDPFdLPYnOMroiHH8+G/oL5dltUbla8IBGlE+WfKhpgu2dzpEIt5ivV\n6/XoVH+sW6VA955Q7OwfVIPLZorr2pkWzyqQutDffrxqzR25/n3npfwlDMbv\n0SKSPn6BUCDBG9a8dchChG290rdHtjZCIqsCI3EwfArWOCZD677m8cZgD2Z+\nS0O33fn6jgnCkXnjdXrzDgol2ccPNCcIRZJf3lk4tiTa1W1ZzsEBJ0jy8ij4\nR8HP0VgxU6TF+JsR7zlBsGABbtArtNprLjtVo/7sH17IE871fq2+75MPGohB\n2DKVnA45Jgh2ZnA5/JqCJVnqK0fjcjYmJpVT4BuqeBZ+/7gF0KkZtuXG1YUK\nLXZsehifvl6vx1vbqY/Rde1WPhtOmLsApJzJ86/rgtflq/+HXUOIRoAWsV/0\nhBtq\r\n=4f/v\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH3mmvQkxxL2tHUb+lSo8g4EgNSN0iZA85VEQ8swxLgUAiAEpend9QKIfpIypw5itA2Bn9JojhU5gCj4UBFFWDLAww=="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_1.0.1_1594705703481_0.8591303857176427"},"_hasShrinkwrap":false},"1.0.2":{"name":"bind-event-listener","version":"1.0.2","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","test":"yarn jest","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@types/jest":"^26.0.0","jest":"^26.0.1","prettier":"^2.0.5","rimraf":"^3.0.2","ts-jest":"^26.1.0","typescript":"^3.9.5"},"dependencies":{},"gitHead":"b3151330fcafd11b0706351458283874db8bd03e","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@1.0.2","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"dist":{"integrity":"sha512-50S1ecl2UzqyHabspfZkZ0zp+V92ueggSm5BUFYGCHq9cD48a6bDqZeEykSWF4yFEbWDIOkl1Ly7igta9l3E7Q==","shasum":"3af1ab15f64aff0b95ba38e0e9d7d2c78b85dc0b","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-1.0.2.tgz","fileCount":15,"unpackedSize":13995,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfERgyCRA9TVsSAnZWagAAqVcQAIaNzqgL3+E1Lc1LYIsb\ngbUueiBtIxpXikuX92WGAiNkxWumUiqeIzdtvxjJYYJ02/q98OeXE0Ee8qWE\nk4tKdGMWQoKPh0eUQ5gB5xYt+ZmQKaXTZXILnCcsP/dEFpSmIt/VfyMzu68i\nxc/Lr2ogVHLOun2+DvRpntFRGgvwQBKrjqckQqo6r352WqRGohUKXuaipoNA\nfksbiQg6f6G2fXlzoBU8AsQ/MtMBQpzU8oB7rRGXjoXdSabW9k+0GMdsg2PU\ni71W/DzEe+FF5zCOPWdwfj+GKMwC9qQSJncdcYYAR/Dp0mjNhmFVXt7E5lgH\nM+oVLVwMO/W3YYbREkOyryduK9ifvKReI9LDi+fDERRtEvtjOS01eFJBrtLO\nbqnqVhr+hWI3pzikMWWTHOehLfyryKKGZG1puGYaTsp4AaK2/jRm4JbXLtsb\na52FIySCmaGfHSJF7oFVGmOi56RWwOdwiA7J1UeDYg2jDeaFDqC/W8W8cZBS\n27Wu8GVhw5pt64PCBCrsXDbznkSxHSObeU9W1pNA3Llu+fV79EKbNC59Q1mz\nY+H1QsZC4668Ws/ih+jCGmRokSlH7FA50BNVUZfnuqH9J5rK1eobf+YiA3zV\nilqQd+59p7DIl/zPlz+ijqzyJ2enGHaPSbTAtAYEC8scpujV+y5rbY3RAg3t\nfgdQ\r\n=vHz/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+er6ERqSpjZC6OZyBrBOuZ//goNd/oNpkUKLDEf7pBwIgaKIWLP1okkodJH4z5MORwiiHZDyiJrG/vzK/PnN27Kg="}]},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_1.0.2_1594955826177_0.8960492271598315"},"_hasShrinkwrap":false},"2.0.0":{"name":"bind-event-listener","version":"2.0.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"330B"}],"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^4.11.0","@types/jest":"^26.0.23","expect-type":"^0.11.0","jest":"^27.0.4","prettier":"^2.3.1","rimraf":"^3.0.2","size-limit":"^4.11.0","ts-jest":"^27.0.3","typescript":"^4.3.2"},"dependencies":{},"gitHead":"c966e80f4a487037eea42ed6e8853d95e6427754","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@2.0.0","_nodeVersion":"14.15.0","_npmVersion":"7.11.1","dist":{"integrity":"sha512-dwUFYlM1O4v0YHtTPnbNna9NOA47CumivFcNzaRnwlz7JNJZ8gYSh3cJViVbu4c2Hm1z22Z58r7verKtBpObSA==","shasum":"5e21d7a0ae8f33420a020d89f91ae6567771690e","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-2.0.0.tgz","fileCount":15,"unpackedSize":22245,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvbFWCRA9TVsSAnZWagAAH58P/3IUEkV1RCbDytz94IE3\nsrC/Aeb9686yI3qiSf0X9264HsgeDWZL5X5jprxR5EwJTeXqDxrUgex3lie7\nRnqJ625J7YzOW2nX89JXA9oosXHvvnZu7VVPU/pg3J57w+oE0VsJ8pBOmrWP\nCQFB4XMBt1u/mSVASnAWyfAQuQYb3UVo3LozmqHL3mFcn5NbKweLEbIiL965\nGFnxNqAgU81dX3hF0nlIFz7BK35CJrxtjNml5wC0Uplh1fsKCU7t9mX+qkTk\nquEiVwOiePjLaqejUv5SfEuVLx1XAjKkch+du+6jkca53V4POzw6M0NqahDI\nDbTUwQ9jGB3M6t3ij66+0pZIW63QixNMTjKGRX3fZu4+WoyFbCx4XYdqYYQA\nJgrxLDJ2rRUKZ2OTGk42Sb1pAe3A3JXMD5WHCQLC7J9up3IhzrbF6g035WAZ\nkwq5ZStPTA5ukp23HhzQRaWw2rsAUPpH7At2hfmp2B3j9SfwudwAuKoq4LAn\nRZSk74dOJWfOAENQRE9CmtNfi11j7u6PzP+zPmvKbUUdjGq+6BVXL4z/5+55\nouXyxejr8hSjbINFEnQYyTjF1jzAOxHacrubGUGZdziUqQByxWdfPiC4Ko4E\nWJ+E7Yr+Pi7s14q19vBJH4fD29ykQsYKB15IIF3jh27S71w7B/w5otUXPS/z\nTeSG\r\n=UJ6I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCheeW40q8v3MUidMcT4l8g3c3e9v9stHLpSbAFg5r3cgIhAI2GPHRlw46tHolD5v6U5K9zb/LBdofhiMEAeWJwC1Yo"}]},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_2.0.0_1623044438265_0.9549554833415155"},"_hasShrinkwrap":false},"2.1.0-beta.0":{"name":"bind-event-listener","version":"2.1.0-beta.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"549B"}],"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^7.0.5","@types/jest":"^27.4.0","expect-type":"^0.13.0","jest":"^27.4.7","prettier":"^2.5.1","rimraf":"^3.0.2","size-limit":"^7.0.5","ts-expect":"^1.3.0","ts-jest":"^27.1.3","typescript":"^4.6.4"},"dependencies":{},"readme":"# bind-event-listener\n\n[![npm](https://img.shields.io/npm/v/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n![types](https://img.shields.io/badge/types-typescript-blueviolet)\n[![minzip](https://img.shields.io/bundlephobia/minzip/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n\n> A utility to make binding and (**especially**) unbinding DOM events easier.\n> I seem to write this again with every new project, so I made it a library\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: function onClick(event) {},\n});\n\n// when you are all done:\nunbind();\n```\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: function onClick(event) {},\n    options: { capture: true },\n  },\n  {\n    type: 'mouseover',\n    listener: function onMouseOver(event) {},\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n## Rationale\n\nWhen using `addEventListener()`, **correctly unbinding** events with `removeEventListener()` can be tricky.\n\n1. You need to remember to call `removeEventListener` (it can be easy to forget!)\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener('click', onClick, options);\n\ntarget.removeEventListener('click', onClick, options);\n```\n\n</details>\n\n2. You need to pass in the same listener _reference_ to `removeEventListener`\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n\n// Even those the functions look the same, they don't have the same reference.\n// The original onClick is not unbound!\ntarget.removeEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n```\n\n```ts\n// Inline arrow functions can never be unbound because you have lost the reference!\ntarget.addEventListener('click', () => console.log('i will never unbind'), options);\ntarget.removeEventListener('click', () => console.log('i will never unbind'), options);\n```\n\n</details>\n\n3. You need to pass in the same `capture` value option\n\n<details>\n<summary>Example</summary>\n\n```ts\n// add a listener: AddEventListenerOptions format\ntarget.addEventListener('click', onClick, { capture: true });\n\n// not unbound: no capture value\ntarget.removeEventListener('click', onClick);\n\n// not unbound: different capture value\ntarget.removeEventListener('click', onClick, { capture: false });\n\n// successfully unbound: same capture value\ntarget.removeEventListener('click', onClick, { capture: true });\n// this would also unbind (different notation)\ntarget.removeEventListener('click', onClick, true /* shorthand for { capture: true } */);\n```\n\n```ts\n// add a listener: boolean capture format\ntarget.addEventListener('click', onClick, true /* shorthand for { capture: true } */);\n\n// not unbound: no capture value\ntarget.addEventListener('click', onClick);\n// not unbound: different capture value\ntarget.addEventListener('click', onClick, false);\n\n// successfully unbound: same capture value\ntarget.addEventListener('click', onClick, true);\n// this would also unbind (different notation)\ntarget.addEventListener('click', onClick, { capture: true });\n```\n\n</details>\n\n**`bind-event-listener` solves these problems**\n\n1. When you bind an event (or events with `bindAll`) you get back a simple `unbind` function\n2. The unbind function ensures the same listener _reference_ is passed to `removeEventListener`\n3. The unbind function ensures that whatever `capture` value is used with `addEventListener` is used with `removeEventListener`\n\nYou will find an even fuller rationale for this project in my course: [\"The Ultimate Guide for Understanding DOM Events\"](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n[![share-card-dom-events](https://user-images.githubusercontent.com/2182637/120963089-52a45f00-c7a4-11eb-82a7-a04c2731999a.jpg)](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n## Usage\n\n### `bind`: basic\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when your are all done:\nunbind();\n```\n\n### `bind`: with options\n\n```ts\nimport { bind } from 'bind-event-listener';\n\nconst unbind = bind(button, {\n  type: 'click',\n  listener: onClick,\n  options: { capture: true, passive: false },\n});\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: basic\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: with options\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { passive: true },\n  },\n  // default options that are applied to all bindings\n  { capture: false },\n]);\n\n// when you are all done:\nunbind();\n```\n\nWhen using `defaultOptions` for `bindAll`, the `defaultOptions` are merged with the `options` on each binding. Options on the individual bindings will take precedent. You can think of it like this:\n\n```ts\nconst merged: AddEventListenerOptions = {\n  ...defaultOptions,\n  ...options,\n};\n```\n\n> Note: it is a little bit more complicated than just object spreading as the library will also behave correctly when passing in a `boolean` capture argument. An options value can be a boolean `{ options: true }` which is shorthand for `{ options: {capture: true } }`\n\n## Types\n\nThanks to the great work by [@Ayub-Begimkulov](https://github.com/Ayub-Begimkulov) `bind-event-listener` has fantastic TypeScript types\n\n> ⚠️ TypeScript 4.1+ is required\n\n```ts\nimport invariant from 'tiny-invariant';\nimport { bind } from 'bind-event-listener';\n\nbind(window, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `window` (the event target that the event listener is added to)\n  },\n});\n\nconst button = document.querySelector('button');\ninvariant(button instanceof HTMLElement);\n\nbind(button, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `button` (the event target that the event listener is added to)\n  },\n});\n\nconst object = {\n  handleEvent: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `object` (the event listener object that the event listener is added to)\n  },\n};\n\nbind(button, {\n  type: 'click',\n  function: object,\n});\n```\n\n## Recipe: [`react`](https://reactjs.org/) effect\n\nYou can return a [cleanup function](https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect) from [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) (or [`useLayoutEffect`](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)). `bind-event-listener` makes this super convenient because you can just return the unbind function from your effect.\n\n```ts\nimport React, { useState, useEffect } from 'react';\nimport { bind } from 'bind-event-listener';\n\nexport default function App() {\n  const [clickCount, onClick] = useState(0);\n\n  useEffect(() => {\n    const unbind = bind(window, {\n      type: 'click',\n      listener: () => onClick((value) => value + 1),\n    });\n\n    return unbind;\n  }, []);\n\n  return <div>Window clicks: {clickCount}</div>;\n}\n```\n\n> You can play with this [example on codesandbox](https://codesandbox.io/s/bind-event-listener-useeffect-mnfi3)\n\n## Types\n\n```ts\nfunction bind(target: EventTarget, binding: Binding): UnbindFn;\n\nfunction bindAll(\n  target: EventTarget,\n  bindings: Binding[],\n  // AddEventListenerOptions is a built in TypeScript type\n  sharedOptions?: boolean | AddEventListenerOptions,\n): UnbindFn;\n\ntype Binding = {\n  type: string;\n  // EventListenerOrEventListenerObject is a built in TypeScript type\n  listener: EventListenerOrEventListenerObject;\n  options?: boolean | AddEventListenerOptions;\n};\n\ntype UnbindFn = () => void;\n```\n\n> Typescript built in DOM types: [raw view](https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.dom.d.ts), [pretty view](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts) (warning: pretty view seems to crash Github!)\n\n## Cheers 👋\n\nBrought to you by [@alexandereardon](https://twitter.com/alexandereardon)\n","readmeFilename":"README.md","gitHead":"37aec31ae72862629c7391697a3a27d050b3959b","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@2.1.0-beta.0","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-OoF8yQZtszk/fgp7c5qPFK0ftTb5EzVUlW6yVvPFvatL9vIleqhNHl3Hdp1/AgHjicGGf4Y4pI/CCGxGxGLdIg==","shasum":"41ba41605712d632aaa7fc6ffff7332e012705cf","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-2.1.0-beta.0.tgz","fileCount":15,"unpackedSize":22027,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiQN3YlG1a1vx/vp7uIIKzWCscSvzb4lxb1TlBc7e7mgIhAO5+EkFOWEdoccegnaZIf7iWiHMIgz7d3S7L2YGI0MPV"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJichBOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrpFw/+IzAtJox2hmxJvIg7+syNfpmVSfGaxwfa6D4DNN6hat55/viB\r\n8m6LrPY8AhzCXl8tmL6EC68GOcQxX8P77h6AfulPA6u/Glr3Q8PqiyHO8n1X\r\nLSyrwo9SwDjkp5zsBTV4NYDcaVVbJAUg42PM6u0ZLTBPadRYth7kCnvFvLfE\r\nKtq1bddcsIl+fphpm40BNMJd6qULbt91bpZiAPbx2w4fMNuLoiZjP6qQ1AM5\r\nK7tB4rgraz+nMWwIto5vzuAUYMWvhMzlxZI9t0Rud5DmiC8w4CMrv7wasKGE\r\n0yrxYbvU9oKU7KY/bqd+a4oEDdu2vXs6jTubEVQSmb5YzjySCVKC3eauNDsa\r\nVoC+jQgI78S8YGy1HiqZM1Hunqde38X38o0NZkGuBk/s4nx/chIcUNch77xJ\r\nMIMIRtsYA1TgHloaYXeTPyt2YTjo8TuF/6kUpqEnTryrjzvNdNgbxMmorh6H\r\n9kPLATCM9tMGrUb4MTqWyLgDIQnUZ0ZjdYYnkyZLqMjcY1QYgztsANBdG1PO\r\naV19vODwM9IkrY6SPW8XFau1QnuqPUdeSPLMqhQHbPA3OdX/ZFN4U5ZXiUdZ\r\nsdYAc8306dYdL8w2IsxU/c14ob918ld28XkVr31E8k9EcvGGaar7wjxuA1uk\r\nelRCbTUEbq1h12Cx0NxuaPGAJfUxcs9TDDg=\r\n=+7rO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_2.1.0-beta.0_1651642445856_0.9269916563115166"},"_hasShrinkwrap":false},"2.1.0":{"name":"bind-event-listener","version":"2.1.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"549B"}],"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^7.0.5","@types/jest":"^27.4.0","expect-type":"^0.13.0","jest":"^27.4.7","prettier":"^2.5.1","rimraf":"^3.0.2","size-limit":"^7.0.5","ts-expect":"^1.3.0","ts-jest":"^27.1.3","typescript":"^4.6.4"},"dependencies":{},"gitHead":"297c8fc83fafe5583f543d6d733904e336a40057","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@2.1.0","_nodeVersion":"17.9.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-YnT3ScNH5F5FEOvzhuVBaowK4avMPiv3vaGGV81fgnhON+iZmn618lXK9nbCSAa7SQiP59oy1TREI51tGk5JLQ==","shasum":"2fc275cce0bb40bdb900931a7c472a482bcf1f0e","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-2.1.0.tgz","fileCount":15,"unpackedSize":22292,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA075IzCdOgzQkU9ugkrT/qHctapatfrhM8x0WaHeqhOAiB99YBmQbt3SNlNMMjOkfxvCGhI7llMdvbvsgZSxExD+g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJic18fACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpmKg//Wc7e+E0CtaLSTksvkEq1M94f5gwzGBVtN9jBnIKtS1mhqW51\r\n8sncCBtp9SlWQavMD9iWQyZc+ne6klK1+JFeqN71DbqI0UUyTCVZPvvkM7yx\r\nng9ax9cOyGEMQb/XOVS+x9JYSoAUFMj2DC7wAjkFl9kdjwBmDg24kcO512Ws\r\nc8BG0VDDwh/uz2DZqnl6OvX1lO6lBQRRrUmPrFAGmGo89md/tjRGQlff/8MG\r\nuQEWwWsbYhHQvebWoOpkyo7DIv693rIm5kuACZ6nc67XNvbNSyGN05qFhgJx\r\niYwbJYVaOYGzcoVRMNEgZc3rWLuasbqIXD8cCuuLBOhlDSHXWiaq3+koO+Y0\r\n++7ncMMYcLL1k3NUCV2815/4/a4t/4i5Njklp85zSIJqb5HZHVg65ouHlc+0\r\nw4WqAgD4a/6pxFsOqB4fiB1zfxLED46IIKNyTFGyhdXJPSdtOi39Zl5cFwFz\r\nVVoHmaKUhP0ecfCoGcGGiQDRRZTV7svYr762f4Q8m3kRaDSUqIVCPcRzIKsj\r\npfq602nxCID+ywcQK8U97t7jS8OWWewSzmD5ccskI+lQEc/QXE821IyugH76\r\nNixggXAiXt7dXzZb7uexjaGRmvFVRNoZrYODT+fTIWoLm3Q9iF088fQ6twjm\r\nVFnnSDggbtoceGiD5x1DSbjlr4wm7nbprkQ=\r\n=3hvJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_2.1.0_1651728158857_0.7635920317919893"},"_hasShrinkwrap":false},"2.1.1":{"name":"bind-event-listener","version":"2.1.1","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"549B"}],"scripts":{"typescript:check":"yarn tsc --noEmit","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^7.0.5","@types/jest":"^27.4.0","expect-type":"^0.13.0","jest":"^27.4.7","prettier":"^2.5.1","rimraf":"^3.0.2","size-limit":"^7.0.5","ts-expect":"^1.3.0","ts-jest":"^27.1.3","typescript":"^4.6.4"},"dependencies":{},"gitHead":"ec5d02c8155e27f57cebc90b645e5afe00cc71a4","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@2.1.1","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"integrity":"sha512-O+a5c0D2se/u2VlBJmPRn45IB6R4mYMh1ok3dWxrIZ2pmLqzggBhb875mbq73508ylzofc0+hT9W41x4Y2s8lg==","shasum":"5e57290181af3027ff53ba6109e417a1e3cbb6f3","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-2.1.1.tgz","fileCount":15,"unpackedSize":30008,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB85ToUA74bjwCf5JhQjrpdDlYDdyJeoT/DZbL/lHJ/9AiEAzYdzQ3CNbKhtEYdoYI+juH5B7Ev6+s8nGGJCGYeK874="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJitZwxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmow7Q/+NtkeNhYGSbU7WVU5UzMUGkOdbRmTXUgoGX2oIlsKxE+bPk74\r\nLof8SYznYTaFOFI39hmcWNwzc83PzXmhN4WhwlFdXvbBkKuJ4vrbz96yNO1o\r\nghlSzd1f9gs1ysX+PVzOoY8Dgnb6u3zr6wCGZYvDepoNud3dMTmP/vnhGyTF\r\noL8LF+VJ0FSDVBg6QJpMdRI2xRFWVYxLEHznF3aw6AXwaWWFVh715qqmiQMc\r\nCjlXYPdGe4VhudgwfAL6HfZqVRObVm26TV4ueFotaEWogRfbkijB/xxwB6WN\r\n7RunOZk1JfdyQT9AeOX1xGlmSzlX4xi935esaJJwiEm5be1aRn705TI2F09J\r\nyAINn0lDDXz4JNexRFE7ZQ6Idn+w55Yqg329YWUICqYUbS0NsunzQ3XuHu/O\r\nXsZEM935JDXgWz7ZQJeZTkLUWNnaaNUPQnreKN/mIrNu1WUlNql8fvFkKsBf\r\nX9rfwxPOUU9JAyS7lCLrUVJsHnIfyz2G/nxJUivnHdmUzh+Q3liAscRihr5k\r\nb/auQwvg8xb93jf7m1URoKu7yt3v5HS8dNtRia3gjnAOsEH7NxJKR2tWg+jA\r\nGwew8QCxkLynSw5/SnTVq0S8X9dsGLYmrPEkVjIgpzw65rLRZLt7Y63gkja5\r\n8xDAbrc1tvzSGY8oYlzAca66dmsbLXFFlJ4=\r\n=XDyc\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_2.1.1_1656069169715_0.9642075617181158"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"bind-event-listener","version":"3.0.0-beta.1","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"549B"}],"scripts":{"typescript:check":"tsc --noEmit && tsc --noEmit --project ./test/tsconfig.json","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^8.2.4","@types/jest":"^29.5.1","@types/node":"^18.16.0","expect-type":"^0.15.0","jest":"^29.5.0","jest-environment-jsdom":"^29.5.0","prettier":"^2.8.8","rimraf":"^5.0.0","size-limit":"^8.2.4","ts-expect":"^1.3.0","ts-jest":"^29.1.0","typescript":"^5.0.4"},"dependencies":{},"readme":"# bind-event-listener\n\n[![npm](https://img.shields.io/npm/v/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n![types](https://img.shields.io/badge/types-typescript-blueviolet)\n[![minzip](https://img.shields.io/bundlephobia/minzip/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n\n> A utility to make binding and (**especially**) unbinding DOM events easier.\n> I seem to write this again with every new project, so I made it a library\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: function onClick(event) {},\n});\n\n// when you are all done:\nunbind();\n```\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: function onClick(event) {},\n    options: { capture: true },\n  },\n  {\n    type: 'mouseover',\n    listener: function onMouseOver(event) {},\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n## Rationale\n\nWhen using `addEventListener()`, **correctly unbinding** events with `removeEventListener()` can be tricky.\n\n1. You need to remember to call `removeEventListener` (it can be easy to forget!)\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener('click', onClick, options);\n\ntarget.removeEventListener('click', onClick, options);\n```\n\n</details>\n\n2. You need to pass in the same listener _reference_ to `removeEventListener`\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n\n// Even those the functions look the same, they don't have the same reference.\n// The original onClick is not unbound!\ntarget.removeEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n```\n\n```ts\n// Inline arrow functions can never be unbound because you have lost the reference!\ntarget.addEventListener('click', () => console.log('i will never unbind'), options);\ntarget.removeEventListener('click', () => console.log('i will never unbind'), options);\n```\n\n</details>\n\n3. You need to pass in the same `capture` value option\n\n<details>\n<summary>Example</summary>\n\n```ts\n// add a listener: AddEventListenerOptions format\ntarget.addEventListener('click', onClick, { capture: true });\n\n// not unbound: no capture value\ntarget.removeEventListener('click', onClick);\n\n// not unbound: different capture value\ntarget.removeEventListener('click', onClick, { capture: false });\n\n// successfully unbound: same capture value\ntarget.removeEventListener('click', onClick, { capture: true });\n// this would also unbind (different notation)\ntarget.removeEventListener('click', onClick, true /* shorthand for { capture: true } */);\n```\n\n```ts\n// add a listener: boolean capture format\ntarget.addEventListener('click', onClick, true /* shorthand for { capture: true } */);\n\n// not unbound: no capture value\ntarget.addEventListener('click', onClick);\n// not unbound: different capture value\ntarget.addEventListener('click', onClick, false);\n\n// successfully unbound: same capture value\ntarget.addEventListener('click', onClick, true);\n// this would also unbind (different notation)\ntarget.addEventListener('click', onClick, { capture: true });\n```\n\n</details>\n\n**`bind-event-listener` solves these problems**\n\n1. When you bind an event (or events with `bindAll`) you get back a simple `unbind` function\n2. The unbind function ensures the same listener _reference_ is passed to `removeEventListener`\n3. The unbind function ensures that whatever `capture` value is used with `addEventListener` is used with `removeEventListener`\n\nYou will find an even fuller rationale for this project in my course: [\"The Ultimate Guide for Understanding DOM Events\"](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n[![share-card-dom-events](https://user-images.githubusercontent.com/2182637/120963089-52a45f00-c7a4-11eb-82a7-a04c2731999a.jpg)](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n## Usage\n\n### `bind`: basic\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when your are all done:\nunbind();\n```\n\n### `bind`: with options\n\n```ts\nimport { bind } from 'bind-event-listener';\n\nconst unbind = bind(button, {\n  type: 'click',\n  listener: onClick,\n  options: { capture: true, passive: false },\n});\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: basic\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: with options\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { passive: true },\n  },\n  // default options that are applied to all bindings\n  { capture: false },\n]);\n\n// when you are all done:\nunbind();\n```\n\nWhen using `defaultOptions` for `bindAll`, the `defaultOptions` are merged with the `options` on each binding. Options on the individual bindings will take precedent. You can think of it like this:\n\n```ts\nconst merged: AddEventListenerOptions = {\n  ...defaultOptions,\n  ...options,\n};\n```\n\n> Note: it is a little bit more complicated than just object spreading as the library will also behave correctly when passing in a `boolean` capture argument. An options value can be a boolean `{ options: true }` which is shorthand for `{ options: {capture: true } }`\n\n## Types\n\nThanks to the great work by [@Ayub-Begimkulov](https://github.com/Ayub-Begimkulov) `bind-event-listener` has fantastic TypeScript types\n\n> ⚠️ TypeScript 4.1+ is required\n\n```ts\nimport invariant from 'tiny-invariant';\nimport { bind } from 'bind-event-listener';\n\nbind(window, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `window` (the event target that the event listener is added to)\n  },\n});\n\nconst button = document.querySelector('button');\ninvariant(button instanceof HTMLElement);\n\nbind(button, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `button` (the event target that the event listener is added to)\n  },\n});\n\nconst object = {\n  handleEvent: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `object` (the event listener object that the event listener is added to)\n  },\n};\n\nbind(button, {\n  type: 'click',\n  function: object,\n});\n```\n\n## Recipe: [`react`](https://reactjs.org/) effect\n\nYou can return a [cleanup function](https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect) from [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) (or [`useLayoutEffect`](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)). `bind-event-listener` makes this super convenient because you can just return the unbind function from your effect.\n\n```ts\nimport React, { useState, useEffect } from 'react';\nimport { bind } from 'bind-event-listener';\n\nexport default function App() {\n  const [clickCount, onClick] = useState(0);\n\n  useEffect(() => {\n    const unbind = bind(window, {\n      type: 'click',\n      listener: () => onClick((value) => value + 1),\n    });\n\n    return unbind;\n  }, []);\n\n  return <div>Window clicks: {clickCount}</div>;\n}\n```\n\n> You can play with this [example on codesandbox](https://codesandbox.io/s/bind-event-listener-useeffect-mnfi3)\n\n## Types\n\n```ts\nfunction bind(target: EventTarget, binding: Binding): UnbindFn;\n\nfunction bindAll(\n  target: EventTarget,\n  bindings: Binding[],\n  // AddEventListenerOptions is a built in TypeScript type\n  sharedOptions?: boolean | AddEventListenerOptions,\n): UnbindFn;\n\ntype Binding = {\n  type: string;\n  // EventListenerOrEventListenerObject is a built in TypeScript type\n  listener: EventListenerOrEventListenerObject;\n  options?: boolean | AddEventListenerOptions;\n};\n\ntype UnbindFn = () => void;\n```\n\n> Typescript built in DOM types: [raw view](https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.dom.d.ts), [pretty view](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts) (warning: pretty view seems to crash Github!)\n\n## Cheers 👋\n\nBrought to you by [@alexandereardon](https://twitter.com/alexandereardon)\n","readmeFilename":"README.md","gitHead":"6e8b16f511722623a6fc8102af23b5a32ed1f52a","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@3.0.0-beta.1","_nodeVersion":"18.13.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-MaGzCng1RnlOzNwq3Rr/9/Ab1gRodPV6by46M53/FOZ5ambuDH4Qs8KcJH1OQ6rUYcMxUgz5Oc4pyIwDbMEW2A==","shasum":"9d7d7a907a1d7a05d15b2fd620a780b7bd06d34a","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-3.0.0-beta.1.tgz","fileCount":15,"unpackedSize":19753,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCwh+b6TH4vRBJZDtXMXJ1J6siYScrP4DpgYyVnAgEyCwIgY6BZcK0Ub4bOw+yShexdZxXMQGfof15gXZMou+TYBBE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSL99ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoccg//TxoWylzTmAAuMOZUcm9euBQkjW/DaGI6qIvH9uepjVUZhRc+\r\nkS3OkWpZ2EtEu/jwKSYertQMbrLY8uxTncav/pvUaPEPDY6JCB+ae/lo8hY0\r\neCoNcAHDGb1We1jigFvGoI/07xVwZmePAg1Y04CfauGdQx+kAQnt+8vtiOOi\r\nOPmwH1Lvvao4BX7GKS133ZLyCCZALSvy3k5KGd84ic31N4Q3fIM6J42YCloC\r\nrwc1mRGQD2aFEm1ffbq5CUJrB/3aLasSXpC093QlrMa6TYLrAfxKt0az6UnU\r\nG5PHIzQnGqr4xqS0ceMtvg7FdKCYrYZErjVysgZsF8Y/qJM6Z7dQurnDQ+YO\r\nNw0Df/0Nq4Lt3lWu3iijvBtsPh0OZ60Yi/2K+5DT6j174t/UASQCXacufZ1u\r\n2ew2wb/l6PF9SmMwYOav2XOZRNklRQPiLIuvp3g9P0nAOnT1w9kaVyrd7EI9\r\nZz/PyydZ9VKxZQX+0x/0MTVyxqt0Hx7ZgEbrbIdDTASht4nExMyiz0HTW7UH\r\nDJOimaF9dlL9uArPkQ5zempZFrpPtQVH50OMsP+DkmSKPPtTCCY0mWaH51MO\r\nkku+ZgvlbDRJ0Y/vOn1kf8PYGCaONMa/q5sdrBIrq9P2cHkQPM1Fxw1/kKAA\r\nJKsQ37Krwdxvlk2UDf+G7HsofCPmAwnD2d0=\r\n=GJsF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_3.0.0-beta.1_1682489213327_0.6365153111843558"},"_hasShrinkwrap":false},"3.0.0":{"name":"bind-event-listener","version":"3.0.0","private":false,"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"keywords":["dom","ui","event listener","event handler"],"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"config":{"prettier_target":"src/**/*.{ts,js,jsx,md,json} test/**/*.{ts,js,jsx,md,json}"},"size-limit":[{"path":"dist/index.js","limit":"549B"}],"scripts":{"typescript:check":"tsc --noEmit && tsc --noEmit --project ./test/tsconfig.json","typescript:watch":"tsc --watch","typescript:build":"tsc","prettier:check":"prettier --debug-check $npm_package_config_prettier_target","prettier:write":"prettier --write $npm_package_config_prettier_target","validate":"yarn typescript:check && yarn prettier:check","test":"yarn jest","size:check":"size-limit","build:clean":"rimraf dist","build":"yarn build:clean && yarn typescript:build","prepublishOnly":"yarn build"},"devDependencies":{"@size-limit/preset-small-lib":"^8.2.4","@types/jest":"^29.5.1","@types/node":"^18.16.0","expect-type":"^0.15.0","jest":"^29.5.0","jest-environment-jsdom":"^29.5.0","prettier":"^2.8.8","rimraf":"^5.0.0","size-limit":"^8.2.4","ts-expect":"^1.3.0","ts-jest":"^29.1.0","typescript":"^5.0.4"},"dependencies":{},"gitHead":"6cf23e4632d9c9112447a7530d7c8a43791cfcfa","bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"homepage":"https://github.com/alexreardon/bind-event-listener#readme","_id":"bind-event-listener@3.0.0","_nodeVersion":"18.13.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==","shasum":"c90f9a7fcb65cac21045f810c20ef7e647a74921","tarball":"https://registry.npmjs.org/bind-event-listener/-/bind-event-listener-3.0.0.tgz","fileCount":15,"unpackedSize":20811,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDLM9JVR2EwnsO+Gd1I5iR3+POnSo3vdCEgwn2vlEJ1yAIgX1Z4yu51reQaF4bLDFph1PET+g4o6qaKLJmpPtmokkc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSa/qACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqtDA/9H9xXe39tcduk0VcQdsIBFV6NC/XFQFhF9Zf3yPHKsXZqI6+l\r\n58WQPsXyfbfmoyJT6OnBHSAQaGhMpchhs1rBn2x90SRmal0s7n6320qFka8/\r\nRbvp2p19UJ+yZH/VINADms2FDGPLsm10Lib5fOQGf/Wb2bF1fQjHeJjHByXC\r\nhY0+vjRZa/BnnrEQfeHCTk+0d6d39xpEzezz07yN8sSrvCCJslEtSD05uRKV\r\nTbDt6CQxaXNzEo8pKYXtXDcwMFis0XjR2mS/cuWCeQ7mim+HPeWbLNb654ky\r\nJWtFYMFAiUwEZFYXgXbyst6dL4EHWB2TAy/cvgoUwskbAHEMauFzQ3RF5NCr\r\nAKl95An7u3alvDAX9AvY+vrbR59wzdMWv+x7zzKpYwh71cMjNKvRTraHQCVB\r\nZrnZBZShV1KfBAu6YdowOYlTBZqtZ/ycXJ5xuVRfT9xHbDtV2BW0H+N4E/3k\r\nMOodFrgZfoxK9gxu4WkWeoOHTZw57lvYyyyHpkvSqr5rTd0gebQHtYABv6BU\r\nU2sh+f1mKOmaRMrDswrWvqYK7QdBhr6wxqh5ZSZM5m4/uoyss8tklCqbFIWS\r\nzHh0FBR5xp99T3+BlMk40aji9wM9/35/IO1TVRGnTgff23uz3x9ho/fyiGU8\r\nCwqm77TLspmOdZC2Vg0e5MxLuEvIO7/sB78=\r\n=vv65\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"alexreardon","email":"alexreardon@gmail.com"},"directories":{},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/bind-event-listener_3.0.0_1682550762786_0.8740849609668835"},"_hasShrinkwrap":false}},"time":{"created":"2020-06-14T22:59:10.342Z","0.1.0":"2020-06-14T22:59:10.484Z","modified":"2023-04-26T23:12:43.074Z","0.2.0":"2020-06-14T23:02:53.313Z","0.3.0":"2020-07-01T04:12:54.832Z","1.0.0":"2020-07-13T10:05:20.770Z","1.0.0-alpha.1":"2020-07-14T05:29:06.719Z","1.0.1-alpha.1":"2020-07-14T05:30:19.418Z","1.0.1":"2020-07-14T05:48:23.636Z","1.0.2":"2020-07-17T03:17:06.355Z","2.0.0":"2021-06-07T05:40:38.408Z","2.1.0-beta.0":"2022-05-04T05:34:06.027Z","2.1.0":"2022-05-05T05:22:38.998Z","2.1.1":"2022-06-24T11:12:49.907Z","3.0.0-beta.1":"2023-04-26T06:06:53.503Z","3.0.0":"2023-04-26T23:12:42.958Z"},"maintainers":[{"name":"alexreardon","email":"alexreardon@gmail.com"}],"description":"Making binding and unbinding DOM events easier","author":{"name":"Alex Reardon","email":"alexreardon@gmail.com"},"license":"MIT","readme":"# bind-event-listener\n\n[![npm](https://img.shields.io/npm/v/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n![types](https://img.shields.io/badge/types-typescript-blueviolet)\n[![minzip](https://img.shields.io/bundlephobia/minzip/bind-event-listener.svg)](https://www.npmjs.com/package/bind-event-listener)\n\nA well typed utility to make creating and removing DOM event listeners safer and more ergonomic.\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: function onClick(event) {},\n});\n\n// when you are all done:\nunbind();\n```\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: function onClick(event) {},\n    options: { capture: true },\n  },\n  {\n    type: 'mouseover',\n    listener: function onMouseOver(event) {},\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n## Rationale\n\nWhen using `addEventListener()`, **correctly unbinding** events with `removeEventListener()` can be tricky.\n\n1. You need to remember to call `removeEventListener` (it can be easy to forget!)\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener('click', onClick, options);\n\ntarget.removeEventListener('click', onClick, options);\n```\n\n</details>\n\n2. You need to pass in the same listener _reference_ to `removeEventListener`\n\n<details>\n<summary>Example</summary>\n\n```ts\ntarget.addEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n\n// Even those the functions look the same, they don't have the same reference.\n// The original onClick is not unbound!\ntarget.removeEventListener(\n  'click',\n  function onClick() {\n    console.log('clicked');\n  },\n  options,\n);\n```\n\n```ts\n// Inline arrow functions can never be unbound because you have lost the reference!\ntarget.addEventListener('click', () => console.log('i will never unbind'), options);\ntarget.removeEventListener('click', () => console.log('i will never unbind'), options);\n```\n\n</details>\n\n3. You need to pass in the same `capture` value option\n\n<details>\n<summary>Example</summary>\n\n```ts\n// add a listener: AddEventListenerOptions format\ntarget.addEventListener('click', onClick, { capture: true });\n\n// not unbound: no capture value\ntarget.removeEventListener('click', onClick);\n\n// not unbound: different capture value\ntarget.removeEventListener('click', onClick, { capture: false });\n\n// successfully unbound: same capture value\ntarget.removeEventListener('click', onClick, { capture: true });\n// this would also unbind (different notation)\ntarget.removeEventListener('click', onClick, true /* shorthand for { capture: true } */);\n```\n\n```ts\n// add a listener: boolean capture format\ntarget.addEventListener('click', onClick, true /* shorthand for { capture: true } */);\n\n// not unbound: no capture value\ntarget.addEventListener('click', onClick);\n// not unbound: different capture value\ntarget.addEventListener('click', onClick, false);\n\n// successfully unbound: same capture value\ntarget.addEventListener('click', onClick, true);\n// this would also unbind (different notation)\ntarget.addEventListener('click', onClick, { capture: true });\n```\n\n</details>\n\n**`bind-event-listener` solves these problems**\n\n1. When you bind an event (or events with `bindAll`) you get back a simple `unbind` function\n2. The unbind function ensures the same listener _reference_ is passed to `removeEventListener`\n3. The unbind function ensures that whatever `capture` value is used with `addEventListener` is used with `removeEventListener`\n\nYou will find an even fuller rationale for this project in my course: [\"The Ultimate Guide for Understanding DOM Events\"](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n[![share-card-dom-events](https://user-images.githubusercontent.com/2182637/120963089-52a45f00-c7a4-11eb-82a7-a04c2731999a.jpg)](https://egghead.io/courses/the-ultimate-guide-for-understanding-dom-events-6c0c0d23?af=2jc3e4)\n\n## Usage\n\n### `bind`: basic\n\n```ts\nimport { bind, UnbindFn } from 'bind-event-listener';\n\nconst unbind: UnbindFn = bind(button, {\n  type: 'click',\n  listener: onClick,\n});\n\n// when your are all done:\nunbind();\n```\n\n### `bind`: with options\n\n```ts\nimport { bind } from 'bind-event-listener';\n\nconst unbind = bind(button, {\n  type: 'click',\n  listener: onClick,\n  options: { capture: true, passive: false },\n});\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: basic\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n  },\n]);\n\n// when you are all done:\nunbind();\n```\n\n### `bindAll`: with options\n\n```ts\nimport { bindAll } from 'bind-event-listener';\n\nconst unbind = bindAll(button, [\n  {\n    type: 'click',\n    listener: onClick,\n    options: { passive: true },\n  },\n  // default options that are applied to all bindings\n  { capture: false },\n]);\n\n// when you are all done:\nunbind();\n```\n\nWhen using `defaultOptions` for `bindAll`, the `defaultOptions` are merged with the `options` on each binding. Options on the individual bindings will take precedent. You can think of it like this:\n\n```ts\nconst merged: AddEventListenerOptions = {\n  ...defaultOptions,\n  ...options,\n};\n```\n\n> Note: it is a little bit more complicated than just object spreading as the library will also behave correctly when passing in a `boolean` capture argument. An options value can be a boolean `{ options: true }` which is shorthand for `{ options: {capture: true } }`\n\n## Types\n\nThanks to the great work by [@Ayub-Begimkulov](https://github.com/Ayub-Begimkulov) and [@Andarist](https://github.com/Andarist) `bind-event-listener` has fantastic TypeScript types and auto complete.\n\n> ⚠️ TypeScript 4.1+ is required for types\n> ⚠️ TypeScript 5.0+ is required for event name autocompletion\n\n```ts\nimport invariant from 'tiny-invariant';\nimport { bind } from 'bind-event-listener';\n\nbind(window, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `window` (the event target that the event listener is added to)\n  },\n});\n\nconst button = document.querySelector('button');\ninvariant(button instanceof HTMLElement);\n\nbind(button, {\n  type: 'click',\n  function: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `button` (the event target that the event listener is added to)\n  },\n});\n\nconst object = {\n  handleEvent: function onClick(event) {\n    // `event` is correctly typed as a 'MouseEvent'\n    // `this` is correctly typed as `object` (the event listener object that the event listener is added to)\n  },\n};\n\nbind(button, {\n  type: 'click',\n  function: object,\n});\n```\n\n`bind` and `bindAll` accept type arguments (generics), but it is generally best to let these be inferred\n\n```ts\n// with explicit type arguments\nbind<HTMLElement, 'click'>(button, {\n  type: 'click',\n  listener: function onClick() {},\n});\n\n// ✨ types will automatically be inferred for you ✨\nbind(button, {\n  type: 'click',\n  listener: function onClick() {},\n});\n\n// with explicit type arguments\nbindAll<HTMLElement, ['click', 'keydown']>(button, [\n  {\n    type: 'click',\n    listener: function onClick() {},\n  },\n  {\n    type: 'keydown',\n    listener: function onKeyDown() {},\n  },\n]);\n\n// ✨ types will automatically be inferred for you ✨\nbindAll(button, [\n  {\n    type: 'click',\n    listener: function onClick() {},\n  },\n  {\n    type: 'keydown',\n    listener: function onKeyDown() {},\n  },\n]);\n```\n\n> Typescript built in DOM types: [raw view](https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.dom.d.ts), [pretty view](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts) (warning: pretty view seems to crash Github!)\n\n### Type helpers\n\n```ts\nimport { Binding, Listener, UnbindFn } from 'bind-event-listener';\n```\n\n`Listener`: the `function` or `object` that you provide to the `listener` property of a `Binding`\n\n```ts\nbind(button, {\n  type: 'click',\n  listener: function onClick() {}, // ← `Listener`\n});\n```\n\n`Binding`: the definition of an event binding.\n\n```ts\nbind(\n  button,\n  // ↓ `Binding`\n  {\n    type: 'click',\n    listener: function onClick() {},\n  },\n);\n```\n\n`UnbindFn`: a named type for `() => void` to make it clearer that the function will unbind the added event listener(s):\n\n```ts\nconst unbind: UnbindFn = bind(button, { type: 'click', listener: function onClick() {} });\n```\n\n## Recipe: [`react`](https://reactjs.org/) effect\n\nYou can return a [cleanup function](https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect) from [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) (or [`useLayoutEffect`](https://reactjs.org/docs/hooks-reference.html#uselayouteffect)). `bind-event-listener` makes this super convenient because you can just return the unbind function from your effect.\n\n```ts\nimport React, { useState, useEffect } from 'react';\nimport { bind } from 'bind-event-listener';\n\nexport default function App() {\n  const [clickCount, onClick] = useState(0);\n\n  useEffect(() => {\n    const unbind = bind(window, {\n      type: 'click',\n      listener: () => onClick((value) => value + 1),\n    });\n\n    return unbind;\n  }, []);\n\n  return <div>Window clicks: {clickCount}</div>;\n}\n```\n\n> You can play with this [example on codesandbox](https://codesandbox.io/s/bind-event-listener-useeffect-mnfi3)\n\n## Cheers 👋\n\nBrought to you by [@alexandereardon](https://twitter.com/alexandereardon)\n","readmeFilename":"README.md","homepage":"https://github.com/alexreardon/bind-event-listener#readme","repository":{"type":"git","url":"git+https://github.com/alexreardon/bind-event-listener.git"},"bugs":{"url":"https://github.com/alexreardon/bind-event-listener/issues"},"keywords":["dom","ui","event listener","event handler"]}