├── .github └── ISSUE_TEMPLATE │ ├── Add_hook.md │ └── Bug_report.md ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── hooks.json ├── scripts ├── .gitignore ├── analyzeSource.js ├── guessSource.js ├── package.json ├── utils.js └── yarn.lock └── site ├── .gitignore ├── README.md ├── gatsby-config.js ├── jest-preprocess.js ├── jest.config.js ├── package.json ├── src ├── components │ ├── header.js │ ├── layout.css │ └── layout.js ├── hooks.json.test.js ├── images │ └── react-hooks.png ├── pages │ ├── 404.js │ └── index.js ├── utils.js └── utils.test.js └── yarn.lock /.github/ISSUE_TEMPLATE/Add_hook.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🎣 Add hook 3 | about: If you want to add hook! 4 | --- 5 | 6 | --------------^ Click "Preview" for a nicer view! 7 | 8 | No need to ask to add hook. You can do it yourself easily. Use this [link](https://github.com/nikgraf/react-hooks/edit/master/hooks.json). 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: If something isn't working as expected 🤔. 4 | --- 5 | 6 | ## Bug Report 7 | 8 | **Current Behavior** 9 | A clear and concise description of the behavior. 10 | 11 | **Reproducible demo** 12 | Link to GitHub repository or codesandbox with a demo of the bug behavior. 13 | 14 | **Expected behavior/code** 15 | A clear and concise description of what you expected to happen (or code). 16 | 17 | **Possible Solution** 18 | 19 | 20 | 21 | **Additional context/Screenshots** 22 | Add any other context about the problem here. If applicable, add screenshots to help explain. 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - scripts/tmp 6 | - $HOME/.cache/yarn 7 | notifications: 8 | email: false 9 | node_js: 10 | - "10" 11 | 12 | script: 13 | - cd scripts 14 | - yarn 15 | - node analyzeSource.js 16 | - cd ../site 17 | - yarn 18 | - yarn test 19 | - yarn build 20 | 21 | deploy: 22 | provider: pages 23 | local-dir: site/public 24 | skip-cleanup: true 25 | github-token: $GITHUB_TOKEN 26 | keep-history: true 27 | on: 28 | branch: master 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Nik Graf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Collection of React Hooks 2 | 3 | ## Website 4 | 5 | [https://nikgraf.github.io/react-hooks/](https://nikgraf.github.io/react-hooks/) 6 | 7 | ## Planned Features 8 | 9 | - Add Type System Info e.g. TypeScript, Flow, Reason 10 | - Add information from Github and NPM 11 | -------------------------------------------------------------------------------- /hooks.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "@koale/useWorker", 4 | "tags": [ 5 | "useworker", 6 | "web worker", 7 | "background", 8 | "heavy task", 9 | "blocking UI" 10 | ], 11 | "repositoryUrl": "https://github.com/alewin/useWorker", 12 | "importStatement": "import { useWorker } from '@koale/useworker'" 13 | }, 14 | { 15 | "name": "useErrorBoundary", 16 | "tags": [ 17 | "use-error-boundary", 18 | "useErrorBoundary", 19 | "React Error Boundaries", 20 | "catch" 21 | ], 22 | "repositoryUrl": "https://github.com/JoschuaSchneider/use-error-boundary", 23 | "importStatement": "import { useErrorBoundary } from 'use-error-boundary'" 24 | }, 25 | { 26 | "name": "useSSR", 27 | "tags": [ 28 | "useSSR", 29 | "SSR", 30 | "server-side-rendering", 31 | "browser", 32 | "client", 33 | "server", 34 | "server-side", 35 | "isomorphic" 36 | ], 37 | "repositoryUrl": "https://github.com/alex-cory/use-ssr", 38 | "importStatement": "import useSSR from 'use-ssr'" 39 | }, 40 | { 41 | "name": "useComlink", 42 | "tags": [ 43 | "comlink", 44 | "webworker", 45 | "web worker", 46 | "webworkers" 47 | ], 48 | "repositoryUrl": "https://github.com/pocesar/react-use-comlink", 49 | "importStatement": "import useComlink from 'react-use-comlink';" 50 | }, 51 | { 52 | "name": "useModal", 53 | "tags": [ 54 | "React Modal", 55 | "use-modal", 56 | "modal", 57 | "modal-hook", 58 | "react-modal-hook" 59 | ], 60 | "repositoryUrl": "https://github.com/alexanderkhivrych/use-modal-hook", 61 | "importStatement": "import { useModal, ModalProvider } from 'use-modal-hook';" 62 | }, 63 | { 64 | "name": "useModal", 65 | "tags": [ 66 | "modal", 67 | "portal", 68 | "use-modal", 69 | "useModal", 70 | "react-hooks-modal-hook" 71 | ], 72 | "repositoryUrl": "https://github.com/shibe97/react-hooks-use-modal", 73 | "importStatement": "import useModal from 'react-hooks-use-modal';" 74 | }, 75 | { 76 | "name": "useHeroku", 77 | "tags": [ 78 | "heroku", 79 | "loading", 80 | "useHeroku", 81 | "get", 82 | "wakeup", 83 | "fetch" 84 | ], 85 | "repositoryUrl": "https://github.com/GainorB/react-use-heroku", 86 | "importStatement": "import useHeroku from 'react-use-heroku';" 87 | }, 88 | { 89 | "name": "usePortal", 90 | "tags": [ 91 | "React Portal", 92 | "Portal", 93 | "usePortal", 94 | "use-portal", 95 | "react-useportal", 96 | "modal", 97 | "tooltip", 98 | "dropdown" 99 | ], 100 | "repositoryUrl": "https://github.com/alex-cory/react-useportal", 101 | "importStatement": "import usePortal from 'react-useportal';" 102 | }, 103 | { 104 | "name": "useFetch", 105 | "tags": [ 106 | "React Fetch", 107 | "use-http", 108 | "http", 109 | "get", 110 | "delete", 111 | "patch", 112 | "put", 113 | "post", 114 | "react-usefetch", 115 | "fetch", 116 | "http", 117 | "request", 118 | "rest", 119 | "graphql", 120 | "loading", 121 | "usefetch", 122 | "isomorphic", 123 | "ssr", 124 | "suspense" 125 | ], 126 | "repositoryUrl": "https://github.com/alex-cory/react-usefetch", 127 | "importStatement": "import useFetch, { usePost, usePut, usePatch } from 'use-http';" 128 | }, 129 | { 130 | "name": "useState", 131 | "tags": [ 132 | "React Core", 133 | "State Management" 134 | ], 135 | "repositoryUrl": "https://github.com/facebook/react", 136 | "importStatement": "import { useState } from 'react';" 137 | }, 138 | { 139 | "name": "useReducer", 140 | "tags": [ 141 | "React Core", 142 | "State Management" 143 | ], 144 | "repositoryUrl": "https://github.com/facebook/react", 145 | "importStatement": "import { useReducer } from 'react';" 146 | }, 147 | { 148 | "name": "useEffect", 149 | "tags": [ 150 | "React Core" 151 | ], 152 | "repositoryUrl": "https://github.com/facebook/react", 153 | "importStatement": "import { useEffect } from 'react';" 154 | }, 155 | { 156 | "name": "useLayoutEffect", 157 | "tags": [ 158 | "React Core" 159 | ], 160 | "repositoryUrl": "https://github.com/facebook/react", 161 | "importStatement": "import { useLayoutEffect } from 'react';" 162 | }, 163 | { 164 | "name": "useContext", 165 | "tags": [ 166 | "React Core" 167 | ], 168 | "repositoryUrl": "https://github.com/facebook/react", 169 | "importStatement": "import { useContext } from 'react';" 170 | }, 171 | { 172 | "name": "useMemo", 173 | "tags": [ 174 | "React Core" 175 | ], 176 | "repositoryUrl": "https://github.com/facebook/react", 177 | "importStatement": "import { useMemo } from 'react';" 178 | }, 179 | { 180 | "name": "useInView", 181 | "tags": [ 182 | "scroll" 183 | ], 184 | "repositoryUrl": "https://github.com/elinadenfina/useinview", 185 | "importStatement": "import useInView from 'use-in-view';", 186 | "sourceUrl": "https://github.com/elinadenfina/useinview/raw/master/index.js" 187 | }, 188 | { 189 | "name": "useRef", 190 | "tags": [ 191 | "React Core" 192 | ], 193 | "repositoryUrl": "https://github.com/facebook/react", 194 | "importStatement": "import { useRef } from 'react';" 195 | }, 196 | { 197 | "name": "useMutationEffect", 198 | "tags": [ 199 | "React Core" 200 | ], 201 | "repositoryUrl": "https://github.com/facebook/react", 202 | "importStatement": "import { useMutationEffect } from 'react';" 203 | }, 204 | { 205 | "name": "useImperativeMethods", 206 | "tags": [ 207 | "React Core" 208 | ], 209 | "repositoryUrl": "https://github.com/facebook/react", 210 | "importStatement": "import { useImperativeMethods } from 'react';" 211 | }, 212 | { 213 | "name": "useCallback", 214 | "tags": [ 215 | "React Core" 216 | ], 217 | "repositoryUrl": "https://github.com/facebook/react", 218 | "importStatement": "import { useCallback } from 'react';" 219 | }, 220 | { 221 | "name": "useForm", 222 | "tags": [ 223 | "Form" 224 | ], 225 | "repositoryUrl": "https://github.com/revelcw/react-hooks-helper", 226 | "importStatement": "import { useForm } from 'react-hooks-helper';", 227 | "sourceUrl": "https://github.com/revelcw/react-hooks-helper/raw/master/src/useForm.js" 228 | }, 229 | { 230 | "name": "useStep", 231 | "tags": [ 232 | "Step", 233 | "Wizard" 234 | ], 235 | "repositoryUrl": "https://github.com/revelcw/react-hooks-helper", 236 | "importStatement": "import { useStep } from 'react-hooks-helper';", 237 | "sourceUrl": "https://github.com/revelcw/react-hooks-helper/raw/master/src/useStep.js" 238 | }, 239 | { 240 | "name": "useInterval", 241 | "tags": [ 242 | "Timer", 243 | "Interval" 244 | ], 245 | "repositoryUrl": "https://github.com/donavon/use-interval", 246 | "importStatement": "import useInterval from '@use-it/interval';", 247 | "sourceUrl": "https://github.com/donavon/use-interval/raw/master/src/index.js" 248 | }, 249 | { 250 | "name": "useEventListener", 251 | "tags": [ 252 | "Events" 253 | ], 254 | "repositoryUrl": "https://github.com/donavon/use-event-listener", 255 | "importStatement": "import useEventListener from '@use-it/event-listener';", 256 | "sourceUrl": "https://github.com/donavon/use-event-listener/raw/master/src/index.js" 257 | }, 258 | { 259 | "name": "useDarkMode", 260 | "tags": [ 261 | "DarkMode", 262 | "Theme" 263 | ], 264 | "repositoryUrl": "https://github.com/donavon/use-dark-mode", 265 | "importStatement": "import useDarkMode from 'use-dark-mode';", 266 | "sourceUrl": "https://github.com/donavon/use-dark-mode/raw/master/src/index.js" 267 | }, 268 | { 269 | "name": "usePersistedState", 270 | "tags": [ 271 | "Persistence", 272 | "LocalStorage" 273 | ], 274 | "repositoryUrl": "https://github.com/donavon/use-persisted-state", 275 | "importStatement": "import createPersistedState from 'use-persisted-state';", 276 | "sourceUrl": "https://github.com/donavon/use-persisted-state/raw/master/src/usePersistedState.js" 277 | }, 278 | { 279 | "name": "useQrCode", 280 | "tags": [ 281 | "QRCode" 282 | ], 283 | "repositoryUrl": "https://github.com/alexanderson1993/react-qrcode-hook", 284 | "importStatement": "import useQrCode from 'react-qrcode-hook';" 285 | }, 286 | { 287 | "name": "useImmer", 288 | "tags": [ 289 | "State Management" 290 | ], 291 | "repositoryUrl": "https://github.com/mweststrate/use-immer", 292 | "importStatement": "import { useImmer } from 'use-immer';", 293 | "sourceUrl": "https://github.com/mweststrate/use-immer/raw/master/index.js" 294 | }, 295 | { 296 | "name": "useImmerReducer", 297 | "tags": [ 298 | "State Management" 299 | ], 300 | "repositoryUrl": "https://github.com/mweststrate/use-immer", 301 | "importStatement": "import { useImmerReducer } from 'use-immer';", 302 | "sourceUrl": "https://github.com/mweststrate/use-immer/raw/master/index.js" 303 | }, 304 | { 305 | "name": "useSpring", 306 | "tags": [ 307 | "Animation" 308 | ], 309 | "repositoryUrl": "https://github.com/drcmda/react-spring", 310 | "importStatement": "import { useSpring } from 'react-spring';", 311 | "sourceUrl": "https://github.com/react-spring/react-spring/raw/master/src/useSpring.js" 312 | }, 313 | { 314 | "name": "useSprings", 315 | "tags": [ 316 | "Animation" 317 | ], 318 | "repositoryUrl": "https://github.com/drcmda/react-spring", 319 | "importStatement": "import { useSprings } from 'react-spring';", 320 | "sourceUrl": "https://github.com/react-spring/react-spring/raw/master/src/useSprings.js" 321 | }, 322 | { 323 | "name": "useChain", 324 | "tags": [ 325 | "Animation" 326 | ], 327 | "repositoryUrl": "https://github.com/drcmda/react-spring", 328 | "importStatement": "import { useChain } from 'react-spring';", 329 | "sourceUrl": "https://github.com/react-spring/react-spring/raw/master/src/useChain.js" 330 | }, 331 | { 332 | "name": "useTrail", 333 | "tags": [ 334 | "Animation" 335 | ], 336 | "repositoryUrl": "https://github.com/drcmda/react-spring", 337 | "importStatement": "import { useTrail } from 'react-spring';", 338 | "sourceUrl": "https://github.com/react-spring/react-spring/raw/master/src/useTrail.js" 339 | }, 340 | { 341 | "name": "useTransition", 342 | "tags": [ 343 | "Animation" 344 | ], 345 | "repositoryUrl": "https://github.com/drcmda/react-spring", 346 | "importStatement": "import { useTransition } from 'react-spring';", 347 | "sourceUrl": "https://github.com/react-spring/react-spring/raw/master/src/useTransition.js" 348 | }, 349 | { 350 | "name": "useWindowSize", 351 | "tags": [ 352 | "Layout" 353 | ], 354 | "repositoryUrl": "https://github.com/rehooks/window-size", 355 | "importStatement": "import useWindowSize from '@rehooks/window-size';" 356 | }, 357 | { 358 | "name": "useInputValue", 359 | "tags": [ 360 | "State Management" 361 | ], 362 | "repositoryUrl": "https://github.com/rehooks/input-value", 363 | "importStatement": "import useInputValue from '@rehooks/input-value';" 364 | }, 365 | { 366 | "name": "useDocumentVisibility", 367 | "tags": [ 368 | "Layout" 369 | ], 370 | "repositoryUrl": "https://github.com/rehooks/document-visibility", 371 | "importStatement": "import useDocumentVisibility from '@rehooks/document-visibility';" 372 | }, 373 | { 374 | "name": "useComponentSize", 375 | "tags": [ 376 | "Layout" 377 | ], 378 | "repositoryUrl": "https://github.com/rehooks/component-size", 379 | "importStatement": "import useComponentSize from '@rehooks/component-size';" 380 | }, 381 | { 382 | "name": "useDocumentTitle", 383 | "tags": [], 384 | "repositoryUrl": "https://github.com/rehooks/document-title", 385 | "importStatement": "import useDocumentTitle from '@rehooks/document-title';" 386 | }, 387 | { 388 | "name": "useNetworkStatus", 389 | "tags": [ 390 | "Network" 391 | ], 392 | "repositoryUrl": "https://github.com/rehooks/network-status", 393 | "importStatement": "import useNetworkStatus from '@rehooks/network-status';" 394 | }, 395 | { 396 | "name": "useOnlineStatus", 397 | "tags": [ 398 | "Network" 399 | ], 400 | "repositoryUrl": "https://github.com/rehooks/online-status", 401 | "importStatement": "import useOnlineStatus from '@rehooks/online-status';" 402 | }, 403 | { 404 | "name": "useLocalStorage", 405 | "tags": [], 406 | "repositoryUrl": "https://github.com/rehooks/local-storage", 407 | "importStatement": "import useLocalStorage from '@rehooks/local-storage';" 408 | }, 409 | { 410 | "name": "useWindowScrollPosition", 411 | "tags": [ 412 | "Layout" 413 | ], 414 | "repositoryUrl": "https://github.com/rehooks/window-scroll-position", 415 | "importStatement": "import useWindowScrollPosition from '@rehooks/window-scroll-position';" 416 | }, 417 | { 418 | "name": "useDeviceMotion", 419 | "tags": [], 420 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 421 | "importStatement": "import useDeviceMotion from 'the-platform';", 422 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useDeviceMotion.tsx" 423 | }, 424 | { 425 | "name": "useDeviceOrientation", 426 | "tags": [], 427 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 428 | "importStatement": "import useDeviceOrientation from 'the-platform';", 429 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useDeviceOrientation.tsx" 430 | }, 431 | { 432 | "name": "useGeoPosition", 433 | "tags": [], 434 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 435 | "importStatement": "import useGeoPosition from 'the-platform';", 436 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useGeoPosition.tsx" 437 | }, 438 | { 439 | "name": "useNetworkStatus", 440 | "tags": [ 441 | "Network" 442 | ], 443 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 444 | "importStatement": "import useNetworkStatus from 'the-platform';", 445 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useNetworkStatus.tsx" 446 | }, 447 | { 448 | "name": "useMedia", 449 | "tags": [], 450 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 451 | "importStatement": "import useMedia from 'the-platform';", 452 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useMedia.tsx" 453 | }, 454 | { 455 | "name": "useScript", 456 | "tags": [], 457 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 458 | "importStatement": "import useScript from 'the-platform';" 459 | }, 460 | { 461 | "name": "useStylesheet", 462 | "tags": [], 463 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 464 | "importStatement": "import useStylesheet from 'the-platform';" 465 | }, 466 | { 467 | "name": "useWindowScrollPosition", 468 | "tags": [], 469 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 470 | "importStatement": "import useWindowScrollPosition from 'the-platform';", 471 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useWindowScrollPosition.tsx" 472 | }, 473 | { 474 | "name": "useWindowSize", 475 | "tags": [ 476 | "Layout" 477 | ], 478 | "repositoryUrl": "https://github.com/palmerhq/the-platform", 479 | "importStatement": "import useWindowSize from 'the-platform';", 480 | "sourceUrl": "https://github.com/palmerhq/the-platform/raw/master/src/useWindowSize.tsx" 481 | }, 482 | { 483 | "name": "useStateful", 484 | "tags": [ 485 | "State Management" 486 | ], 487 | "repositoryUrl": "https://github.com/kitze/react-hanger", 488 | "importStatement": "import { useStateful } from 'react-hanger';", 489 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 490 | }, 491 | { 492 | "name": "useOnMount", 493 | "tags": [], 494 | "repositoryUrl": "https://github.com/kitze/react-hanger", 495 | "importStatement": "import { useOnMount } from 'react-hanger';", 496 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 497 | }, 498 | { 499 | "name": "useOnUnmount", 500 | "tags": [], 501 | "repositoryUrl": "https://github.com/kitze/react-hanger", 502 | "importStatement": "import { useOnUnmount } from 'react-hanger';", 503 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 504 | }, 505 | { 506 | "name": "useLifecycleHooks", 507 | "tags": [], 508 | "repositoryUrl": "https://github.com/kitze/react-hanger", 509 | "importStatement": "import { useLifecycleHooks } from 'react-hanger';", 510 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 511 | }, 512 | { 513 | "name": "useBoolean", 514 | "tags": [ 515 | "State Management" 516 | ], 517 | "repositoryUrl": "https://github.com/kitze/react-hanger", 518 | "importStatement": "import { useBoolean } from 'react-hanger';", 519 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 520 | }, 521 | { 522 | "name": "useNumber", 523 | "tags": [ 524 | "State Management" 525 | ], 526 | "repositoryUrl": "https://github.com/kitze/react-hanger", 527 | "importStatement": "import { useNumber } from 'react-hanger';", 528 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 529 | }, 530 | { 531 | "name": "useInput", 532 | "tags": [ 533 | "State Management" 534 | ], 535 | "repositoryUrl": "https://github.com/kitze/react-hanger", 536 | "importStatement": "import { useInput } from 'react-hanger';", 537 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 538 | }, 539 | { 540 | "name": "useIntercom", 541 | "tags": [], 542 | "repositoryUrl": "https://github.com/krvajal/use-intercom-hook", 543 | "importStatement": "import useIntercom from 'use-intercom-hook';" 544 | }, 545 | { 546 | "name": "useArray", 547 | "tags": [ 548 | "State Management" 549 | ], 550 | "repositoryUrl": "https://github.com/kitze/react-hanger", 551 | "importStatement": "import { useArray } from 'react-hanger';", 552 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 553 | }, 554 | { 555 | "name": "useSetState", 556 | "tags": [ 557 | "State Management" 558 | ], 559 | "repositoryUrl": "https://github.com/kitze/react-hanger", 560 | "importStatement": "import { useSetState } from 'react-hanger';", 561 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 562 | }, 563 | { 564 | "name": "usePrevious", 565 | "tags": [ 566 | "State Management" 567 | ], 568 | "repositoryUrl": "https://github.com/kitze/react-hanger", 569 | "importStatement": "import { usePrevious } from 'react-hanger';", 570 | "sourceUrl": "https://github.com/kitze/react-hanger/raw/master/src/index.js" 571 | }, 572 | { 573 | "name": "useToggle", 574 | "tags": [ 575 | "State Management" 576 | ], 577 | "repositoryUrl": "https://github.com/kalcifer/react-powerhooks", 578 | "importStatement": "import { useToggle } from 'react-powerhooks';" 579 | }, 580 | { 581 | "name": "useActive", 582 | "tags": [], 583 | "repositoryUrl": "https://github.com/kalcifer/react-powerhooks", 584 | "importStatement": "import { useActive } from 'react-powerhooks';" 585 | }, 586 | { 587 | "name": "useInterval", 588 | "tags": [ 589 | "Timing" 590 | ], 591 | "repositoryUrl": "https://github.com/kalcifer/react-powerhooks", 592 | "importStatement": "import { useInterval } from 'react-powerhooks';" 593 | }, 594 | { 595 | "name": "useBattery", 596 | "tags": [ 597 | "Sensor", 598 | "Web API", 599 | "Battery" 600 | ], 601 | "repositoryUrl": "https://github.com/streamich/react-use", 602 | "importStatement": "import { useBattery } from 'react-use';", 603 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useBattery.ts" 604 | }, 605 | { 606 | "name": "useMouse", 607 | "tags": [ 608 | "Sensor", 609 | "Mouse" 610 | ], 611 | "repositoryUrl": "https://github.com/streamich/react-use", 612 | "importStatement": "import { useMouse } from 'react-use';", 613 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMouse.ts" 614 | }, 615 | { 616 | "name": "useMouseHovered", 617 | "tags": [ 618 | "Sensor", 619 | "Mouse" 620 | ], 621 | "repositoryUrl": "https://github.com/streamich/react-use", 622 | "importStatement": "import { useMouseHovered } from 'react-use';", 623 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMouseHovered.ts" 624 | }, 625 | { 626 | "name": "useClickAway", 627 | "tags": [ 628 | "UI" 629 | ], 630 | "repositoryUrl": "https://github.com/streamich/react-use", 631 | "importStatement": "import { useClickAway } from 'react-use';", 632 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useClickAway.ts" 633 | }, 634 | { 635 | "name": "usePageLeave", 636 | "tags": [ 637 | "Sensor" 638 | ], 639 | "repositoryUrl": "https://github.com/streamich/react-use", 640 | "importStatement": "import { usePageLeave } from 'react-use';", 641 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/usePageLeave.ts" 642 | }, 643 | { 644 | "name": "useLockBodyScroll", 645 | "tags": [ 646 | "Side-effect", 647 | "Scroll", 648 | "UI" 649 | ], 650 | "repositoryUrl": "https://github.com/streamich/react-use", 651 | "importStatement": "import { useLockBodyScroll } from 'react-use';", 652 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useLockBodyScroll.ts" 653 | }, 654 | { 655 | "name": "useScroll", 656 | "tags": [ 657 | "Sensor", 658 | "Scroll" 659 | ], 660 | "repositoryUrl": "https://github.com/streamich/react-use", 661 | "importStatement": "import { useScroll } from 'react-use';", 662 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useScroll.ts" 663 | }, 664 | { 665 | "name": "useScrollData", 666 | "tags": [ 667 | "Window", 668 | "UI", 669 | "Scroll" 670 | ], 671 | "repositoryUrl": "https://github.com/dejorrit/scroll-data-hook", 672 | "importStatement": "import { useScrollData } from 'scroll-data-hook';", 673 | "sourceUrl": "https://github.com/dejorrit/scroll-data-hook/raw/master/src/index.tsx" 674 | }, 675 | { 676 | "name": "useFullscreen", 677 | "tags": [ 678 | "Web API", 679 | "UI", 680 | "Fullscreen" 681 | ], 682 | "repositoryUrl": "https://github.com/streamich/react-use", 683 | "importStatement": "import { useFullscreen } from 'react-use';", 684 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useFullscreen.ts" 685 | }, 686 | { 687 | "name": "useWindowScroll", 688 | "tags": [ 689 | "Sensor", 690 | "Web API", 691 | "UI", 692 | "Window", 693 | "Scroll" 694 | ], 695 | "repositoryUrl": "https://github.com/streamich/react-use", 696 | "importStatement": "import { useWindowScroll } from 'react-use';", 697 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useWindowScroll.ts" 698 | }, 699 | { 700 | "name": "useThrottle", 701 | "tags": [ 702 | "Throttle" 703 | ], 704 | "repositoryUrl": "https://github.com/streamich/react-use", 705 | "importStatement": "import { useThrottle } from 'react-use';", 706 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useThrottle.ts" 707 | }, 708 | { 709 | "name": "useThrottleFn", 710 | "tags": [ 711 | "Throttle" 712 | ], 713 | "repositoryUrl": "https://github.com/streamich/react-use", 714 | "importStatement": "import { useThrottleFn } from 'react-use';", 715 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useThrottleFn.ts" 716 | }, 717 | { 718 | "name": "useGeolocation", 719 | "tags": [ 720 | "Sensor", 721 | "Web API", 722 | "Geo", 723 | "Location" 724 | ], 725 | "repositoryUrl": "https://github.com/streamich/react-use", 726 | "importStatement": "import { useGeolocation } from 'react-use';", 727 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useGeolocation.ts" 728 | }, 729 | { 730 | "name": "useHover", 731 | "tags": [ 732 | "Sensor", 733 | "UI", 734 | "Mouse", 735 | "Hover" 736 | ], 737 | "repositoryUrl": "https://github.com/streamich/react-use", 738 | "importStatement": "import { useHover } from 'react-use';", 739 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useHover.ts" 740 | }, 741 | { 742 | "name": "useHoverDirty", 743 | "tags": [ 744 | "Sensor", 745 | "UI", 746 | "Mouse", 747 | "Hover" 748 | ], 749 | "repositoryUrl": "https://github.com/streamich/react-use", 750 | "importStatement": "import { useHoverDirty } from 'react-use';", 751 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useHoverDirty.ts" 752 | }, 753 | { 754 | "name": "useKey", 755 | "tags": [ 756 | "Sensor", 757 | "Event", 758 | "Keyboard" 759 | ], 760 | "repositoryUrl": "https://github.com/streamich/react-use", 761 | "importStatement": "import { useKey } from 'react-use';", 762 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useKey.ts" 763 | }, 764 | { 765 | "name": "useKeyPress", 766 | "tags": [ 767 | "Sensor", 768 | "Event", 769 | "Keyboard" 770 | ], 771 | "repositoryUrl": "https://github.com/streamich/react-use", 772 | "importStatement": "import { useKeyPress } from 'react-use';", 773 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useKeyPress.ts" 774 | }, 775 | { 776 | "name": "useKeyPressEvent", 777 | "tags": [ 778 | "Sensor", 779 | "Event", 780 | "Keyboard" 781 | ], 782 | "repositoryUrl": "https://github.com/streamich/react-use", 783 | "importStatement": "import { useKeyPressEvent } from 'react-use';", 784 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useKeyPressEvent.ts" 785 | }, 786 | { 787 | "name": "useKeyboardJs", 788 | "tags": [ 789 | "Sensor", 790 | "Event", 791 | "Keyboard" 792 | ], 793 | "repositoryUrl": "https://github.com/streamich/react-use", 794 | "importStatement": "import { useKeyboardJs } from 'react-use';", 795 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useKeyboardJs.ts" 796 | }, 797 | { 798 | "name": "useIdle", 799 | "tags": [ 800 | "Sensor", 801 | "Web API", 802 | "UI" 803 | ], 804 | "repositoryUrl": "https://github.com/streamich/react-use", 805 | "importStatement": "import { useIdle } from 'react-use';", 806 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useIdle.ts" 807 | }, 808 | { 809 | "name": "useLocation", 810 | "tags": [ 811 | "Sensor", 812 | "Web API", 813 | "Location" 814 | ], 815 | "repositoryUrl": "https://github.com/streamich/react-use", 816 | "importStatement": "import { useLocation } from 'react-use';", 817 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useLocation.ts" 818 | }, 819 | { 820 | "name": "useMedia", 821 | "tags": [ 822 | "Sensor", 823 | "Web API", 824 | "Media-Query", 825 | "CSS" 826 | ], 827 | "repositoryUrl": "https://github.com/streamich/react-use", 828 | "importStatement": "import { useMedia } from 'react-use';", 829 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMedia.ts" 830 | }, 831 | { 832 | "name": "useMediaDevices", 833 | "tags": [ 834 | "Sensor", 835 | "Web API", 836 | "Devices" 837 | ], 838 | "repositoryUrl": "https://github.com/streamich/react-use", 839 | "importStatement": "import { useMediaDevices } from 'react-use';", 840 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMediaDevices.ts" 841 | }, 842 | { 843 | "name": "useMotion", 844 | "tags": [ 845 | "Sensor", 846 | "Web API", 847 | "Motion" 848 | ], 849 | "repositoryUrl": "https://github.com/streamich/react-use", 850 | "importStatement": "import { useMotion } from 'react-use';", 851 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMotion.ts" 852 | }, 853 | { 854 | "name": "useNetwork", 855 | "tags": [ 856 | "Sensor", 857 | "Web API", 858 | "Network" 859 | ], 860 | "repositoryUrl": "https://github.com/streamich/react-use", 861 | "importStatement": "import { useNetwork } from 'react-use';", 862 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useNetwork.ts" 863 | }, 864 | { 865 | "name": "useOrientation", 866 | "tags": [ 867 | "Sensor", 868 | "Web API", 869 | "Orientation" 870 | ], 871 | "repositoryUrl": "https://github.com/streamich/react-use", 872 | "importStatement": "import { useOrientation } from 'react-use';", 873 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useOrientation.ts" 874 | }, 875 | { 876 | "name": "useSize", 877 | "tags": [ 878 | "Sensor", 879 | "UI", 880 | "Size" 881 | ], 882 | "repositoryUrl": "https://github.com/streamich/react-use", 883 | "importStatement": "import { useSize } from 'react-use';", 884 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useSize.tsx" 885 | }, 886 | { 887 | "name": "useWindowSize", 888 | "tags": [ 889 | "Sensor", 890 | "Web API", 891 | "UI", 892 | "Window", 893 | "Size" 894 | ], 895 | "repositoryUrl": "https://github.com/streamich/react-use", 896 | "importStatement": "import { useWindowSize } from 'react-use';", 897 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useWindowSize.ts" 898 | }, 899 | { 900 | "name": "useAudio", 901 | "tags": [ 902 | "UI", 903 | "Audio" 904 | ], 905 | "repositoryUrl": "https://github.com/streamich/react-use", 906 | "importStatement": "import { useAudio } from 'react-use';", 907 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useAudio.ts" 908 | }, 909 | { 910 | "name": "useSpeech", 911 | "tags": [ 912 | "UI", 913 | "Audio", 914 | "Speech" 915 | ], 916 | "repositoryUrl": "https://github.com/streamich/react-use", 917 | "importStatement": "import { useSpeech } from 'react-use';", 918 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useSpeech.ts" 919 | }, 920 | { 921 | "name": "useRaf", 922 | "tags": [ 923 | "Animations", 924 | "requestAnimationFrame", 925 | "Rendering" 926 | ], 927 | "repositoryUrl": "https://github.com/streamich/react-use", 928 | "importStatement": "import { useRaf } from 'react-use';", 929 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useRaf.ts" 930 | }, 931 | { 932 | "name": "useSpring", 933 | "tags": [ 934 | "Animations", 935 | "Spring", 936 | "Tween" 937 | ], 938 | "repositoryUrl": "https://github.com/streamich/react-use", 939 | "importStatement": "import { useSpring } from 'react-use';", 940 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useSpring.ts" 941 | }, 942 | { 943 | "name": "useTimeout", 944 | "tags": [ 945 | "Animations", 946 | "Timeout" 947 | ], 948 | "repositoryUrl": "https://github.com/streamich/react-use", 949 | "importStatement": "import { useTimeout } from 'react-use';", 950 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useTimeout.ts" 951 | }, 952 | { 953 | "name": "useTween", 954 | "tags": [ 955 | "Animations", 956 | "Tween" 957 | ], 958 | "repositoryUrl": "https://github.com/streamich/react-use", 959 | "importStatement": "import { useTween } from 'react-use';", 960 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useTween.ts" 961 | }, 962 | { 963 | "name": "usePromise", 964 | "tags": [ 965 | "Async" 966 | ], 967 | "repositoryUrl": "https://github.com/streamich/react-use", 968 | "importStatement": "import { usePromise } from 'react-use';", 969 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/usePromise.ts" 970 | }, 971 | { 972 | "name": "useAsync", 973 | "tags": [ 974 | "Side-effect", 975 | "Async" 976 | ], 977 | "repositoryUrl": "https://github.com/streamich/react-use", 978 | "importStatement": "import { useAsync } from 'react-use';", 979 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useAsync.ts" 980 | }, 981 | { 982 | "name": "useAsyncRetry", 983 | "tags": [ 984 | "Side-effect", 985 | "Async" 986 | ], 987 | "repositoryUrl": "https://github.com/streamich/react-use", 988 | "importStatement": "import { useAsyncRetry } from 'react-use';", 989 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useAsyncRetry.ts" 990 | }, 991 | { 992 | "name": "useCss", 993 | "tags": [ 994 | "Side-effect", 995 | "UI", 996 | "CSS" 997 | ], 998 | "repositoryUrl": "https://github.com/streamich/react-use", 999 | "importStatement": "import { useCss } from 'react-use';", 1000 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useCss.ts" 1001 | }, 1002 | { 1003 | "name": "useFavicon", 1004 | "tags": [ 1005 | "Side-effect", 1006 | "Favicon" 1007 | ], 1008 | "repositoryUrl": "https://github.com/streamich/react-use", 1009 | "importStatement": "import { useFavicon } from 'react-use';", 1010 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useFavicon.ts" 1011 | }, 1012 | { 1013 | "name": "useTitle", 1014 | "tags": [ 1015 | "Side-effect", 1016 | "Title" 1017 | ], 1018 | "repositoryUrl": "https://github.com/streamich/react-use", 1019 | "importStatement": "import { useTitle } from 'react-use';", 1020 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useTitle.ts" 1021 | }, 1022 | { 1023 | "name": "useEffectOnce", 1024 | "tags": [ 1025 | "Lifecycles" 1026 | ], 1027 | "repositoryUrl": "https://github.com/streamich/react-use", 1028 | "importStatement": "import { useEffectOnce } from 'react-use';", 1029 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useEffectOnce.ts" 1030 | }, 1031 | { 1032 | "name": "useLogger", 1033 | "tags": [ 1034 | "Lifecycles" 1035 | ], 1036 | "repositoryUrl": "https://github.com/streamich/react-use", 1037 | "importStatement": "import { useLogger } from 'react-use';", 1038 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useLogger.ts" 1039 | }, 1040 | { 1041 | "name": "useMount", 1042 | "tags": [ 1043 | "Lifecycles" 1044 | ], 1045 | "repositoryUrl": "https://github.com/streamich/react-use", 1046 | "importStatement": "import { useMount } from 'react-use';", 1047 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMount.ts" 1048 | }, 1049 | { 1050 | "name": "useUnmount", 1051 | "tags": [ 1052 | "Lifecycles" 1053 | ], 1054 | "repositoryUrl": "https://github.com/streamich/react-use", 1055 | "importStatement": "import { useUnmount } from 'react-use';", 1056 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useUnmount.ts" 1057 | }, 1058 | { 1059 | "name": "useSetState", 1060 | "tags": [ 1061 | "State" 1062 | ], 1063 | "repositoryUrl": "https://github.com/streamich/react-use", 1064 | "importStatement": "import { useSetState } from 'react-use';", 1065 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useSetState.ts" 1066 | }, 1067 | { 1068 | "name": "useToggle", 1069 | "tags": [ 1070 | "State" 1071 | ], 1072 | "repositoryUrl": "https://github.com/streamich/react-use", 1073 | "importStatement": "import { useToggle } from 'react-use';", 1074 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useToggle.ts" 1075 | }, 1076 | { 1077 | "name": "useCounter", 1078 | "tags": [ 1079 | "State" 1080 | ], 1081 | "repositoryUrl": "https://github.com/streamich/react-use", 1082 | "importStatement": "import { useCounter } from 'react-use';", 1083 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useCounter.ts" 1084 | }, 1085 | { 1086 | "name": "useList", 1087 | "tags": [ 1088 | "State" 1089 | ], 1090 | "repositoryUrl": "https://github.com/streamich/react-use", 1091 | "importStatement": "import { useList } from 'react-use';", 1092 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useList.ts" 1093 | }, 1094 | { 1095 | "name": "useMap", 1096 | "tags": [ 1097 | "State" 1098 | ], 1099 | "repositoryUrl": "https://github.com/streamich/react-use", 1100 | "importStatement": "import { useMap } from 'react-use';", 1101 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useMap.ts" 1102 | }, 1103 | { 1104 | "name": "useDrop", 1105 | "tags": [ 1106 | "UI" 1107 | ], 1108 | "repositoryUrl": "https://github.com/streamich/react-use", 1109 | "importStatement": "import { useDrop } from 'react-use';", 1110 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useDrop.ts" 1111 | }, 1112 | { 1113 | "name": "useDropArea", 1114 | "tags": [ 1115 | "UI" 1116 | ], 1117 | "repositoryUrl": "https://github.com/streamich/react-use", 1118 | "importStatement": "import { useDropArea } from 'react-use';", 1119 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useDropArea.ts" 1120 | }, 1121 | { 1122 | "name": "useCallbag", 1123 | "tags": [ 1124 | "Streams" 1125 | ], 1126 | "repositoryUrl": "https://github.com/Andarist/use-callbag", 1127 | "importStatement": "import useCallbag from 'use-callbag';", 1128 | "sourceUrl": "https://github.com/Andarist/use-callbag/raw/master/src/index.js" 1129 | }, 1130 | { 1131 | "name": "createSelector", 1132 | "tags": [], 1133 | "repositoryUrl": "https://github.com/Andarist/react-selector-hooks", 1134 | "importStatement": "import { createSelector } from 'react-selector-hooks';", 1135 | "sourceUrl": "https://github.com/Andarist/react-selector-hooks/raw/master/src/index.js" 1136 | }, 1137 | { 1138 | "name": "createStateSelector", 1139 | "tags": [], 1140 | "repositoryUrl": "https://github.com/Andarist/react-selector-hooks", 1141 | "importStatement": "import { createStateSelector } from 'react-selector-hooks';", 1142 | "sourceUrl": "https://github.com/Andarist/react-selector-hooks/raw/master/src/index.js" 1143 | }, 1144 | { 1145 | "name": "createStructuredSelector", 1146 | "tags": [], 1147 | "repositoryUrl": "https://github.com/Andarist/react-selector-hooks", 1148 | "importStatement": "import { createStructuredSelector } from 'react-selector-hooks';", 1149 | "sourceUrl": "https://github.com/Andarist/react-selector-hooks/raw/master/src/index.js" 1150 | }, 1151 | { 1152 | "name": "useIntersectionVisible", 1153 | "tags": [ 1154 | "Viewport", 1155 | "Visible" 1156 | ], 1157 | "repositoryUrl": "https://github.com/AvraamMavridis/react-intersection-visible-hook", 1158 | "importStatement": "import useIntersectionVisible from 'react-intersection-visible-hook';" 1159 | }, 1160 | { 1161 | "name": "useBrowserContextCommunication", 1162 | "tags": [ 1163 | "Communication" 1164 | ], 1165 | "repositoryUrl": "https://github.com/AvraamMavridis/react-window-communication-hook", 1166 | "importStatement": "import useBrowserContextCommunication from 'react-window-communication-hook';" 1167 | }, 1168 | { 1169 | "name": "useSubstate", 1170 | "tags": [ 1171 | "State Management" 1172 | ], 1173 | "repositoryUrl": "https://github.com/philipp-spiess/use-substate", 1174 | "importStatement": "import { SubstateProvider, useSubstate } from 'use-substate';", 1175 | "sourceUrl": "https://github.com/philipp-spiess/use-substate/raw/master/src/index.js" 1176 | }, 1177 | { 1178 | "name": "useOnClickOutside", 1179 | "tags": [ 1180 | "Sensor", 1181 | "Click", 1182 | "UI", 1183 | "Mouse", 1184 | "Touch" 1185 | ], 1186 | "repositoryUrl": "https://github.com/Andarist/use-onclickoutside", 1187 | "importStatement": "import useOnClickOutside from 'use-onclickoutside';", 1188 | "sourceUrl": "https://github.com/Andarist/use-onclickoutside/raw/master/src/index.ts" 1189 | }, 1190 | { 1191 | "name": "usePrevious", 1192 | "tags": [], 1193 | "repositoryUrl": "https://github.com/Andarist/use-previous", 1194 | "importStatement": "import usePrevious from 'use-previous';", 1195 | "sourceUrl": "https://github.com/Andarist/use-previous/raw/master/src/index.js" 1196 | }, 1197 | { 1198 | "name": "createGlobalState", 1199 | "tags": [ 1200 | "State Management" 1201 | ], 1202 | "repositoryUrl": "https://github.com/dai-shi/react-hooks-global-state", 1203 | "importStatement": "import { createGlobalState } from 'react-hooks-global-state';", 1204 | "sourceUrl": "https://github.com/dai-shi/react-hooks-global-state/raw/master/src/index.js" 1205 | }, 1206 | { 1207 | "name": "usePromise", 1208 | "tags": [ 1209 | "Network" 1210 | ], 1211 | "repositoryUrl": "https://github.com/aiven715/promise-hook", 1212 | "importStatement": "import { usePromise } from 'promise-hook';", 1213 | "sourceUrl": "https://github.com/aiven715/promise-hook/raw/master/src/index.js" 1214 | }, 1215 | { 1216 | "name": "useDomLocation", 1217 | "tags": [ 1218 | "UI", 1219 | "Location" 1220 | ], 1221 | "repositoryUrl": "https://github.com/forthealllight/dom-location", 1222 | "importStatement": "import useDomLocation from 'dom-location';", 1223 | "sourceUrl": "https://github.com/forthealllight/dom-location/raw/master/src/index.js" 1224 | }, 1225 | { 1226 | "name": "useGraphQL", 1227 | "tags": [ 1228 | "GraphQL", 1229 | "Network" 1230 | ], 1231 | "repositoryUrl": "https://github.com/capaj/use-graphql-request", 1232 | "importStatement": "import { setupClient } from 'use-graphql-request'" 1233 | }, 1234 | { 1235 | "name": "useObjectState", 1236 | "tags": [ 1237 | "State Management" 1238 | ], 1239 | "repositoryUrl": "https://github.com/thers/use-object-state", 1240 | "importStatement": "import { useObjectState } from 'use-object-state'", 1241 | "sourceUrl": "https://github.com/thers/use-object-state/raw/master/src/index.js" 1242 | }, 1243 | { 1244 | "name": "useApolloClient", 1245 | "tags": [ 1246 | "GraphQL", 1247 | "Network", 1248 | "State Management" 1249 | ], 1250 | "repositoryUrl": "https://github.com/trojanowski/react-apollo-hooks", 1251 | "importStatement": "import { useApolloClient } from 'react-apollo-hooks'" 1252 | }, 1253 | { 1254 | "name": "useApolloMutation", 1255 | "tags": [ 1256 | "GraphQL", 1257 | "Network", 1258 | "State Management" 1259 | ], 1260 | "repositoryUrl": "https://github.com/trojanowski/react-apollo-hooks", 1261 | "importStatement": "import { useApolloMutation } from 'react-apollo-hooks'" 1262 | }, 1263 | { 1264 | "name": "useApolloQuery", 1265 | "tags": [ 1266 | "GraphQL", 1267 | "Network", 1268 | "State Management" 1269 | ], 1270 | "repositoryUrl": "https://github.com/trojanowski/react-apollo-hooks", 1271 | "importStatement": "import { useApolloQuery } from 'react-apollo-hooks'" 1272 | }, 1273 | { 1274 | "name": "useMemento", 1275 | "tags": [ 1276 | "State Management", 1277 | "Debugging", 1278 | "Time Travel" 1279 | ], 1280 | "repositoryUrl": "https://github.com/chasestarr/react-memento", 1281 | "importStatement": "import { useMemento } from 'react-memento'", 1282 | "sourceUrl": "https://github.com/chasestarr/react-memento/raw/master/index.js" 1283 | }, 1284 | { 1285 | "name": "useWait", 1286 | "tags": [ 1287 | "Loading", 1288 | "Waiting", 1289 | "Loader Management", 1290 | "UI" 1291 | ], 1292 | "repositoryUrl": "https://github.com/f/react-wait", 1293 | "importStatement": "import { Waiter, useWait } from 'react-wait'", 1294 | "sourceUrl": "https://github.com/f/react-wait/raw/master/src/index.js" 1295 | }, 1296 | { 1297 | "name": "useIdb", 1298 | "tags": [ 1299 | "IndexedDB", 1300 | "Local State", 1301 | "State Management" 1302 | ], 1303 | "repositoryUrl": "https://github.com/kigiri/react-use-idb", 1304 | "importStatement": "import { useIdb } from 'react-use-idb'", 1305 | "sourceUrl": "https://github.com/kigiri/react-use-idb/raw/master/index.js" 1306 | }, 1307 | { 1308 | "name": "useKey", 1309 | "tags": [ 1310 | "Web API", 1311 | "Devices" 1312 | ], 1313 | "repositoryUrl": "https://github.com/haldarmahesh/use-key-hook", 1314 | "importStatement": "import useKey from 'use-key-hook';" 1315 | }, 1316 | { 1317 | "name": "useMobileDetect", 1318 | "tags": [ 1319 | "Web API", 1320 | "Devices" 1321 | ], 1322 | "repositoryUrl": "https://github.com/haldarmahesh/use-mobile-detect-hook", 1323 | "importStatement": "import useMobileDetect from 'use-mobile-detect-hook" 1324 | }, 1325 | { 1326 | "name": "useDebounce", 1327 | "tags": [ 1328 | "Debounce" 1329 | ], 1330 | "repositoryUrl": "https://github.com/xnimorz/use-debounce", 1331 | "importStatement": "import { useDebounce } from 'use-debounce" 1332 | }, 1333 | { 1334 | "name": "useObservable", 1335 | "tags": [ 1336 | "Local State", 1337 | "State Management" 1338 | ], 1339 | "repositoryUrl": "https://github.com/mobxjs/mobx-react-lite", 1340 | "importStatement": "import { useObservable } from 'mobx-react-lite", 1341 | "sourceUrl": "https://github.com/mobxjs/mobx-react-lite/raw/master/src/useObservable.ts" 1342 | }, 1343 | { 1344 | "name": "useAbortableFetch", 1345 | "tags": [ 1346 | "Network", 1347 | "Fetch", 1348 | "Ajax", 1349 | "Aborting" 1350 | ], 1351 | "repositoryUrl": "https://github.com/mauricedb/use-abortable-fetch", 1352 | "importStatement": "import useAbortableFetch from 'use-abortable-fetch'", 1353 | "sourceUrl": "https://github.com/mauricedb/use-abortable-fetch/raw/master/src/index.ts" 1354 | }, 1355 | { 1356 | "name": "useScrollSpy", 1357 | "tags": [ 1358 | "scrollspy", 1359 | "ui", 1360 | "scroll", 1361 | "window", 1362 | "navigation" 1363 | ], 1364 | "repositoryUrl": "https://github.com/Purii/react-use-scrollspy", 1365 | "importStatement": "import useScrollSpy from 'react-use-scrollspy'", 1366 | "sourceUrl": "https://github.com/Purii/react-use-scrollspy/raw/master/index.js" 1367 | }, 1368 | { 1369 | "name": "globalReducer", 1370 | "tags": [ 1371 | "Reducer", 1372 | "Global", 1373 | "Selectable", 1374 | "State" 1375 | ], 1376 | "repositoryUrl": "https://github.com/jacob-ebey/react-hook-utils", 1377 | "importStatement": "import { globalReducer } from 'react-hook-utils'", 1378 | "sourceUrl": "https://github.com/jacob-ebey/react-hook-utils/raw/master/src/globalReducer.js" 1379 | }, 1380 | { 1381 | "name": "usePromise", 1382 | "tags": [ 1383 | "Promise", 1384 | "Async", 1385 | "Fetch", 1386 | "Loading" 1387 | ], 1388 | "repositoryUrl": "https://github.com/jacob-ebey/react-hook-utils", 1389 | "importStatement": "import { usePromise } from 'react-hook-utils'", 1390 | "sourceUrl": "https://github.com/jacob-ebey/react-hook-utils/raw/master/src/usePromise.js" 1391 | }, 1392 | { 1393 | "name": "useDataLoader", 1394 | "tags": [ 1395 | "Promise", 1396 | "Async", 1397 | "Load Data" 1398 | ], 1399 | "repositoryUrl": "https://github.com/smmoosavi/react-use-data-loader", 1400 | "importStatement": "import { useDataLoader } from 'react-use-data-loader'", 1401 | "sourceUrl": "https://github.com/smmoosavi/react-use-data-loader/raw/master/src/index.js" 1402 | }, 1403 | { 1404 | "name": "useTimer", 1405 | "tags": [ 1406 | "timer", 1407 | "decrement", 1408 | "increment", 1409 | "countdown" 1410 | ], 1411 | "repositoryUrl": "https://github.com/thibaultboursier/use-timer", 1412 | "importStatement": "import { useTimer } from 'use-timer'", 1413 | "sourceUrl": "https://github.com/thibaultboursier/use-timer/raw/master/src/useTimer.ts" 1414 | }, 1415 | { 1416 | "name": "useTimer", 1417 | "tags": [ 1418 | "timer", 1419 | "countdown" 1420 | ], 1421 | "repositoryUrl": "https://github.com/amrlabib/react-timer-hook", 1422 | "importStatement": "import useTimer from 'react-timer-hook'", 1423 | "sourceUrl": "https://github.com/amrlabib/react-timer-hook/raw/master/src/useTimer.js" 1424 | }, 1425 | { 1426 | "name": "useTimer", 1427 | "tags": [ 1428 | "timer" 1429 | ], 1430 | "repositoryUrl": "https://github.com/awgv/use-timer-hook", 1431 | "importStatement": "import { useTimer } from '@awgv/use-timer-hook'", 1432 | "sourceUrl": "https://github.com/awgv/use-timer-hook/raw/master/src/useTimer.js" 1433 | }, 1434 | { 1435 | "name": "useContextState", 1436 | "tags": [ 1437 | "State Management", 1438 | "Context", 1439 | "Global", 1440 | "State" 1441 | ], 1442 | "repositoryUrl": "https://github.com/diegohaz/constate", 1443 | "importStatement": "import { useContextState } from 'constate';" 1444 | }, 1445 | { 1446 | "name": "useContextReducer", 1447 | "tags": [ 1448 | "State Management", 1449 | "Context", 1450 | "Global", 1451 | "Reducer" 1452 | ], 1453 | "repositoryUrl": "https://github.com/diegohaz/constate", 1454 | "importStatement": "import { useContextReducer } from 'constate';" 1455 | }, 1456 | { 1457 | "name": "useTopState", 1458 | "tags": [ 1459 | "State Management", 1460 | "Global" 1461 | ], 1462 | "repositoryUrl": "https://github.com/mvolkmann/top-state-hook", 1463 | "importStatement": "import { useTopState } from 'top-state-hook';" 1464 | }, 1465 | { 1466 | "name": "useFormState", 1467 | "tags": [ 1468 | "State Management" 1469 | ], 1470 | "repositoryUrl": "https://github.com/wsmd/react-use-form-state", 1471 | "importStatement": "import { useFormState } from 'react-use-form-state';", 1472 | "sourceUrl": "https://github.com/wsmd/react-use-form-state/raw/master/src/useFormState.js" 1473 | }, 1474 | { 1475 | "name": "useForm", 1476 | "tags": [ 1477 | "State Management", 1478 | "Async", 1479 | "Load Data" 1480 | ], 1481 | "repositoryUrl": "https://github.com/adamsoffer/react-hubspot", 1482 | "importStatement": "import { useForm } from 'react-hubspot';", 1483 | "sourceUrl": "https://github.com/adamsoffer/react-hubspot/raw/master/src/useForm.js" 1484 | }, 1485 | { 1486 | "name": "useFetcher", 1487 | "tags": [ 1488 | "Fetch", 1489 | "Abortable Fetch" 1490 | ], 1491 | "repositoryUrl": "https://github.com/raghav-grover/use-fetcher", 1492 | "importStatement": "import { useFetcher } from 'use-fetcher';", 1493 | "sourceUrl": "https://github.com/raghav-grover/use-fetcher/raw/master/src/useFetcher.js" 1494 | }, 1495 | { 1496 | "name": "useSize", 1497 | "tags": [ 1498 | "Web API", 1499 | "Side-effect" 1500 | ], 1501 | "repositoryUrl": "https://github.com/infodusha/react-hook-size", 1502 | "importStatement": "import { useSize } from 'react-hook-size';" 1503 | }, 1504 | { 1505 | "name": "usePromise", 1506 | "tags": [ 1507 | "promise", 1508 | "async", 1509 | "fetch", 1510 | "loading", 1511 | "result", 1512 | "pending" 1513 | ], 1514 | "repositoryUrl": "https://github.com/doasync/use-promise", 1515 | "importStatement": "import { usePromise } from 'use-promise'" 1516 | }, 1517 | { 1518 | "name": "useCall", 1519 | "tags": [ 1520 | "function", 1521 | "call", 1522 | "ref", 1523 | "result" 1524 | ], 1525 | "repositoryUrl": "https://github.com/doasync/use-call", 1526 | "importStatement": "import { useCall } from 'use-call'" 1527 | }, 1528 | { 1529 | "name": "useAsyncCall", 1530 | "tags": [ 1531 | "function", 1532 | "call", 1533 | "ref", 1534 | "result", 1535 | "promise", 1536 | "async", 1537 | "fetch", 1538 | "loading", 1539 | "pending" 1540 | ], 1541 | "repositoryUrl": "https://github.com/doasync/use-call", 1542 | "importStatement": "import { useAsyncCall } from 'use-call'" 1543 | }, 1544 | { 1545 | "name": "useSubscription", 1546 | "tags": [ 1547 | "GraphQL", 1548 | "Network", 1549 | "State Management" 1550 | ], 1551 | "repositoryUrl": "https://github.com/FormidableLabs/urql", 1552 | "importStatement": "import { useSubscription } from 'urql';", 1553 | "sourceUrl": "https://github.com/FormidableLabs/urql/raw/master/src/hooks/useSubscription.ts" 1554 | }, 1555 | { 1556 | "name": "useQuery", 1557 | "tags": [ 1558 | "GraphQL", 1559 | "Network", 1560 | "State Management" 1561 | ], 1562 | "repositoryUrl": "https://github.com/FormidableLabs/urql", 1563 | "importStatement": "import { useQuery } from 'urql';", 1564 | "sourceUrl": "https://github.com/FormidableLabs/urql/raw/master/src/hooks/useQuery.ts" 1565 | }, 1566 | { 1567 | "name": "useMutation", 1568 | "tags": [ 1569 | "GraphQL", 1570 | "Network", 1571 | "State Management" 1572 | ], 1573 | "repositoryUrl": "https://github.com/FormidableLabs/urql", 1574 | "importStatement": "import { useMutation } from 'urql';", 1575 | "sourceUrl": "https://github.com/FormidableLabs/urql/raw/master/src/hooks/useMutation.ts" 1576 | }, 1577 | { 1578 | "name": "useOutsideClick", 1579 | "tags": [], 1580 | "repositoryUrl": "https://github.com/streamich/react-use", 1581 | "importStatement": "import { useOutsideClick } from 'react-use';", 1582 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useOutsideClick.ts" 1583 | }, 1584 | { 1585 | "name": "useVideo", 1586 | "tags": [], 1587 | "repositoryUrl": "https://github.com/streamich/react-use", 1588 | "importStatement": "import { useVideo } from 'react-use';", 1589 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useVideo.ts" 1590 | }, 1591 | { 1592 | "name": "useWait", 1593 | "tags": [], 1594 | "repositoryUrl": "https://github.com/streamich/react-use", 1595 | "importStatement": "import { useWait } from 'react-use';", 1596 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useWait.ts" 1597 | }, 1598 | { 1599 | "name": "useUpdate", 1600 | "tags": [], 1601 | "repositoryUrl": "https://github.com/streamich/react-use", 1602 | "importStatement": "import { useUpdate } from 'react-use';", 1603 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useUpdate.ts" 1604 | }, 1605 | { 1606 | "name": "useLocalStorage", 1607 | "tags": [], 1608 | "repositoryUrl": "https://github.com/streamich/react-use", 1609 | "importStatement": "import { useLocalStorage } from 'react-use';", 1610 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useLocalStorage.ts" 1611 | }, 1612 | { 1613 | "name": "useSessionStorage", 1614 | "tags": [], 1615 | "repositoryUrl": "https://github.com/streamich/react-use", 1616 | "importStatement": "import { useSessionStorage } from 'react-use';", 1617 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useSessionStorage.ts" 1618 | }, 1619 | { 1620 | "name": "useDebounce", 1621 | "tags": [ 1622 | "debounce" 1623 | ], 1624 | "repositoryUrl": "https://github.com/streamich/react-use", 1625 | "importStatement": "import { useDebounce } from 'react-use';", 1626 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useDebounce.ts" 1627 | }, 1628 | { 1629 | "name": "useRefMounted", 1630 | "tags": [], 1631 | "repositoryUrl": "https://github.com/streamich/react-use", 1632 | "importStatement": "import { useRefMounted } from 'react-use';", 1633 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useRefMounted.ts" 1634 | }, 1635 | { 1636 | "name": "createMemo", 1637 | "tags": [], 1638 | "repositoryUrl": "https://github.com/streamich/react-use", 1639 | "importStatement": "import { createMemo } from 'react-use';", 1640 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/createMemo.ts" 1641 | }, 1642 | { 1643 | "name": "useCallbag", 1644 | "tags": [], 1645 | "repositoryUrl": "https://github.com/streamich/react-use", 1646 | "importStatement": "import { useCallbag } from 'react-use';", 1647 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useCallbag.ts" 1648 | }, 1649 | { 1650 | "name": "useGetSet", 1651 | "tags": [], 1652 | "repositoryUrl": "https://github.com/streamich/react-use", 1653 | "importStatement": "import { useGetSet } from 'react-use';", 1654 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useGetSet.ts" 1655 | }, 1656 | { 1657 | "name": "useGetSetState", 1658 | "tags": [], 1659 | "repositoryUrl": "https://github.com/streamich/react-use", 1660 | "importStatement": "import { useGetSetState } from 'react-use';", 1661 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useGetSetState.ts" 1662 | }, 1663 | { 1664 | "name": "useObservable", 1665 | "tags": [], 1666 | "repositoryUrl": "https://github.com/streamich/react-use", 1667 | "importStatement": "import { useObservable } from 'react-use';", 1668 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useObservable.ts" 1669 | }, 1670 | { 1671 | "name": "useAxios", 1672 | "tags": [ 1673 | "Network" 1674 | ], 1675 | "repositoryUrl": "https://github.com/use-hooks/react-hooks-axios", 1676 | "importStatement": "import { useAxios } from '@use-hooks/axios';", 1677 | "sourceUrl": "https://github.com/use-hooks/react-hooks-axios/raw/master/src/index.js" 1678 | }, 1679 | { 1680 | "name": "useAPI", 1681 | "tags": [ 1682 | "axios", 1683 | "api", 1684 | "network" 1685 | ], 1686 | "repositoryUrl": "https://github.com/ABWalters/react-api-hooks", 1687 | "importStatement": "import { useAPI } from 'react-api-hooks';", 1688 | "sourceUrl": "https://github.com/ABWalters/react-api-hooks/blob/master/src/useAPI.js" 1689 | }, 1690 | { 1691 | "name": "useImageSize", 1692 | "tags": [ 1693 | "Image" 1694 | ], 1695 | "repositoryUrl": "https://github.com/use-hooks/react-hooks-image-size", 1696 | "importStatement": "import useImageSize from '@use-hooks/image-size';", 1697 | "sourceUrl": "https://github.com/use-hooks/react-hooks-image-size/raw/master/src/index.js" 1698 | }, 1699 | { 1700 | "name": "useVideoMeta", 1701 | "tags": [ 1702 | "Video" 1703 | ], 1704 | "repositoryUrl": "https://github.com/use-hooks/react-hooks-video-meta", 1705 | "importStatement": "import useVideoMeta from '@use-hooks/video-meta';", 1706 | "sourceUrl": "https://github.com/use-hooks/react-hooks-video-meta/raw/master/src/index.js" 1707 | }, 1708 | { 1709 | "name": "useInterval", 1710 | "tags": [ 1711 | "Time" 1712 | ], 1713 | "repositoryUrl": "https://github.com/use-hooks/react-hooks-interval", 1714 | "importStatement": "import useInterval from '@use-hooks/interval';", 1715 | "sourceUrl": "https://github.com/use-hooks/react-hooks-interval/raw/master/src/index.js" 1716 | }, 1717 | { 1718 | "name": "createPersistedState", 1719 | "tags": [ 1720 | "localStorage" 1721 | ], 1722 | "repositoryUrl": "https://github.com/donavon/use-persisted-state", 1723 | "importStatement": "import createPersistedState from 'use-persisted-state'", 1724 | "sourceUrl": "https://github.com/donavon/use-persisted-state/raw/master/src/index.js" 1725 | }, 1726 | { 1727 | "name": "useInView", 1728 | "tags": [ 1729 | "IntersectionObserver" 1730 | ], 1731 | "repositoryUrl": "https://github.com/thebuilder/react-intersection-observer", 1732 | "importStatement": "import { useInView } from 'react-intersection-observer'", 1733 | "sourceUrl": "https://github.com/thebuilder/react-intersection-observer/raw/master/src/useInView.tsx" 1734 | }, 1735 | { 1736 | "name": "useUndo", 1737 | "tags": [ 1738 | "undo", 1739 | "State Management" 1740 | ], 1741 | "repositoryUrl": "https://github.com/xxhomey19/use-undo", 1742 | "importStatement": "import useUndo from 'use-undo';", 1743 | "sourceUrl": "https://github.com/xxhomey19/use-undo/raw/master/index.js" 1744 | }, 1745 | { 1746 | "name": "useScreenType", 1747 | "tags": [], 1748 | "repositoryUrl": "https://github.com/pankod/react-hooks-screen-type", 1749 | "importStatement": "import useScreenType from 'react-hooks-screen-type';", 1750 | "sourceUrl": "https://github.com/pankod/react-hooks-screen-type/raw/master/src/index.js" 1751 | }, 1752 | { 1753 | "name": "usePosition", 1754 | "tags": [], 1755 | "repositoryUrl": "https://github.com/tranbathanhtung/usePosition", 1756 | "importStatement": "import usePosition from '@rehooks/usePosition';" 1757 | }, 1758 | { 1759 | "name": "useT", 1760 | "tags": [ 1761 | "i18n" 1762 | ], 1763 | "repositoryUrl": "https://github.com/streamich/use-t", 1764 | "importStatement": "import {Provider, useT} from 'use-t';" 1765 | }, 1766 | { 1767 | "name": "useSocket", 1768 | "tags": [ 1769 | "socket" 1770 | ], 1771 | "repositoryUrl": "https://github.com/iamgyz/use-socket.io-client", 1772 | "importStatement": "import useSocket from 'use-socket.io-client';", 1773 | "sourceUrl": "https://github.com/iamgyz/use-socket.io-client/raw/master/src/index.js" 1774 | }, 1775 | { 1776 | "name": "useSocket", 1777 | "tags": [ 1778 | "socket" 1779 | ], 1780 | "repositoryUrl": "https://github.com/mfrachet/use-socketio", 1781 | "importStatement": "import { ClientSocket, useSocket } from 'use-socketio';", 1782 | "sourceUrl": "https://github.com/mfrachet/use-socketio/raw/master/src/useSocket.js" 1783 | }, 1784 | { 1785 | "name": "useSimpleUndo", 1786 | "tags": [ 1787 | "undo", 1788 | "State Management" 1789 | ], 1790 | "repositoryUrl": "https://github.com/sandiiarov/use-simple-undo", 1791 | "importStatement": "import useSimpleUndo from 'use-simple-undo';" 1792 | }, 1793 | { 1794 | "name": "useRedux", 1795 | "tags": [ 1796 | "State Management" 1797 | ], 1798 | "repositoryUrl": "https://github.com/flepretre/use-redux", 1799 | "importStatement": "import { useRedux } from 'use-redux';", 1800 | "sourceUrl": "https://github.com/flepretre/use-redux/raw/master/src/useRedux.js" 1801 | }, 1802 | { 1803 | "name": "useActive", 1804 | "tags": [], 1805 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1806 | "importStatement": "import { useActive } from 'use-events';" 1807 | }, 1808 | { 1809 | "name": "useClickOutside", 1810 | "tags": [], 1811 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1812 | "importStatement": "import { useClickOutside } from 'use-events';" 1813 | }, 1814 | { 1815 | "name": "useFocus", 1816 | "tags": [], 1817 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1818 | "importStatement": "import { useFocus } from 'use-events';" 1819 | }, 1820 | { 1821 | "name": "useHover", 1822 | "tags": [], 1823 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1824 | "importStatement": "import { useHover } from 'use-events';" 1825 | }, 1826 | { 1827 | "name": "useMousePosition", 1828 | "tags": [], 1829 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1830 | "importStatement": "import { useMousePosition } from 'use-events';" 1831 | }, 1832 | { 1833 | "name": "useTouch", 1834 | "tags": [], 1835 | "repositoryUrl": "https://github.com/sandiiarov/use-events", 1836 | "importStatement": "import { useTouch } from 'use-events';" 1837 | }, 1838 | { 1839 | "name": "useDetectPrint", 1840 | "tags": [ 1841 | "Media" 1842 | ], 1843 | "repositoryUrl": "https://github.com/gregnb/use-detect-print", 1844 | "importStatement": "import useDetectPrint from 'use-detect-print'", 1845 | "sourceUrl": "https://github.com/gregnb/use-detect-print/raw/master/src/index.js" 1846 | }, 1847 | { 1848 | "name": "useBrowserHistory", 1849 | "tags": [ 1850 | "history" 1851 | ], 1852 | "repositoryUrl": "https://github.com/zcallan/use-browser-history", 1853 | "importStatement": "import useBrowserHistory from 'use-browser-history'", 1854 | "sourceUrl": "https://github.com/zcallan/use-browser-history/raw/master/src/index.js" 1855 | }, 1856 | { 1857 | "name": "useObservable", 1858 | "tags": [ 1859 | "rxjs", 1860 | "reactive" 1861 | ], 1862 | "repositoryUrl": "https://github.com/LeetCode-OpenSource/rxjs-hooks", 1863 | "importStatement": "import { useObservable } from 'rxjs-hooks'" 1864 | }, 1865 | { 1866 | "name": "useEventCallback", 1867 | "tags": [ 1868 | "rxjs", 1869 | "reactive" 1870 | ], 1871 | "repositoryUrl": "https://github.com/LeetCode-OpenSource/rxjs-hooks", 1872 | "importStatement": "import { useEventCallback } from 'rxjs-hooks'" 1873 | }, 1874 | { 1875 | "name": "createSynced", 1876 | "tags": [ 1877 | "State Management" 1878 | ], 1879 | "repositoryUrl": "https://github.com/pedronasser/resynced", 1880 | "importStatement": "import { createSynced } from 'resynced'" 1881 | }, 1882 | { 1883 | "name": "createSyncedRedux", 1884 | "tags": [ 1885 | "State Management" 1886 | ], 1887 | "repositoryUrl": "https://github.com/pedronasser/resynced", 1888 | "importStatement": "import { createSyncedRedux } from 'resynced'" 1889 | }, 1890 | { 1891 | "name": "useDispatch", 1892 | "tags": [ 1893 | "redux", 1894 | "State Management" 1895 | ], 1896 | "repositoryUrl": "https://github.com/facebookincubator/redux-react-hook", 1897 | "importStatement": "import { useDispatch } from 'redux-react-hook';" 1898 | }, 1899 | { 1900 | "name": "useMappedState", 1901 | "tags": [ 1902 | "redux", 1903 | "State Management" 1904 | ], 1905 | "repositoryUrl": "https://github.com/facebookincubator/redux-react-hook", 1906 | "importStatement": "import { useMappedState } from 'redux-react-hook';" 1907 | }, 1908 | { 1909 | "name": "useStore", 1910 | "tags": [ 1911 | "State Management" 1912 | ], 1913 | "repositoryUrl": "https://github.com/iusehooks/redhooks", 1914 | "importStatement": "import { useStore } from 'redhooks';" 1915 | }, 1916 | { 1917 | "name": "useStore", 1918 | "tags": [ 1919 | "State Management" 1920 | ], 1921 | "repositoryUrl": "https://github.com/mfrachet/reaktion", 1922 | "importStatement": "import { useStore } from 'reaktion';", 1923 | "sourceUrl": "https://github.com/mfrachet/reaktion/raw/master/src/useStore.js" 1924 | }, 1925 | { 1926 | "name": "useMiddleware", 1927 | "tags": [ 1928 | "redux", 1929 | "State Management" 1930 | ], 1931 | "repositoryUrl": "https://github.com/venil7/react-usemiddleware", 1932 | "importStatement": "import useMiddleware from 'react-usemiddleware';", 1933 | "sourceUrl": "https://github.com/venil7/react-usemiddleware/raw/master/src/index.js" 1934 | }, 1935 | { 1936 | "name": "useFormless", 1937 | "tags": [ 1938 | "Form", 1939 | "State Management" 1940 | ], 1941 | "repositoryUrl": "https://github.com/GeDiez/react-use-formless", 1942 | "importStatement": "import useFormless from 'react-useformless';", 1943 | "sourceUrl": "https://github.com/GeDiez/react-use-formless/raw/master/src/index.js" 1944 | }, 1945 | { 1946 | "name": "useScrollPosition", 1947 | "tags": [ 1948 | "Position" 1949 | ], 1950 | "repositoryUrl": "https://github.com/neo/react-use-scroll-position", 1951 | "importStatement": "import { useScrollPosition } from 'react-use-scroll-position';", 1952 | "sourceUrl": "https://github.com/neo/react-use-scroll-position/raw/master/index.ts" 1953 | }, 1954 | { 1955 | "name": "useScrollXPosition", 1956 | "tags": [ 1957 | "Position" 1958 | ], 1959 | "repositoryUrl": "https://github.com/neo/react-use-scroll-position", 1960 | "importStatement": "import { useScrollXPosition } from 'react-use-scroll-position';", 1961 | "sourceUrl": "https://github.com/neo/react-use-scroll-position/raw/master/index.ts" 1962 | }, 1963 | { 1964 | "name": "useScrollYPosition", 1965 | "tags": [ 1966 | "Position" 1967 | ], 1968 | "repositoryUrl": "https://github.com/neo/react-use-scroll-position", 1969 | "importStatement": "import { useScrollYPosition } from 'react-use-scroll-position';", 1970 | "sourceUrl": "https://github.com/neo/react-use-scroll-position/raw/master/index.ts" 1971 | }, 1972 | { 1973 | "name": "useClipboard", 1974 | "tags": [ 1975 | "Clipboard" 1976 | ], 1977 | "repositoryUrl": "https://github.com/danoc/react-use-clipboard", 1978 | "importStatement": "import useClipboard from 'react-use-clipboard';" 1979 | }, 1980 | { 1981 | "name": "useResource", 1982 | "tags": [ 1983 | "Network" 1984 | ], 1985 | "repositoryUrl": "https://github.com/schettino/react-request-hook", 1986 | "importStatement": "import {useResource} from 'react-request-hook';", 1987 | "sourceUrl": "https://github.com/schettino/react-request-hook/raw/master/src/useResource.ts" 1988 | }, 1989 | { 1990 | "name": "useRequest", 1991 | "tags": [ 1992 | "Network" 1993 | ], 1994 | "repositoryUrl": "https://github.com/schettino/react-request-hook", 1995 | "importStatement": "import {useRequest} from 'react-request-hook';", 1996 | "sourceUrl": "https://github.com/schettino/react-request-hook/raw/master/src/useRequest.ts" 1997 | }, 1998 | { 1999 | "name": "useMap", 2000 | "tags": [ 2001 | "State Management" 2002 | ], 2003 | "repositoryUrl": "https://github.com/kalcifer/react-powerhooks", 2004 | "importStatement": "import { useMap } from 'react-powerhooks';" 2005 | }, 2006 | { 2007 | "name": "usePrevious", 2008 | "tags": [ 2009 | "State Management" 2010 | ], 2011 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2012 | "importStatement": "import { usePrevious } from 'react-pirate'", 2013 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/usePrevious.js" 2014 | }, 2015 | { 2016 | "name": "useTimeout", 2017 | "tags": [ 2018 | "Time" 2019 | ], 2020 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2021 | "importStatement": "import { useTimeout } from 'react-pirate'", 2022 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useTimeout.js" 2023 | }, 2024 | { 2025 | "name": "useInterval", 2026 | "tags": [ 2027 | "Time" 2028 | ], 2029 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2030 | "importStatement": "import { useInterval } from 'react-pirate'", 2031 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useInterval.js" 2032 | }, 2033 | { 2034 | "name": "useToggle", 2035 | "tags": [ 2036 | "State Management" 2037 | ], 2038 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2039 | "importStatement": "import { useToggle } from 'react-pirate'", 2040 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useToggle.js" 2041 | }, 2042 | { 2043 | "name": "useMount", 2044 | "tags": [ 2045 | "Lifecycle" 2046 | ], 2047 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2048 | "importStatement": "import { useMount } from 'react-pirate'", 2049 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useMount.js" 2050 | }, 2051 | { 2052 | "name": "useUpdate", 2053 | "tags": [ 2054 | "Lifecycle" 2055 | ], 2056 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2057 | "importStatement": "import { useUpdate } from 'react-pirate'", 2058 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useUpdate.js" 2059 | }, 2060 | { 2061 | "name": "useLegacyUpdate", 2062 | "tags": [ 2063 | "Lifecycle" 2064 | ], 2065 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2066 | "importStatement": "import { useLegacyUpdate } from 'react-pirate'" 2067 | }, 2068 | { 2069 | "name": "useUnmount", 2070 | "tags": [ 2071 | "Lifecycle" 2072 | ], 2073 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2074 | "importStatement": "import { useUnmount } from 'react-pirate'", 2075 | "sourceUrl": "https://github.com/dispix/react-pirate/raw/master/src/useUnmount.js" 2076 | }, 2077 | { 2078 | "name": "useLegacyUnmount", 2079 | "tags": [ 2080 | "Lifecycle" 2081 | ], 2082 | "repositoryUrl": "https://github.com/dispix/react-pirate", 2083 | "importStatement": "import { useLegacyUnmount } from 'react-pirate'" 2084 | }, 2085 | { 2086 | "name": "useMediaPredicate", 2087 | "tags": [ 2088 | "Media" 2089 | ], 2090 | "repositoryUrl": "https://github.com/lessmess-agency/react-media-hook", 2091 | "importStatement": "import { useMediaPredicate } from 'react-media-hook';", 2092 | "sourceUrl": "https://github.com/lessmess-agency/react-media-hook/raw/master/src/useMediaPredicate.js" 2093 | }, 2094 | { 2095 | "name": "useValidate", 2096 | "tags": [ 2097 | "Form" 2098 | ], 2099 | "repositoryUrl": "https://github.com/marceloadsj/react-indicative-hooks", 2100 | "importStatement": "import { useValidate } from 'react-indicative-hooks';", 2101 | "sourceUrl": "https://github.com/marceloadsj/react-indicative-hooks/raw/master/src/index.js" 2102 | }, 2103 | { 2104 | "name": "useValidateAll", 2105 | "tags": [ 2106 | "Form" 2107 | ], 2108 | "repositoryUrl": "https://github.com/marceloadsj/react-indicative-hooks", 2109 | "importStatement": "import { useValidateAll } from 'react-indicative-hooks';", 2110 | "sourceUrl": "https://github.com/marceloadsj/react-indicative-hooks/raw/master/src/index.js" 2111 | }, 2112 | { 2113 | "name": "useStateValidator", 2114 | "tags": [ 2115 | "Form" 2116 | ], 2117 | "repositoryUrl": "https://github.com/marceloadsj/react-indicative-hooks", 2118 | "importStatement": "import { useStateValidator } from 'react-indicative-hooks';", 2119 | "sourceUrl": "https://github.com/marceloadsj/react-indicative-hooks/raw/master/src/index.js" 2120 | }, 2121 | { 2122 | "name": "useImmerState", 2123 | "tags": [ 2124 | "immer" 2125 | ], 2126 | "repositoryUrl": "https://github.com/sin/react-immer-hooks", 2127 | "importStatement": "import { useImmerState } from 'react-immer-hooks'" 2128 | }, 2129 | { 2130 | "name": "useHotkeys", 2131 | "tags": [ 2132 | "Hotkeys" 2133 | ], 2134 | "repositoryUrl": "https://github.com/JohannesKlauss/react-hotkeys-hook", 2135 | "importStatement": "import useHotkeys from 'react-hotkeys-hook'", 2136 | "sourceUrl": "https://github.com/JohannesKlauss/react-hotkeys-hook/raw/master/src/index.ts" 2137 | }, 2138 | { 2139 | "name": "useDidMount", 2140 | "tags": [ 2141 | "Lifecycle" 2142 | ], 2143 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2144 | "importStatement": "import { useDidMount } from 'react-hooks-lib'", 2145 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useDidMount.js" 2146 | }, 2147 | { 2148 | "name": "useWillUnmount", 2149 | "tags": [ 2150 | "Lifecycle" 2151 | ], 2152 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2153 | "importStatement": "import { useWillUnmount } from 'react-hooks-lib'", 2154 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useWillUnmount.js" 2155 | }, 2156 | { 2157 | "name": "useDidUpdate", 2158 | "tags": [ 2159 | "Lifecycle" 2160 | ], 2161 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2162 | "importStatement": "import { useDidUpdate } from 'react-hooks-lib'", 2163 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useDidUpdate.js" 2164 | }, 2165 | { 2166 | "name": "createContextState", 2167 | "tags": [ 2168 | "State Management" 2169 | ], 2170 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2171 | "importStatement": "import { createContextState } from 'react-hooks-lib'" 2172 | }, 2173 | { 2174 | "name": "createGlobalState", 2175 | "tags": [ 2176 | "State Management" 2177 | ], 2178 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2179 | "importStatement": "import { createGlobalState } from 'react-hooks-lib'" 2180 | }, 2181 | { 2182 | "name": "useMergeState", 2183 | "tags": [ 2184 | "State Management" 2185 | ], 2186 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2187 | "importStatement": "import { useMergeState } from 'react-hooks-lib'", 2188 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useMergeState.js" 2189 | }, 2190 | { 2191 | "name": "useCounter", 2192 | "tags": [ 2193 | "State Management" 2194 | ], 2195 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2196 | "importStatement": "import { useCounter } from 'react-hooks-lib'", 2197 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useCounter.js" 2198 | }, 2199 | { 2200 | "name": "useToggle", 2201 | "tags": [ 2202 | "State Management" 2203 | ], 2204 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2205 | "importStatement": "import { useToggle } from 'react-hooks-lib'", 2206 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useToggle.js" 2207 | }, 2208 | { 2209 | "name": "useList", 2210 | "tags": [ 2211 | "State Management" 2212 | ], 2213 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2214 | "importStatement": "import { useList } from 'react-hooks-lib'", 2215 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useList.js" 2216 | }, 2217 | { 2218 | "name": "useMap", 2219 | "tags": [ 2220 | "State Management" 2221 | ], 2222 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2223 | "importStatement": "import { useMap } from 'react-hooks-lib'", 2224 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useMap.js" 2225 | }, 2226 | { 2227 | "name": "useFetch", 2228 | "tags": [ 2229 | "Network" 2230 | ], 2231 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2232 | "importStatement": "import { useFetch } from 'react-hooks-lib'", 2233 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useFetch.js" 2234 | }, 2235 | { 2236 | "name": "useOnlineStatus", 2237 | "tags": [ 2238 | "Network" 2239 | ], 2240 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2241 | "importStatement": "import { useOnlineStatus } from 'react-hooks-lib'", 2242 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useOnlineStatus.js" 2243 | }, 2244 | { 2245 | "name": "useHover", 2246 | "tags": [ 2247 | "Event" 2248 | ], 2249 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2250 | "importStatement": "import { useHover } from 'react-hooks-lib'", 2251 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useHover.js" 2252 | }, 2253 | { 2254 | "name": "useActive", 2255 | "tags": [ 2256 | "Event" 2257 | ], 2258 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2259 | "importStatement": "import { useActive } from 'react-hooks-lib'", 2260 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useActive.js" 2261 | }, 2262 | { 2263 | "name": "useFocus", 2264 | "tags": [ 2265 | "Event" 2266 | ], 2267 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2268 | "importStatement": "import { useFocus } from 'react-hooks-lib'", 2269 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useFocus.js" 2270 | }, 2271 | { 2272 | "name": "useTouch", 2273 | "tags": [ 2274 | "Event" 2275 | ], 2276 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2277 | "importStatement": "import { useTouch } from 'react-hooks-lib'", 2278 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useTouch.js" 2279 | }, 2280 | { 2281 | "name": "useField", 2282 | "tags": [], 2283 | "repositoryUrl": "https://github.com/beizhedenglong/react-hooks-lib", 2284 | "importStatement": "import { useField } from 'react-hooks-lib'", 2285 | "sourceUrl": "https://github.com/beizhedenglong/react-hooks-lib/raw/master/src/hooks/useField.js" 2286 | }, 2287 | { 2288 | "name": "useArray", 2289 | "tags": [ 2290 | "State Management" 2291 | ], 2292 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2293 | "importStatement": "import { useArray } from 'react-hookedup';", 2294 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useArray.ts" 2295 | }, 2296 | { 2297 | "name": "useBoolean", 2298 | "tags": [ 2299 | "State Management" 2300 | ], 2301 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2302 | "importStatement": "import { useBoolean } from 'react-hookedup';", 2303 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useBoolean.ts" 2304 | }, 2305 | { 2306 | "name": "useCounter", 2307 | "tags": [ 2308 | "State Management" 2309 | ], 2310 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2311 | "importStatement": "import { useCounter } from 'react-hookedup';", 2312 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useCounter.ts" 2313 | }, 2314 | { 2315 | "name": "useFocus", 2316 | "tags": [ 2317 | "Event" 2318 | ], 2319 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2320 | "importStatement": "import { useFocus } from 'react-hookedup';", 2321 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useFocus.ts" 2322 | }, 2323 | { 2324 | "name": "useHover", 2325 | "tags": [ 2326 | "Event" 2327 | ], 2328 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2329 | "importStatement": "import { useHover } from 'react-hookedup';", 2330 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useHover.ts" 2331 | }, 2332 | { 2333 | "name": "useInput", 2334 | "tags": [ 2335 | "Event" 2336 | ], 2337 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2338 | "importStatement": "import { useInput } from 'react-hookedup';", 2339 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useInput.ts" 2340 | }, 2341 | { 2342 | "name": "useLifecycleHooks", 2343 | "tags": [ 2344 | "Lifecycle" 2345 | ], 2346 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2347 | "importStatement": "import { useLifecycleHooks } from 'react-hookedup';", 2348 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useLifecycleHooks.ts" 2349 | }, 2350 | { 2351 | "name": "useOnMount", 2352 | "tags": [ 2353 | "Lifecycle" 2354 | ], 2355 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2356 | "importStatement": "import { useOnMount } from 'react-hookedup';", 2357 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useOnMount.ts" 2358 | }, 2359 | { 2360 | "name": "useOnUnmount", 2361 | "tags": [ 2362 | "Lifecycle" 2363 | ], 2364 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2365 | "importStatement": "import { useOnUnmount } from 'react-hookedup';", 2366 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useOnUnmount.ts" 2367 | }, 2368 | { 2369 | "name": "useMergeState", 2370 | "tags": [ 2371 | "State Management" 2372 | ], 2373 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2374 | "importStatement": "import { useMergeState } from 'react-hookedup';", 2375 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useMergeState.ts" 2376 | }, 2377 | { 2378 | "name": "usePrevious", 2379 | "tags": [ 2380 | "State Management" 2381 | ], 2382 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2383 | "importStatement": "import { usePrevious } from 'react-hookedup';", 2384 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/usePrevious.ts" 2385 | }, 2386 | { 2387 | "name": "useInterval", 2388 | "tags": [ 2389 | "Time" 2390 | ], 2391 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2392 | "importStatement": "import { useInterval } from 'react-hookedup';", 2393 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useInterval.ts" 2394 | }, 2395 | { 2396 | "name": "useTimeout", 2397 | "tags": [ 2398 | "Time" 2399 | ], 2400 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2401 | "importStatement": "import { useTimeout } from 'react-hookedup';", 2402 | "sourceUrl": "https://github.com/zakariaharti/react-hookedup/raw/master/src/hooks/useTimeout.ts" 2403 | }, 2404 | { 2405 | "name": "useOnLineStatus", 2406 | "tags": [ 2407 | "Networl" 2408 | ], 2409 | "repositoryUrl": "https://github.com/zakariaharti/react-hookedup", 2410 | "importStatement": "import { useOnLineStatus } from 'react-hookedup';" 2411 | }, 2412 | { 2413 | "name": "useSFControl", 2414 | "tags": [ 2415 | "Form" 2416 | ], 2417 | "repositoryUrl": "https://github.com/ckedwards/react-form-stateful", 2418 | "importStatement": "import { useSFControl } from 'react-form-stateful';" 2419 | }, 2420 | { 2421 | "name": "useSFError", 2422 | "tags": [ 2423 | "Form" 2424 | ], 2425 | "repositoryUrl": "https://github.com/ckedwards/react-form-stateful", 2426 | "importStatement": "import { useSFError } from 'react-form-stateful';" 2427 | }, 2428 | { 2429 | "name": "useSFValue", 2430 | "tags": [ 2431 | "Form" 2432 | ], 2433 | "repositoryUrl": "https://github.com/ckedwards/react-form-stateful", 2434 | "importStatement": "import { useSFValue } from 'react-form-stateful';" 2435 | }, 2436 | { 2437 | "name": "useAuthState", 2438 | "tags": [], 2439 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2440 | "importStatement": "import { useAuthState } from 'react-firebase-hooks/auth';" 2441 | }, 2442 | { 2443 | "name": "useCollection", 2444 | "tags": [], 2445 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2446 | "importStatement": "import { useCollection } from 'react-firebase-hooks/firestore';" 2447 | }, 2448 | { 2449 | "name": "useDocument", 2450 | "tags": [], 2451 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2452 | "importStatement": "import { useDocument } from 'react-firebase-hooks/firestore';" 2453 | }, 2454 | { 2455 | "name": "useDownloadUrl", 2456 | "tags": [], 2457 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2458 | "importStatement": "import { useDownloadUrl } from 'react-firebase-hooks/storage';" 2459 | }, 2460 | { 2461 | "name": "useList", 2462 | "tags": [], 2463 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2464 | "importStatement": "import { useList } from 'react-firebase-hooks/database';" 2465 | }, 2466 | { 2467 | "name": "useObject", 2468 | "tags": [], 2469 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2470 | "importStatement": "import { useObject } from 'react-firebase-hooks/database';" 2471 | }, 2472 | { 2473 | "name": "useListVals", 2474 | "tags": [], 2475 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2476 | "importStatement": "import { useListVals } from 'react-firebase-hooks/database';" 2477 | }, 2478 | { 2479 | "name": "useListKeys", 2480 | "tags": [], 2481 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2482 | "importStatement": "import { useListKeys } from 'react-firebase-hooks/database';" 2483 | }, 2484 | { 2485 | "name": "useObjectVal", 2486 | "tags": [], 2487 | "repositoryUrl": "https://github.com/csfrequency/react-firebase-hooks", 2488 | "importStatement": "import { useObjectVal } from 'react-firebase-hooks/database';" 2489 | }, 2490 | { 2491 | "name": "useFetch", 2492 | "tags": [ 2493 | "Network" 2494 | ], 2495 | "repositoryUrl": "https://github.com/ilyalesik/react-fetch-hook", 2496 | "importStatement": "import { useFetch } from 'react-fetch-hook';", 2497 | "sourceUrl": "https://github.com/ilyalesik/react-fetch-hook/raw/master/src/useFetch.js" 2498 | }, 2499 | { 2500 | "name": "useEnhancedReducer", 2501 | "tags": [ 2502 | "State Management" 2503 | ], 2504 | "repositoryUrl": "https://github.com/shiningjason/react-enhanced-reducer-hook", 2505 | "importStatement": "import useEnhancedReducer from 'react-enhanced-reducer-hook'", 2506 | "sourceUrl": "https://github.com/shiningjason/react-enhanced-reducer-hook/raw/master/index.js" 2507 | }, 2508 | { 2509 | "name": "useDOMState", 2510 | "tags": [], 2511 | "repositoryUrl": "https://github.com/yeskunall/react-dom-status-hook", 2512 | "importStatement": "import useDOMState from '@yeskunall/react-dom-status-hook';" 2513 | }, 2514 | { 2515 | "name": "useAsync", 2516 | "tags": [], 2517 | "repositoryUrl": "https://github.com/slorber/react-async-hook", 2518 | "importStatement": "import { useAsync } from 'react-async-hook';", 2519 | "sourceUrl": "https://github.com/slorber/react-async-hook/raw/master/src/index.js" 2520 | }, 2521 | { 2522 | "name": "useAsync", 2523 | "tags": [ 2524 | "Side-effect", 2525 | "Async", 2526 | "promise" 2527 | ], 2528 | "repositoryUrl": "https://github.com/wolverineks/react-use-async", 2529 | "importStatement": "import { useAsync } from 'react-use-async';", 2530 | "sourceUrl": "https://github.com/wolverineks/react-use-async/raw/master/src/index.js" 2531 | }, 2532 | { 2533 | "name": "useStore", 2534 | "tags": [ 2535 | "State Management" 2536 | ], 2537 | "repositoryUrl": "https://github.com/ctrlplusb/easy-peasy", 2538 | "importStatement": "import { useStore } from 'easy-peasy';" 2539 | }, 2540 | { 2541 | "name": "useActions", 2542 | "tags": [ 2543 | "State Management" 2544 | ], 2545 | "repositoryUrl": "https://github.com/ctrlplusb/easy-peasy", 2546 | "importStatement": "import { useActions } from 'easy-peasy';" 2547 | }, 2548 | { 2549 | "name": "useActive", 2550 | "tags": [], 2551 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2552 | "importStatement": "import { useActive } from '@withvoid/melting-pot';", 2553 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useActive.js" 2554 | }, 2555 | { 2556 | "name": "useDidMount", 2557 | "tags": [ 2558 | "Lifecycle" 2559 | ], 2560 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2561 | "importStatement": "import { useDidMount } from '@withvoid/melting-pot';", 2562 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useDidMount.js" 2563 | }, 2564 | { 2565 | "name": "useFormField", 2566 | "tags": [ 2567 | "Form" 2568 | ], 2569 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2570 | "importStatement": "import { useFormField } from '@withvoid/melting-pot';", 2571 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useFormField.js" 2572 | }, 2573 | { 2574 | "name": "useHover", 2575 | "tags": [ 2576 | "Event" 2577 | ], 2578 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2579 | "importStatement": "import { useHover } from '@withvoid/melting-pot';", 2580 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useHover.js" 2581 | }, 2582 | { 2583 | "name": "useInterval", 2584 | "tags": [ 2585 | "Time" 2586 | ], 2587 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2588 | "importStatement": "import { useInterval } from '@withvoid/melting-pot';", 2589 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useInterval.js" 2590 | }, 2591 | { 2592 | "name": "useKeyPress", 2593 | "tags": [ 2594 | "Event" 2595 | ], 2596 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2597 | "importStatement": "import { useKeyPress } from '@withvoid/melting-pot';", 2598 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useKeyPress.js" 2599 | }, 2600 | { 2601 | "name": "useOnlineStatus", 2602 | "tags": [ 2603 | "Network" 2604 | ], 2605 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2606 | "importStatement": "import { useOnlineStatus } from '@withvoid/melting-pot';", 2607 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useOnlineStatus.js" 2608 | }, 2609 | { 2610 | "name": "useScreenType", 2611 | "tags": [ 2612 | "Media" 2613 | ], 2614 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2615 | "importStatement": "import { useScreenType } from '@withvoid/melting-pot';", 2616 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useScreenType.js" 2617 | }, 2618 | { 2619 | "name": "useTitle", 2620 | "tags": [], 2621 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2622 | "importStatement": "import { useTitle } from '@withvoid/melting-pot';", 2623 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useTitle.js" 2624 | }, 2625 | { 2626 | "name": "useToggle", 2627 | "tags": [ 2628 | "State Management" 2629 | ], 2630 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2631 | "importStatement": "import { useToggle } from '@withvoid/melting-pot';", 2632 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useToggle.js" 2633 | }, 2634 | { 2635 | "name": "useTouch", 2636 | "tags": [ 2637 | "Event" 2638 | ], 2639 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2640 | "importStatement": "import { useTouch } from '@withvoid/melting-pot';", 2641 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useTouch.js" 2642 | }, 2643 | { 2644 | "name": "useUpdate", 2645 | "tags": [], 2646 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2647 | "importStatement": "import { useUpdate } from '@withvoid/melting-pot';", 2648 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useUpdate.js" 2649 | }, 2650 | { 2651 | "name": "useWindowScrollPosition", 2652 | "tags": [], 2653 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2654 | "importStatement": "import { useWindowScrollPosition } from '@withvoid/melting-pot';", 2655 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useWindowScrollPosition.js" 2656 | }, 2657 | { 2658 | "name": "useWindowSize", 2659 | "tags": [], 2660 | "repositoryUrl": "https://github.com/withvoid/melting-pot", 2661 | "importStatement": "import { useWindowSize } from '@withvoid/melting-pot';", 2662 | "sourceUrl": "https://github.com/withvoid/melting-pot/raw/master/src/hooks/useWindowSize.js" 2663 | }, 2664 | { 2665 | "name": "useProfunctorState", 2666 | "tags": [], 2667 | "repositoryUrl": "https://github.com/staltz/use-profunctor-state", 2668 | "importStatement": "import useProfunctorState from '@staltz/use-profunctor-state';", 2669 | "sourceUrl": "https://github.com/staltz/use-profunctor-state/raw/master/index.ts" 2670 | }, 2671 | { 2672 | "name": "useOrientation", 2673 | "tags": [ 2674 | "Web API" 2675 | ], 2676 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2677 | "importStatement": "import useOrientation from '@21kb/react-device-orientation-hook';" 2678 | }, 2679 | { 2680 | "name": "reactDomStatusHook", 2681 | "tags": [], 2682 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2683 | "importStatement": "import reactDomStatusHook from '@21kb/react-dom-status-hook';" 2684 | }, 2685 | { 2686 | "name": "reactWindowFocusHook", 2687 | "tags": [], 2688 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2689 | "importStatement": "import reactWindowFocusHook from '@21kb/react-window-focus-hook';" 2690 | }, 2691 | { 2692 | "name": "useNotification", 2693 | "tags": [ 2694 | "Web API" 2695 | ], 2696 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2697 | "importStatement": "import useNotification from '@21kb/react-notification-hook';" 2698 | }, 2699 | { 2700 | "name": "useOfflineStatus", 2701 | "tags": [ 2702 | "Network" 2703 | ], 2704 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2705 | "importStatement": "import { useOfflineStatus } from '@21kb/react-online-status-hook';" 2706 | }, 2707 | { 2708 | "name": "useOnlineStatus", 2709 | "tags": [ 2710 | "Network" 2711 | ], 2712 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2713 | "importStatement": "import { useOnlineStatus } from '@21kb/react-online-status-hook';" 2714 | }, 2715 | { 2716 | "name": "useVisible", 2717 | "tags": [], 2718 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2719 | "importStatement": "import useVisible from '@21kb/react-page-visible-hook';" 2720 | }, 2721 | { 2722 | "name": "useVibration", 2723 | "tags": [ 2724 | "Web API" 2725 | ], 2726 | "repositoryUrl": "https://github.com/21kb/react-hooks", 2727 | "importStatement": "import useVibration from '@21kb/react-vibration-hook';" 2728 | }, 2729 | { 2730 | "name": "useMousetrap", 2731 | "tags": [ 2732 | "Hotkeys" 2733 | ], 2734 | "repositoryUrl": "https://github.com/olup/react-hook-mousetrap", 2735 | "importStatement": "import useMousetrap from 'react-hook-mousetrap'", 2736 | "sourceUrl": "https://github.com/olup/react-hook-mousetrap/raw/master/index.js" 2737 | }, 2738 | { 2739 | "name": "useLog", 2740 | "tags": [ 2741 | "Development Tools" 2742 | ], 2743 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2744 | "importStatement": "import { useLog } from 'retoggle';" 2745 | }, 2746 | { 2747 | "name": "useTextKnob", 2748 | "tags": [ 2749 | "Development Tools" 2750 | ], 2751 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2752 | "importStatement": "import { useTextKnob } from 'retoggle';" 2753 | }, 2754 | { 2755 | "name": "useNumberKnob", 2756 | "tags": [ 2757 | "Development Tools" 2758 | ], 2759 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2760 | "importStatement": "import { useNumberKnob } from 'retoggle';" 2761 | }, 2762 | { 2763 | "name": "useBooleanKnob", 2764 | "tags": [ 2765 | "Development Tools" 2766 | ], 2767 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2768 | "importStatement": "import { useBooleanKnob } from 'retoggle';" 2769 | }, 2770 | { 2771 | "name": "useRangeKnob", 2772 | "tags": [ 2773 | "Development Tools" 2774 | ], 2775 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2776 | "importStatement": "import { useRangeKnob } from 'retoggle';" 2777 | }, 2778 | { 2779 | "name": "useRangesKnob", 2780 | "tags": [ 2781 | "Development Tools" 2782 | ], 2783 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2784 | "importStatement": "import { useRangesKnob } from 'retoggle';" 2785 | }, 2786 | { 2787 | "name": "useSelectKnob", 2788 | "tags": [ 2789 | "Development Tools" 2790 | ], 2791 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2792 | "importStatement": "import { useSelectKnob } from 'retoggle';" 2793 | }, 2794 | { 2795 | "name": "useObjectKnob", 2796 | "tags": [ 2797 | "Development Tools" 2798 | ], 2799 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2800 | "importStatement": "import { useObjectKnob } from 'retoggle';" 2801 | }, 2802 | { 2803 | "name": "useColorKnob", 2804 | "tags": [ 2805 | "Development Tools" 2806 | ], 2807 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2808 | "importStatement": "import { useColorKnob } from 'retoggle';" 2809 | }, 2810 | { 2811 | "name": "useTimemachine", 2812 | "tags": [ 2813 | "Development Tools" 2814 | ], 2815 | "repositoryUrl": "https://github.com/raathigesh/retoggle", 2816 | "importStatement": "import { useTimemachine } from 'retoggle';" 2817 | }, 2818 | { 2819 | "name": "useBoundingclientrect", 2820 | "tags": [ 2821 | "Size", 2822 | "Position" 2823 | ], 2824 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2825 | "importStatement": "import useBoundingclientrect from '@rooks/use-boundingclientrect';" 2826 | }, 2827 | { 2828 | "name": "useCounter", 2829 | "tags": [ 2830 | "State Manager" 2831 | ], 2832 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2833 | "importStatement": "import useCounter from '@rooks/use-counter';" 2834 | }, 2835 | { 2836 | "name": "useDidMount", 2837 | "tags": [ 2838 | "Lifecycle" 2839 | ], 2840 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2841 | "importStatement": "import useDidMount from '@rooks/use-did-mount';" 2842 | }, 2843 | { 2844 | "name": "useDidUpdate", 2845 | "tags": [ 2846 | "Lifecycle" 2847 | ], 2848 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2849 | "importStatement": "import useDidUpdate from '@rooks/use-did-update';" 2850 | }, 2851 | { 2852 | "name": "useInput", 2853 | "tags": [ 2854 | "State Management" 2855 | ], 2856 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2857 | "importStatement": "import useInput from '@rooks/use-input';" 2858 | }, 2859 | { 2860 | "name": "useInterval", 2861 | "tags": [ 2862 | "State Management" 2863 | ], 2864 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2865 | "importStatement": "import useInterval from '@rooks/use-interval';" 2866 | }, 2867 | { 2868 | "name": "useKey", 2869 | "tags": [], 2870 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2871 | "importStatement": "import useKey from '@rooks/use-key';" 2872 | }, 2873 | { 2874 | "name": "useLocalstorage", 2875 | "tags": [ 2876 | "State Management" 2877 | ], 2878 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2879 | "importStatement": "import useLocalstorage from '@rooks/use-localstorage';" 2880 | }, 2881 | { 2882 | "name": "useMouse", 2883 | "tags": [], 2884 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2885 | "importStatement": "import useMouse from '@rooks/use-mouse';" 2886 | }, 2887 | { 2888 | "name": "useSessionStorage", 2889 | "tags": [ 2890 | "State Management" 2891 | ], 2892 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2893 | "importStatement": "import useSessionStorage from '@rooks/use-sessionstorage';" 2894 | }, 2895 | { 2896 | "name": "useWillUnmount", 2897 | "tags": [ 2898 | "Lifecycle" 2899 | ], 2900 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2901 | "importStatement": "import useWillUnmount from '@rooks/use-will-unmount';" 2902 | }, 2903 | { 2904 | "name": "useOnline", 2905 | "tags": [ 2906 | "Network" 2907 | ], 2908 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2909 | "importStatement": "import useOnline from '@rooks/use-online';" 2910 | }, 2911 | { 2912 | "name": "useOutsideClick", 2913 | "tags": [ 2914 | "Event" 2915 | ], 2916 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2917 | "importStatement": "import useOutsideClick from '@rooks/use-outside-click';" 2918 | }, 2919 | { 2920 | "name": "usePrevious", 2921 | "tags": [ 2922 | "State Management" 2923 | ], 2924 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2925 | "importStatement": "import usePrevious from '@rooks/use-previous';" 2926 | }, 2927 | { 2928 | "name": "useSelect", 2929 | "tags": [ 2930 | "State Management" 2931 | ], 2932 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2933 | "importStatement": "import useSelect from '@rooks/use-select';" 2934 | }, 2935 | { 2936 | "name": "useToggle", 2937 | "tags": [ 2938 | "State Management" 2939 | ], 2940 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2941 | "importStatement": "import useToggle from '@rooks/use-toggle';" 2942 | }, 2943 | { 2944 | "name": "useWindowSize", 2945 | "tags": [ 2946 | "Size", 2947 | "Position" 2948 | ], 2949 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2950 | "importStatement": "import useWindowSize from '@rooks/use-window-size';" 2951 | }, 2952 | { 2953 | "name": "useTimeout", 2954 | "tags": [ 2955 | "Time" 2956 | ], 2957 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2958 | "importStatement": "import useTimeout from '@rooks/use-timeout';" 2959 | }, 2960 | { 2961 | "name": "useMutationObserver", 2962 | "tags": [], 2963 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2964 | "importStatement": "import useMutationObserver from '@rooks/use-mutation-observer';" 2965 | }, 2966 | { 2967 | "name": "useNavigatorLanguage", 2968 | "tags": [], 2969 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2970 | "importStatement": "import useNavigatorLanguage from '@rooks/use-navigator-language';" 2971 | }, 2972 | { 2973 | "name": "useRaf", 2974 | "tags": [ 2975 | "Time", 2976 | "Animation" 2977 | ], 2978 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2979 | "importStatement": "import useRaf from '@rooks/use-raf';" 2980 | }, 2981 | { 2982 | "name": "useTimeAgo", 2983 | "tags": [], 2984 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2985 | "importStatement": "import useTimeAgo from '@rooks/use-time-ago';" 2986 | }, 2987 | { 2988 | "name": "useVisibilitySensor", 2989 | "tags": [], 2990 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2991 | "importStatement": "import useVisibilitySensor from '@rooks/use-visibility-sensor';" 2992 | }, 2993 | { 2994 | "name": "useWorker", 2995 | "tags": [], 2996 | "repositoryUrl": "https://github.com/imbhargav5/rooks", 2997 | "importStatement": "import useWorker from '@rooks/use-worker';" 2998 | }, 2999 | { 3000 | "name": "useMermaid", 3001 | "tags": [ 3002 | "mermaid" 3003 | ], 3004 | "repositoryUrl": "https://github.com/DanShai/useMermaid-hook", 3005 | "importStatement": "import { useMermaid } from './useMermaid';" 3006 | }, 3007 | { 3008 | "name": "usePanZoom", 3009 | "tags": [ 3010 | "UI", 3011 | "layout" 3012 | ], 3013 | "repositoryUrl": "https://github.com/wouterraateland/use-pan-and-zoom", 3014 | "importStatement": "import usePanZoom from 'use-pan-and-zoom';", 3015 | "sourceUrl": "https://github.com/wouterraateland/use-pan-and-zoom/raw/master/src/index.js" 3016 | }, 3017 | { 3018 | "name": "useForceUpdate", 3019 | "tags": [ 3020 | "Lifecycles" 3021 | ], 3022 | "repositoryUrl": "https://github.com/CharlesStover/use-force-update", 3023 | "importStatement": "import useForceUpdate from 'use-force-update';" 3024 | }, 3025 | { 3026 | "name": "useDimensions", 3027 | "tags": [ 3028 | "React Native" 3029 | ], 3030 | "repositoryUrl": "https://github.com/CharlesStover/use-dimensions", 3031 | "importStatement": "import useDimensions from 'use-dimensions';" 3032 | }, 3033 | { 3034 | "name": "useScreenDimensions", 3035 | "tags": [ 3036 | "React Native" 3037 | ], 3038 | "repositoryUrl": "https://github.com/CharlesStover/use-dimensions", 3039 | "importStatement": "import { useScreenDimensions } from 'use-dimensions';" 3040 | }, 3041 | { 3042 | "name": "useWindowDimensions", 3043 | "tags": [ 3044 | "React Native" 3045 | ], 3046 | "repositoryUrl": "https://github.com/CharlesStover/use-dimensions", 3047 | "importStatement": "import { useWindowDimensions } from 'use-dimensions';" 3048 | }, 3049 | { 3050 | "name": "useFetch", 3051 | "tags": [ 3052 | "Async", 3053 | "Fetch", 3054 | "Load Data", 3055 | "Suspense" 3056 | ], 3057 | "repositoryUrl": "https://github.com/CharlesStover/fetch-suspense", 3058 | "importStatement": "import useFetch from 'fetch-suspense';" 3059 | }, 3060 | { 3061 | "name": "useReactRouter", 3062 | "tags": [ 3063 | "React Router", 3064 | "Routes" 3065 | ], 3066 | "repositoryUrl": "https://github.com/CharlesStover/use-react-router", 3067 | "importStatement": "import useReactRouter from 'use-react-router';" 3068 | }, 3069 | { 3070 | "name": "useGlobal", 3071 | "tags": [ 3072 | "State Management" 3073 | ], 3074 | "repositoryUrl": "https://github.com/CharlesStover/reactn", 3075 | "importStatement": "import { useGlobal } from 'reactn';" 3076 | }, 3077 | { 3078 | "name": "useURLState", 3079 | "tags": [ 3080 | "State Management" 3081 | ], 3082 | "repositoryUrl": "https://github.com/contiamo/operational-ui", 3083 | "importStatement": "import { useURLState } from '@operational/components';" 3084 | }, 3085 | { 3086 | "name": "useWindowSize", 3087 | "tags": [ 3088 | "Size" 3089 | ], 3090 | "repositoryUrl": "https://github.com/contiamo/operational-ui", 3091 | "importStatement": "import { useWindowSize } from '@operational/components';" 3092 | }, 3093 | { 3094 | "name": "useSt8", 3095 | "tags": [ 3096 | "State Management" 3097 | ], 3098 | "repositoryUrl": "https://github.com/mweststrate/use-st8", 3099 | "importStatement": "import { useSt8 } from 'use-st8';", 3100 | "sourceUrl": "https://github.com/mweststrate/use-st8/raw/master/src/index.ts" 3101 | }, 3102 | { 3103 | "name": "useMeasure", 3104 | "tags": [ 3105 | "Browser-API", 3106 | "Side-effect", 3107 | "Size" 3108 | ], 3109 | "repositoryUrl": "https://github.com/SoftBind/react-hooks/tree/master/packages/useMeasure", 3110 | "importStatement": "import { useMeasure } from \"@softbind/hook-use-measure\";" 3111 | }, 3112 | { 3113 | "name": "useMotor", 3114 | "tags": [ 3115 | "Browser", 3116 | "History", 3117 | "Router" 3118 | ], 3119 | "repositoryUrl": "https://github.com/wilcoschoneveld/react-motor", 3120 | "importStatement": "import { useMotor } from 'react-motor';" 3121 | }, 3122 | { 3123 | "name": "useCurrentRoute", 3124 | "tags": [ 3125 | "History", 3126 | "Router" 3127 | ], 3128 | "repositoryUrl": "https://github.com/frontarm/navi", 3129 | "importStatement": "import { useCurrentRoute } from 'react-navi';" 3130 | }, 3131 | { 3132 | "name": "useLoadingRoute", 3133 | "tags": [ 3134 | "History", 3135 | "Router", 3136 | "Loading" 3137 | ], 3138 | "repositoryUrl": "https://github.com/frontarm/navi", 3139 | "importStatement": "import { useLoadingRoute } from 'react-navi';" 3140 | }, 3141 | { 3142 | "name": "useHistory", 3143 | "tags": [ 3144 | "History", 3145 | "Location" 3146 | ], 3147 | "repositoryUrl": "https://github.com/frontarm/navi", 3148 | "importStatement": "import { useHistory } from 'react-navi';" 3149 | }, 3150 | { 3151 | "name": "useFetch", 3152 | "tags": [ 3153 | "Fetch", 3154 | "Request", 3155 | "Network", 3156 | "Async" 3157 | ], 3158 | "repositoryUrl": "https://github.com/bghveding/use-fetch", 3159 | "importStatement": "import { useFetch } from '@bjornagh/use-fetch';", 3160 | "sourceUrl": "https://github.com/bghveding/use-fetch/raw/master/src/useFetch.js" 3161 | }, 3162 | { 3163 | "name": "useScrollPosition", 3164 | "tags": [ 3165 | "Scroll", 3166 | "Window", 3167 | "Layout", 3168 | "Position" 3169 | ], 3170 | "repositoryUrl": "https://gitlab.com/bmgaynor/use-scroll-position", 3171 | "importStatement": "import useScrollPosition from 'use-scroll-position';" 3172 | }, 3173 | { 3174 | "name": "react-universal-hooks", 3175 | "tags": [ 3176 | "react", 3177 | "hooks", 3178 | "class", 3179 | "classes", 3180 | "universal" 3181 | ], 3182 | "repositoryUrl": "https://github.com/salvoravida/react-universal-hooks", 3183 | "importStatement": "import 'react-universal-hooks';" 3184 | }, 3185 | { 3186 | "name": "use-abortable-stream-fetch", 3187 | "tags": [ 3188 | "react", 3189 | "hooks", 3190 | "fetch", 3191 | "ajax", 3192 | "abort" 3193 | ], 3194 | "repositoryUrl": "https://github.com/marconi/use-abortable-stream-fetch", 3195 | "importStatement": "import useAbortableStreamFetch from 'use-abortable-stream-fetch';", 3196 | "sourceUrl": "https://github.com/marconi/use-abortable-stream-fetch/raw/master/src/index.ts" 3197 | }, 3198 | { 3199 | "name": "useMouseAction", 3200 | "tags": [ 3201 | "Mouse", 3202 | "Event", 3203 | "Accessibility", 3204 | "A11y" 3205 | ], 3206 | "repositoryUrl": "https://github.com/dimitrinicolas/use-mouse-action", 3207 | "importStatement": "import useMouseAction from 'use-mouse-action';", 3208 | "sourceUrl": "https://github.com/dimitrinicolas/use-mouse-action/raw/master/src/index.ts" 3209 | }, 3210 | { 3211 | "name": "useMouseDown", 3212 | "tags": [ 3213 | "Mouse", 3214 | "Event", 3215 | "Accessibility", 3216 | "A11y" 3217 | ], 3218 | "repositoryUrl": "https://github.com/dimitrinicolas/use-mouse-action", 3219 | "importStatement": "import { useMouseDown } from 'use-mouse-action';", 3220 | "sourceUrl": "https://github.com/dimitrinicolas/use-mouse-action/raw/master/src/index.ts" 3221 | }, 3222 | { 3223 | "name": "useMouseUp", 3224 | "tags": [ 3225 | "Mouse", 3226 | "Event", 3227 | "Accessibility", 3228 | "A11y" 3229 | ], 3230 | "repositoryUrl": "https://github.com/dimitrinicolas/use-mouse-action", 3231 | "importStatement": "import { useMouseUp } from 'use-mouse-action';", 3232 | "sourceUrl": "https://github.com/dimitrinicolas/use-mouse-action/raw/master/src/index.ts" 3233 | }, 3234 | { 3235 | "name": "useTrackingIsLoaded", 3236 | "tags": [ 3237 | "Analytics" 3238 | ], 3239 | "repositoryUrl": "https://github.com/zanonnicola/tracking-ready-hook", 3240 | "importStatement": "import useTrackingIsLoaded from 'tracking-ready-hook';", 3241 | "sourceUrl": "https://github.com/zanonnicola/tracking-ready-hook/raw/master/src/index.js" 3242 | }, 3243 | { 3244 | "name": "useClippy", 3245 | "tags": [ 3246 | "State Management", 3247 | "Clipboard" 3248 | ], 3249 | "repositoryUrl": "https://github.com/CharlesStover/use-clippy", 3250 | "importStatement": "import useClippy from 'use-clippy';" 3251 | }, 3252 | { 3253 | "name": "useUpdateEffect", 3254 | "tags": [ 3255 | "effect", 3256 | "update" 3257 | ], 3258 | "repositoryUrl": "https://github.com/streamich/react-use", 3259 | "importStatement": "import { useUpdateEffect } from 'react-use';", 3260 | "sourceUrl": "https://github.com/streamich/react-use/raw/master/src/useUpdateEffect.ts" 3261 | }, 3262 | { 3263 | "name": "useStateTree", 3264 | "tags": [ 3265 | "State Management" 3266 | ], 3267 | "repositoryUrl": "https://github.com/suchipi/react-state-tree", 3268 | "importStatement": "import { useStateTree } from 'react-state-tree';", 3269 | "sourceUrl": "https://github.com/suchipi/react-state-tree/raw/master/index.tsx" 3270 | }, 3271 | { 3272 | "name": "useReduxState", 3273 | "tags": [ 3274 | "State Management" 3275 | ], 3276 | "repositoryUrl": "https://github.com/dai-shi/react-hooks-easy-redux", 3277 | "importStatement": "import { useReduxState } from 'react-hooks-easy-redux';", 3278 | "sourceUrl": "https://github.com/dai-shi/react-hooks-easy-redux/blob/master/src/index.js" 3279 | }, 3280 | { 3281 | "name": "useReduxDispatch", 3282 | "tags": [ 3283 | "State Management" 3284 | ], 3285 | "repositoryUrl": "https://github.com/dai-shi/react-hooks-easy-redux", 3286 | "importStatement": "import { useReduxDispatch } from 'react-hooks-easy-redux';", 3287 | "sourceUrl": "https://github.com/dai-shi/react-hooks-easy-redux/blob/master/src/index.js" 3288 | }, 3289 | { 3290 | "name": "useRoutes", 3291 | "tags": [], 3292 | "repositoryUrl": "https://github.com/Paratron/hookrouter", 3293 | "importStatement": "import {useRoutes} from 'hookrouter';", 3294 | "sourceUrl": "https://raw.githubusercontent.com/Paratron/hookrouter/master/src/router.js" 3295 | }, 3296 | { 3297 | "name": "useMethods", 3298 | "tags": [ 3299 | "state", 3300 | "methods", 3301 | "useReducer", 3302 | "useState", 3303 | "State Management", 3304 | "typescript", 3305 | "immer" 3306 | ], 3307 | "repositoryUrl": "https://github.com/pelotom/use-methods", 3308 | "importStatement": "import useMethods from 'use-methods';", 3309 | "sourceUrl": "https://github.com/pelotom/use-methods/blob/master/src/index.ts" 3310 | }, 3311 | { 3312 | "name": "useForm", 3313 | "tags": [ 3314 | "state", 3315 | "Validation", 3316 | "Async", 3317 | "Form" 3318 | ], 3319 | "repositoryUrl": "https://github.com/bluebill1049/react-hook-form", 3320 | "importStatement": "import useForm from 'react-hook-form';" 3321 | }, 3322 | { 3323 | "name": "useEnhancedReducer", 3324 | "tags": [ 3325 | "reducer", 3326 | "middleware" 3327 | ], 3328 | "repositoryUrl": "https://github.com/pret-a-porter/use-enhanced-reducer", 3329 | "importStatement": "import useEnhancedReducer from 'use-enhanced-reducer';" 3330 | }, 3331 | { 3332 | "name": "useAxiosRequest", 3333 | "tags": [ 3334 | "axios", 3335 | "network", 3336 | "http", 3337 | "use-http", 3338 | "fetch" 3339 | ], 3340 | "repositoryUrl": "https://github.com/Turanchoks/use-axios-request", 3341 | "importStatement": "import { useAxiosRequest } from 'use-axios-request';" 3342 | }, 3343 | { 3344 | "name": "useQueryState", 3345 | "tags": [ 3346 | "State Management", 3347 | "state", 3348 | "URL", 3349 | "Query String", 3350 | "typescript", 3351 | "router" 3352 | ], 3353 | "repositoryUrl": "https://github.com/xiel/use-location-state", 3354 | "importStatement": "import { useQueryState } from 'use-location-state';" 3355 | }, 3356 | { 3357 | "name": "useFile", 3358 | "tags": [ 3359 | "File", 3360 | "Blob" 3361 | ], 3362 | "repositoryUrl": "https://github.com/caasi/hooks", 3363 | "importStatement": "import { useFile } from '@caasi/hooks';" 3364 | }, 3365 | { 3366 | "name": "useObjectURL", 3367 | "tags": [ 3368 | "Blob" 3369 | ], 3370 | "repositoryUrl": "https://github.com/caasi/hooks", 3371 | "importStatement": "import { useObjectURL } from '@caasi/hooks';" 3372 | }, 3373 | { 3374 | "name": "useImageData", 3375 | "tags": [ 3376 | "Canvas", 3377 | "ImageData" 3378 | ], 3379 | "repositoryUrl": "https://github.com/caasi/hooks", 3380 | "importStatement": "import { useImageData } from '@caasi/hooks';" 3381 | }, 3382 | { 3383 | "name": "useImageFile", 3384 | "tags": [ 3385 | "File", 3386 | "Blob", 3387 | "ImageData" 3388 | ], 3389 | "repositoryUrl": "https://github.com/caasi/hooks", 3390 | "importStatement": "import { useImageFile } from '@caasi/hooks';" 3391 | }, 3392 | { 3393 | "name": "useLeafletMap", 3394 | "tags": [ 3395 | "leaflet", 3396 | "map" 3397 | ], 3398 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletmap", 3399 | "importStatement": "import { useLeafletMap } from 'use-leaflet';" 3400 | }, 3401 | { 3402 | "name": "useLeafletZoom", 3403 | "tags": [ 3404 | "leaflet", 3405 | "map", 3406 | "zoom" 3407 | ], 3408 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletzoom", 3409 | "importStatement": "import { useLeafletZoom } from 'use-leaflet';" 3410 | }, 3411 | { 3412 | "name": "useLeafletBounds", 3413 | "tags": [ 3414 | "leaflet", 3415 | "map", 3416 | "bounds" 3417 | ], 3418 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletbounds", 3419 | "importStatement": "import { useLeafletBounds } from 'use-leaflet';" 3420 | }, 3421 | { 3422 | "name": "useLeafletCenter", 3423 | "tags": [ 3424 | "leaflet", 3425 | "map", 3426 | "center" 3427 | ], 3428 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletcenter", 3429 | "importStatement": "import { useLeafletCenter } from 'use-leaflet';" 3430 | }, 3431 | { 3432 | "name": "useLeafletIsMoving", 3433 | "tags": [ 3434 | "leaflet", 3435 | "map", 3436 | "moving" 3437 | ], 3438 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletismoving", 3439 | "importStatement": "import { useLeafletIsMoving } from 'use-leaflet';" 3440 | }, 3441 | { 3442 | "name": "useLeafletIsZooming", 3443 | "tags": [ 3444 | "leaflet", 3445 | "map", 3446 | "zooming" 3447 | ], 3448 | "repositoryUrl": "https://github.com/vadzim/use-leaflet#useleafletiszooming", 3449 | "importStatement": "import { useLeafletIsZooming } from 'use-leaflet';" 3450 | }, 3451 | { 3452 | "name": "useMetaTags", 3453 | "tags": [ 3454 | "meta", 3455 | "metatag" 3456 | ], 3457 | "repositoryUrl": "https://github.com/lordgiotto/react-metatags-hook", 3458 | "importStatement": "import useMetaTags from 'react-metatags-hook';", 3459 | "sourceUrl": "https://github.com/lordgiotto/react-metatags-hook/raw/master/src/index.ts" 3460 | }, 3461 | { 3462 | "name": "useRefScroller", 3463 | "tags": [ 3464 | "scroll" 3465 | ], 3466 | "repositoryUrl": "https://github.com/dimitar-nikovski/use-ref-scroller", 3467 | "importStatement": "import useRefScroller from 'use-ref-scroller';", 3468 | "sourceUrl": "https://github.com/dimitar-nikovski/use-ref-scroller/blob/master/src/useRefScroller.ts" 3469 | }, 3470 | { 3471 | "name": "useScript", 3472 | "tags": [ 3473 | "script", 3474 | "loader", 3475 | "typescript" 3476 | ], 3477 | "repositoryUrl": "https://github.com/hupe1980/react-script-hook", 3478 | "importStatement": "import useScript from 'react-script-hook';" 3479 | }, 3480 | { 3481 | "name": "useIsMounted", 3482 | "tags": [ 3483 | "mounted", 3484 | "typescript" 3485 | ], 3486 | "repositoryUrl": "https://github.com/hupe1980/react-is-mounted-hook", 3487 | "importStatement": "import useIsMounted from 'react-is-mounted-hook';" 3488 | }, 3489 | { 3490 | "name": "useSyncScroll", 3491 | "tags": [ 3492 | "sync", 3493 | "synchronized", 3494 | "scroll", 3495 | "scrolling", 3496 | "dom", 3497 | "elements" 3498 | ], 3499 | "repositoryUrl": "https://github.com/agorf/react-use-sync-scroll", 3500 | "importStatement": "import useSyncScroll from 'react-use-sync-scroll';", 3501 | "sourceUrl": "https://raw.githubusercontent.com/agorf/react-use-sync-scroll/master/index.js" 3502 | }, 3503 | { 3504 | "name": "useWebShare", 3505 | "tags": [ 3506 | "web share api", 3507 | "native share" 3508 | ], 3509 | "repositoryUrl": "https://github.com/BoyWithSilverWings/react-use-web-share", 3510 | "importStatement": "import useWebShare from 'react-use-web-share';" 3511 | }, 3512 | { 3513 | "name": "useSwipeable", 3514 | "tags": [ 3515 | "swipe", 3516 | "touch", 3517 | "swipeable" 3518 | ], 3519 | "repositoryUrl": "https://github.com/dogfessional/react-swipeable", 3520 | "importStatement": "import { useSwipeable } from 'react-swipeable';", 3521 | "sourceUrl": "https://raw.githubusercontent.com/dogfessional/react-swipeable/master/src/index.js" 3522 | }, 3523 | { 3524 | "name": "useRecaptcha", 3525 | "tags": [ 3526 | "recaptcha", 3527 | "grecaptcha", 3528 | "v3", 3529 | "typescript" 3530 | ], 3531 | "repositoryUrl": "https://github.com/hupe1980/react-recaptcha-hook", 3532 | "importStatement": "import useRecaptcha, { Badge } from 'react-recaptcha-hook';" 3533 | }, 3534 | { 3535 | "name": "useStateSnapshots", 3536 | "tags": [ 3537 | "undo", 3538 | "history", 3539 | "State Management", 3540 | "useState" 3541 | ], 3542 | "repositoryUrl": "https://github.com/haydn/use-state-snapshots", 3543 | "importStatement": "import useStateSnapshots from 'use-state-snapshots';" 3544 | }, 3545 | { 3546 | "name": "useApi", 3547 | "tags": [ 3548 | "Fetch", 3549 | "Axios", 3550 | "HTTP", 3551 | "ajax", 3552 | "API", 3553 | "network" 3554 | ], 3555 | "repositoryUrl": "https://github.com/swrichards/use-http-api", 3556 | "importStatement": "import useApi from 'use-http-api';" 3557 | }, 3558 | { 3559 | "name": "useContextMenu", 3560 | "tags": [ 3561 | "context-menu", 3562 | "right click" 3563 | ], 3564 | "repositoryUrl": "https://github.com/cluk3/use-context-menu", 3565 | "importStatement": "import useContextMenu from 'react-use-context-menu';", 3566 | "sourceUrl": "https://raw.githubusercontent.com/cluk3/use-context-menu/master/src/useContextMenu.js" 3567 | }, 3568 | { 3569 | "name": "useFileInput", 3570 | "tags": [ 3571 | "File", 3572 | "Input" 3573 | ], 3574 | "repositoryUrl": "https://github.com/rot1024/use-file-input", 3575 | "importStatement": "import useFileInput from 'use-file-input';" 3576 | }, 3577 | { 3578 | "name": "useStore", 3579 | "tags": [ 3580 | "store", 3581 | "state management", 3582 | "state", 3583 | "model" 3584 | ], 3585 | "repositoryUrl": "https://github.com/awmleer/reto", 3586 | "importStatement": "import {useStore} from 'reto';" 3587 | }, 3588 | { 3589 | "name": "usePersistedReducer", 3590 | "tags": [ 3591 | "useReducer", 3592 | "Local Storage", 3593 | "Session Storage", 3594 | "Persist", 3595 | "Reducer" 3596 | ], 3597 | "repositoryUrl": "https://github.com/johnayeni/use-persisted-reducer", 3598 | "importStatement": "import createPersistedReducer from 'use-persisted-reducer';" 3599 | }, 3600 | { 3601 | "name": "useSelectors", 3602 | "tags": [ 3603 | "redux", 3604 | "State Management" 3605 | ], 3606 | "repositoryUrl": "https://github.com/qest-cz/use-selectors", 3607 | "importStatement": "import useSelectors from '@qest/use-selectors';" 3608 | }, 3609 | { 3610 | "name": "useResource", 3611 | "tags": [ 3612 | "Async", 3613 | "Fetch", 3614 | "Load Data", 3615 | "Suspense", 3616 | "Data Fetching", 3617 | "Entity", 3618 | "API", 3619 | "TypeScript" 3620 | ], 3621 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3622 | "importStatement": "import { useResource } from 'rest-hooks';", 3623 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useResource.ts" 3624 | }, 3625 | { 3626 | "name": "useFetcher", 3627 | "tags": [ 3628 | "Async", 3629 | "Fetch", 3630 | "Load Data", 3631 | "Suspense", 3632 | "Data Fetching", 3633 | "Entity", 3634 | "API", 3635 | "TypeScript" 3636 | ], 3637 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3638 | "importStatement": "import { useFetcher } from 'rest-hooks';", 3639 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useFetcher.ts" 3640 | }, 3641 | { 3642 | "name": "useCache", 3643 | "tags": [ 3644 | "Async", 3645 | "Fetch", 3646 | "Load Data", 3647 | "Suspense", 3648 | "Data Fetching", 3649 | "Entity", 3650 | "API", 3651 | "TypeScript" 3652 | ], 3653 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3654 | "importStatement": "import { useCache } from 'rest-hooks';", 3655 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useCache.ts" 3656 | }, 3657 | { 3658 | "name": "useSubscription", 3659 | "tags": [ 3660 | "Async", 3661 | "Fetch", 3662 | "Load Data", 3663 | "Suspense", 3664 | "Data Fetching", 3665 | "Entity", 3666 | "API", 3667 | "TypeScript" 3668 | ], 3669 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3670 | "importStatement": "import { useSubscription } from 'rest-hooks';", 3671 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useSubscription.ts" 3672 | }, 3673 | { 3674 | "name": "useRetrieve", 3675 | "tags": [ 3676 | "Async", 3677 | "Fetch", 3678 | "Load Data", 3679 | "Suspense", 3680 | "Data Fetching", 3681 | "Entity", 3682 | "API", 3683 | "TypeScript" 3684 | ], 3685 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3686 | "importStatement": "import { useRetrieve } from 'rest-hooks';", 3687 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useRetrieve.ts" 3688 | }, 3689 | { 3690 | "name": "useInvalidator", 3691 | "tags": [ 3692 | "Async", 3693 | "Fetch", 3694 | "Load Data", 3695 | "Suspense", 3696 | "Data Fetching", 3697 | "Entity", 3698 | "API", 3699 | "TypeScript" 3700 | ], 3701 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3702 | "importStatement": "import { useInvalidator } from 'rest-hooks';", 3703 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useInvalidator.ts" 3704 | }, 3705 | { 3706 | "name": "useResetter", 3707 | "tags": [ 3708 | "Async", 3709 | "Fetch", 3710 | "Load Data", 3711 | "Suspense", 3712 | "Data Fetching", 3713 | "Entity", 3714 | "API", 3715 | "TypeScript" 3716 | ], 3717 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 3718 | "importStatement": "import { useResetter } from 'rest-hooks';", 3719 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/rest-hooks/src/react-integration/hooks/useResetter.ts" 3720 | }, 3721 | { 3722 | "name": "useQrcode", 3723 | "tags": [ 3724 | "qrcode", 3725 | "reader", 3726 | "decoder", 3727 | "comlink", 3728 | "webworker", 3729 | "zxing" 3730 | ], 3731 | "repositoryUrl": "https://github.com/pocesar/react-use-qrcode", 3732 | "importStatement": "import useQrcode from 'react-use-qrcode';" 3733 | }, 3734 | { 3735 | "name": "useAdjustColor", 3736 | "tags": [ 3737 | "UI", 3738 | "Theme" 3739 | ], 3740 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3741 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useAdjustColor.js", 3742 | "importStatement": "import { useAdjustColor } from 'react-recipes';" 3743 | }, 3744 | { 3745 | "name": "useArray", 3746 | "tags": [ 3747 | "State Management" 3748 | ], 3749 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3750 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useArray.js", 3751 | "importStatement": "import { useArray } from 'react-recipes';" 3752 | }, 3753 | { 3754 | "name": "useAsync", 3755 | "tags": [ 3756 | "Side-effect", 3757 | "Async", 3758 | "promise" 3759 | ], 3760 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3761 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useAsync.js", 3762 | "importStatement": "import { useAsync } from 'react-recipes';" 3763 | }, 3764 | { 3765 | "name": "useCookie", 3766 | "tags": [ 3767 | "LocalStorage", 3768 | "Persistence" 3769 | ], 3770 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3771 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useAsync.js", 3772 | "importStatement": "import { useAsync } from 'react-recipes';" 3773 | }, 3774 | { 3775 | "name": "useCopyClipboard", 3776 | "tags": [ 3777 | "Copy", 3778 | "Clipboard" 3779 | ], 3780 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3781 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useCopyClipboard.js", 3782 | "importStatement": "import { useCopyClipboard } from 'react-recipes';" 3783 | }, 3784 | { 3785 | "name": "useDarkMode", 3786 | "tags": [ 3787 | "DarkMode", 3788 | "Theme" 3789 | ], 3790 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3791 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useDarkMode.js", 3792 | "importStatement": "import { useDarkMode } from 'react-recipes';" 3793 | }, 3794 | { 3795 | "name": "useDebounce", 3796 | "tags": [ 3797 | "Debounce" 3798 | ], 3799 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3800 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useDebounce.js", 3801 | "importStatement": "import { useDebounce } from 'react-recipes';" 3802 | }, 3803 | { 3804 | "name": "useDimensions", 3805 | "tags": [ 3806 | "Dimensions", 3807 | "Layout", 3808 | "Height", 3809 | "Width" 3810 | ], 3811 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3812 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useDimensions.js", 3813 | "importStatement": "import { useDimensions } from 'react-recipes';" 3814 | }, 3815 | { 3816 | "name": "useEventListener", 3817 | "tags": [ 3818 | "EventListener", 3819 | "Events" 3820 | ], 3821 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3822 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useEventListener.js", 3823 | "importStatement": "import { useEventListener } from 'react-recipes';" 3824 | }, 3825 | { 3826 | "name": "useFullScreen", 3827 | "tags": [ 3828 | "Web API" 3829 | ], 3830 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3831 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useEventListener.js", 3832 | "importStatement": "import { useEventListener } from 'react-recipes';" 3833 | }, 3834 | { 3835 | "name": "useGeolocation", 3836 | "tags": [ 3837 | "Sensor", 3838 | "Web API", 3839 | "Geo", 3840 | "Location", 3841 | "Geolocation" 3842 | ], 3843 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3844 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useGeolocation.js", 3845 | "importStatement": "import { useGeolocation } from 'react-recipes';" 3846 | }, 3847 | { 3848 | "name": "useHover", 3849 | "tags": [ 3850 | "Hover", 3851 | "Sensor", 3852 | "UI", 3853 | "Mouse" 3854 | ], 3855 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3856 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useHover.js", 3857 | "importStatement": "import { useHover } from 'react-recipes';" 3858 | }, 3859 | { 3860 | "name": "useInterval", 3861 | "tags": [ 3862 | "Interval", 3863 | "Timer", 3864 | "Time" 3865 | ], 3866 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3867 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useInterval.js", 3868 | "importStatement": "import { useInterval } from 'react-recipes';" 3869 | }, 3870 | { 3871 | "name": "useIsClient", 3872 | "tags": [ 3873 | "server-side-rendering", 3874 | "browser", 3875 | "client", 3876 | "server", 3877 | "server-side" 3878 | ], 3879 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3880 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useIsClient.js", 3881 | "importStatement": "import { useIsClient } from 'react-recipes';" 3882 | }, 3883 | { 3884 | "name": "useKeyPress", 3885 | "tags": [ 3886 | "Sensor", 3887 | "Event", 3888 | "Keyboard" 3889 | ], 3890 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3891 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useKeyPress.js", 3892 | "importStatement": "import { useKeyPress } from 'react-recipes';" 3893 | }, 3894 | { 3895 | "name": "useLocalStorage", 3896 | "tags": [ 3897 | "LocalStorage" 3898 | ], 3899 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3900 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useLocalStorage.js", 3901 | "importStatement": "import { useLocalStorage } from 'react-recipes';" 3902 | }, 3903 | { 3904 | "name": "useLockBodyScroll", 3905 | "tags": [ 3906 | "Side-effect", 3907 | "Scroll", 3908 | "UI" 3909 | ], 3910 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3911 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useLockBodyScroll.js", 3912 | "importStatement": "import { useLockBodyScroll } from 'react-recipes';" 3913 | }, 3914 | { 3915 | "name": "useMedia", 3916 | "tags": [ 3917 | "Sensor", 3918 | "Web API", 3919 | "Media-Query", 3920 | "CSS" 3921 | ], 3922 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3923 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useMedia.js", 3924 | "importStatement": "import { useMedia } from 'react-recipes';" 3925 | }, 3926 | { 3927 | "name": "useMultiKeyPress", 3928 | "tags": [ 3929 | "Sensor", 3930 | "Event", 3931 | "Keyboard" 3932 | ], 3933 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3934 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useMultiKeyPress.js", 3935 | "importStatement": "import { useMultiKeyPress } from 'react-recipes';" 3936 | }, 3937 | { 3938 | "name": "useNotification", 3939 | "tags": [ 3940 | "Web API" 3941 | ], 3942 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3943 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useNotification.js", 3944 | "importStatement": "import { useNotification } from 'react-recipes';" 3945 | }, 3946 | { 3947 | "name": "useOnClickOutside", 3948 | "tags": [ 3949 | "Click", 3950 | "UI", 3951 | "Touch" 3952 | ], 3953 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3954 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useOnClickOutside.js", 3955 | "importStatement": "import { useOnClickOutside } from 'react-recipes';" 3956 | }, 3957 | { 3958 | "name": "useOnlineStatus", 3959 | "tags": [ 3960 | "Network" 3961 | ], 3962 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3963 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useOnlineStatus.js", 3964 | "importStatement": "import { useOnlineStatus } from 'react-recipes';" 3965 | }, 3966 | { 3967 | "name": "usePrevious", 3968 | "tags": [ 3969 | "State Management" 3970 | ], 3971 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3972 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/usePrevious.js", 3973 | "importStatement": "import { usePrevious } from 'react-recipes';" 3974 | }, 3975 | { 3976 | "name": "useScript", 3977 | "tags": [ 3978 | "Script", 3979 | "Loader" 3980 | ], 3981 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3982 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useScript.js", 3983 | "importStatement": "import { useScript } from 'react-recipes';" 3984 | }, 3985 | { 3986 | "name": "useSpeechRecognition", 3987 | "tags": [ 3988 | "Web API", 3989 | "Speech", 3990 | "UI", 3991 | "Audio" 3992 | ], 3993 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 3994 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useSpeechRecognition.js", 3995 | "importStatement": "import { useSpeechRecognition } from 'react-recipes';" 3996 | }, 3997 | { 3998 | "name": "useSpeechSynthesis", 3999 | "tags": [ 4000 | "Web API", 4001 | "Speech", 4002 | "UI", 4003 | "Audio" 4004 | ], 4005 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4006 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useSpeechSynthesis.js", 4007 | "importStatement": "import { useSpeechSynthesis } from 'react-recipes';" 4008 | }, 4009 | { 4010 | "name": "useThrottle", 4011 | "tags": [ 4012 | "Throttle" 4013 | ], 4014 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4015 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useThrottle.js", 4016 | "importStatement": "import { useThrottle } from 'react-recipes';" 4017 | }, 4018 | { 4019 | "name": "useWhyDidYouUpdate", 4020 | "tags": [ 4021 | "Console", 4022 | "Log" 4023 | ], 4024 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4025 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useWhyDidYouUpdate.js", 4026 | "importStatement": "import { useWhyDidYouUpdate } from 'react-recipes';" 4027 | }, 4028 | { 4029 | "name": "useWindowScroll", 4030 | "tags": [ 4031 | "Sensor", 4032 | "Web API", 4033 | "UI", 4034 | "Window", 4035 | "Scroll" 4036 | ], 4037 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4038 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useWindowScroll.js", 4039 | "importStatement": "import { useWindowScroll } from 'react-recipes';" 4040 | }, 4041 | { 4042 | "name": "useWindowSize", 4043 | "tags": [ 4044 | "Layout", 4045 | "Size", 4046 | "Window" 4047 | ], 4048 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4049 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useWindowSize.js", 4050 | "importStatement": "import { useWindowSize } from 'react-recipes';" 4051 | }, 4052 | { 4053 | "name": "useWorker", 4054 | "tags": [ 4055 | "Web API" 4056 | ], 4057 | "repositoryUrl": "https://github.com/craig1123/react-recipes", 4058 | "sourceUrl": "https://github.com/craig1123/react-recipes/blob/master/src/useWorker.js", 4059 | "importStatement": "import { useWorker } from 'react-recipes';" 4060 | }, 4061 | { 4062 | "name": "useEnhancedReducer", 4063 | "tags": [ 4064 | "Middleware", 4065 | "Orchestration", 4066 | "Async", 4067 | "Redux", 4068 | "Concurrent mode", 4069 | "TypeScript" 4070 | ], 4071 | "repositoryUrl": "https://github.com/coinbase/rest-hooks", 4072 | "importStatement": "import useEnhancedReducer from '@rest-hooks/use-enhanced-reducer';", 4073 | "sourceUrl": "https://github.com/coinbase/rest-hooks/blob/master/packages/use-enhanced-reducer/src/useEnhancedReducer.ts" 4074 | }, 4075 | { 4076 | "name": "useLayout", 4077 | "tags": [ 4078 | "Layout" 4079 | ], 4080 | "repositoryUrl": "https://github.com/ytiurin/react-hook-layout", 4081 | "importStatement": "import { useLayout } from 'react-hook-layout';", 4082 | "sourceUrl": "https://github.com/ytiurin/react-hook-layout/blob/master/src/index.js" 4083 | }, 4084 | { 4085 | "name": "useSplitInChunks", 4086 | "tags": [ 4087 | "Split", 4088 | "Chunk" 4089 | ], 4090 | "repositoryUrl": "https://github.com/LagunaISW/use-split-in-chunks", 4091 | "importStatement": "import { useSplitInChunks } from '@lagunaisw/use-split-in-chunks';", 4092 | "sourceUrl": "https://github.com/LagunaISW/use-split-in-chunks/blob/master/src/index.tsx" 4093 | }, 4094 | { 4095 | "name": "useRecorder", 4096 | "tags": [ 4097 | "Audio" 4098 | ], 4099 | "repositoryUrl": "https://github.com/orizens/use-recorder", 4100 | "importStatement": "import { useRecorder } from 'user-recorder';", 4101 | "sourceUrl": "https://github.com/orizens/use-recorder/blob/master/src/index.tsx" 4102 | }, 4103 | { 4104 | "name": "useSfx", 4105 | "tags": [ 4106 | "useEffect", 4107 | "UI", 4108 | "TypeScript", 4109 | "Side-effect", 4110 | "Utility" 4111 | ], 4112 | "repositoryUrl": "https://github.com/rafaelgandi/useSfx-react-hook", 4113 | "importStatement": "import useSfx from './useSfx.ts';", 4114 | "sourceUrl": "https://raw.githubusercontent.com/rafaelgandi/useSfx-react-hook/main/useSfx.ts" 4115 | } 4116 | ] 4117 | -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | tmp -------------------------------------------------------------------------------- /scripts/analyzeSource.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const _ = require("highland"); 3 | const { fetchSource, extractImportesExports, createCache } = require("./utils"); 4 | const cache = createCache("./tmp"); 5 | const hooks = require("../hooks.json"); 6 | 7 | _(hooks) 8 | .flatMap(fetchSource({ cache })) 9 | .map(h => { 10 | if (!h.source) return h; 11 | try { 12 | delete h.subHooks; 13 | 14 | const { 15 | exportedHooks, 16 | importedHooks, 17 | localImports, 18 | npmImports 19 | } = extractImportesExports({ code: h.source, filename: h.sourceUrl }); 20 | 21 | if (exportedHooks.length > 1) { 22 | console.warn(`Contains more than one hook ${h.sourceUrl}`); 23 | delete h.source; 24 | return h; 25 | } 26 | if (importedHooks.length === 0) { 27 | // warning 28 | } 29 | if (localImports === 0) { 30 | // self contained 31 | } 32 | console.log( 33 | `${h.name} constructed from ${importedHooks.map(x => x[1]).join(", ")}${ 34 | npmImports.length > 0 ? " and " : "" 35 | }${npmImports.map(x => x[1]).join(", ")}` 36 | ); 37 | delete h.source; 38 | return importedHooks.length > 0 39 | ? { 40 | ...h, 41 | subHooks: importedHooks.map(([source, hook]) => 42 | source.indexOf(".") === 0 || source === "react" 43 | ? hook 44 | : `${source}.${hook}` 45 | ) 46 | } 47 | : h; 48 | } catch (e) { 49 | console.warn(`Can't parse ${h.sourceUrl}`); 50 | console.log(e.message); 51 | } 52 | delete h.source; 53 | return h; 54 | }) 55 | .toArray(result => 56 | fs.writeFileSync("../hooks.json", JSON.stringify(result, null, 2)) 57 | ); 58 | -------------------------------------------------------------------------------- /scripts/guessSource.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const _ = require("highland"); 3 | const { 4 | fetchWithCache, 5 | createCache, 6 | wrap, 7 | extractImportesExports 8 | } = require("./utils"); 9 | const cache = createCache("./tmp"); 10 | const hooks = require("../hooks.json"); 11 | 12 | const options = [ 13 | ({ repositoryUrl, name }) => [ 14 | `${repositoryUrl}/raw/master/src/${name}.js`, 15 | 0.9 16 | ], 17 | ({ repositoryUrl, name }) => [ 18 | `${repositoryUrl}/raw/master/src/${name}.ts`, 19 | 0.9 20 | ], 21 | ({ repositoryUrl, name }) => [ 22 | `${repositoryUrl}/raw/master/src/${name}.tsx`, 23 | 0.9 24 | ], 25 | ({ repositoryUrl, name }) => [ 26 | `${repositoryUrl}/raw/master/src/${name}.jsx`, 27 | 0.9 28 | ], 29 | ({ repositoryUrl, name }) => [ 30 | `${repositoryUrl}/raw/master/src/hooks/${name}.js`, 31 | 0.9 32 | ], 33 | ({ repositoryUrl, name }) => [ 34 | `${repositoryUrl}/raw/master/src/hooks/${name}.ts`, 35 | 0.9 36 | ], 37 | ({ repositoryUrl, name }) => [ 38 | `${repositoryUrl}/raw/master/src/hooks/${name}.tsx`, 39 | 0.9 40 | ], 41 | ({ repositoryUrl, name }) => [ 42 | `${repositoryUrl}/raw/master/src/hooks/${name}.jsx`, 43 | 0.9 44 | ], 45 | ({ repositoryUrl }) => [`${repositoryUrl}/raw/master/src/index.js`, 0.1], 46 | ({ repositoryUrl }) => [`${repositoryUrl}/raw/master/src/index.ts`, 0.1], 47 | ({ repositoryUrl }) => [`${repositoryUrl}/raw/master/index.js`, 0.1], 48 | ({ repositoryUrl }) => [`${repositoryUrl}/raw/master/index.ts`, 0.1] 49 | ]; 50 | 51 | const guessSource = async hook => { 52 | const { sourceUrl, name } = hook; 53 | if (sourceUrl) return hook; 54 | 55 | for (let guess of options) { 56 | const [url, probability] = guess(hook); 57 | 58 | delete hook.sourceUrl; 59 | 60 | const result = await fetchWithCache(url, { cache, cacheErrors: true }); 61 | if (result.status === 200) { 62 | if (probability >= 0.8) { 63 | return { 64 | ...hook, 65 | sourceUrl: url 66 | }; 67 | } 68 | try { 69 | const { exportedHooks, importedHooks } = extractImportesExports({ 70 | code: result.text, 71 | filename: url 72 | }); 73 | if (exportedHooks.length >= 1) { 74 | if (exportedHooks.includes(name)) { 75 | return { 76 | ...hook, 77 | sourceUrl: url 78 | }; 79 | } else { 80 | console.log("Found named imports, but didn't find the name"); 81 | } 82 | } 83 | if (importedHooks.filter(([lib]) => lib === "react").length > 0) { 84 | // default export 85 | return { 86 | ...hook, 87 | sourceUrl: url 88 | }; 89 | } else { 90 | console.log( 91 | `This file doesn't import hooks - probably not a hook or CJS file ${url}` 92 | ); 93 | } 94 | } catch (e) { 95 | console.log(`Can't parse ${url}`); 96 | console.log(e.message); 97 | } 98 | } 99 | } 100 | 101 | return hook; 102 | }; 103 | 104 | _(hooks) 105 | .flatMap(wrap(guessSource)) 106 | .toArray(result => 107 | fs.writeFileSync("../hooks.json", JSON.stringify(result, null, 2)) 108 | ); 109 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "@babel/core": "^7.3.3", 8 | "encoding-down": "^6.0.1", 9 | "highland": "^2.13.3", 10 | "leveldown": "^4.0.1", 11 | "levelup": "^4.0.0", 12 | "node-fetch": "^2.3.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/utils.js: -------------------------------------------------------------------------------- 1 | const _ = require("highland"); 2 | const fetch = require("node-fetch"); 3 | // wrap async function into a stream 4 | const wrap = asyncFunction => arg => _(asyncFunction(arg)); 5 | 6 | const levelup = require("levelup"); 7 | const leveldown = require("leveldown"); 8 | const encode = require("encoding-down"); 9 | 10 | createCache = path => 11 | levelup(encode(leveldown(path), { valueEncoding: "json" })); 12 | 13 | const get = (db, key) => 14 | db.get(key).catch(err => { 15 | if (err.notFound) return undefined; 16 | else return Promise.reject(err); 17 | }); 18 | 19 | const fetchWithCache = async (sourceUrl, { cache, cacheErrors }) => { 20 | let cacheEntry = await get(cache, sourceUrl); 21 | if (!cacheEntry) { 22 | const response = await fetch(sourceUrl); 23 | const { headers, status } = response; 24 | if (response.ok) { 25 | const text = await response.text(); 26 | cacheEntry = { 27 | text, 28 | status, 29 | etag: headers.get("etag"), 30 | expires: headers.get("expires") 31 | }; 32 | } else { 33 | cacheEntry = { 34 | text: undefined, 35 | status, 36 | etag: headers.get("etag"), 37 | expires: headers.get("expires") 38 | }; 39 | } 40 | await cache.put(sourceUrl, cacheEntry); 41 | } else if (cacheErrors) { 42 | // do nothing 43 | } else { 44 | if (new Date(cacheEntry.expires) > new Date()) { 45 | // console.log('cache is fresh'); 46 | } else { 47 | const response = await fetch(sourceUrl); 48 | const { headers } = response; 49 | if (headers.get("etag") === cacheEntry.etag) { 50 | cacheEntry = { 51 | ...cacheEntry, 52 | expires: headers.get("expires") 53 | }; 54 | } else { 55 | const text = await response.text(); 56 | cacheEntry = { 57 | text, 58 | etag: headers.get("etag"), 59 | expires: headers.get("expires") 60 | }; 61 | } 62 | await cache.put(sourceUrl, cacheEntry); 63 | } 64 | } 65 | 66 | return cacheEntry; 67 | }; 68 | 69 | fetchSource = ({ cache }) => 70 | wrap(async h => { 71 | if (!h.sourceUrl) return h; 72 | const result = await fetchWithCache(h.sourceUrl, { cache }); 73 | h.source = result.text; 74 | return h; 75 | }); 76 | 77 | const isHook = name => name.indexOf("use") === 0; 78 | 79 | // this is false for some cases 80 | const isLocal = path => path.indexOf(".") === 0; 81 | 82 | const babel = require("@babel/core"); 83 | 84 | const extractImportesExports = ({ 85 | code, 86 | parserOpts = {}, 87 | filename = "indexed.js" 88 | }) => { 89 | const isTypescript = filename.indexOf(".ts") > -1; 90 | parserOpts = isTypescript 91 | ? { 92 | plugins: [["typescript", { isTSX: true }], "dynamicImport"], 93 | ...parserOpts 94 | } 95 | : { 96 | plugins: ["flow", "jsx", "dynamicImport"], 97 | ...parserOpts 98 | }; 99 | 100 | const exportedHooks = []; 101 | const importedHooks = []; 102 | const localImports = []; 103 | const npmImports = []; 104 | 105 | const ast = babel.parse(code, { 106 | filename, 107 | parserOpts 108 | }); 109 | const file = new babel.File(parserOpts, { code, ast }); 110 | 111 | for (let item of file.path.get("body")) { 112 | if (item.isExportDeclaration()) { 113 | let namedExports = []; 114 | if (item.node.declaration && item.node.declaration.id) { 115 | namedExports.push(item.node.declaration.id); 116 | } 117 | if (item.node.declaration && item.node.declaration.declarations) { 118 | namedExports = namedExports.concat(item.node.declaration.declarations.map(x => x.id)); 119 | } 120 | namedExports.forEach(namedExport => { 121 | if (namedExport && isHook(namedExport.loc.identifierName)) { 122 | exportedHooks.push(namedExport.loc.identifierName); 123 | } 124 | }); 125 | } 126 | 127 | if (item.isImportDeclaration()) { 128 | const namedImports = item.node.specifiers 129 | .filter(imp => imp.imported) 130 | .map(imp => imp.imported) 131 | .map(namedImport => namedImport.loc.identifierName); 132 | 133 | for (let imp of namedImports) { 134 | if (isHook(imp)) { 135 | importedHooks.push([item.node.source.value, imp]); 136 | } else if (isLocal(item.node.source.value)) { 137 | localImports.push([item.node.source.value, imp]); 138 | } else { 139 | npmImports.push([item.node.source.value, imp]); 140 | } 141 | } 142 | } 143 | } 144 | 145 | return { 146 | exportedHooks, 147 | importedHooks, 148 | localImports, 149 | npmImports 150 | }; 151 | }; 152 | 153 | module.exports = { 154 | extractImportesExports, 155 | fetchSource, 156 | fetchWithCache, 157 | createCache, 158 | wrap 159 | }; 160 | -------------------------------------------------------------------------------- /scripts/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.0.0" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" 8 | dependencies: 9 | "@babel/highlight" "^7.0.0" 10 | 11 | "@babel/core@^7.3.3": 12 | version "7.3.3" 13 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.3.tgz#d090d157b7c5060d05a05acaebc048bd2b037947" 14 | dependencies: 15 | "@babel/code-frame" "^7.0.0" 16 | "@babel/generator" "^7.3.3" 17 | "@babel/helpers" "^7.2.0" 18 | "@babel/parser" "^7.3.3" 19 | "@babel/template" "^7.2.2" 20 | "@babel/traverse" "^7.2.2" 21 | "@babel/types" "^7.3.3" 22 | convert-source-map "^1.1.0" 23 | debug "^4.1.0" 24 | json5 "^2.1.0" 25 | lodash "^4.17.11" 26 | resolve "^1.3.2" 27 | semver "^5.4.1" 28 | source-map "^0.5.0" 29 | 30 | "@babel/generator@^7.2.2", "@babel/generator@^7.3.3": 31 | version "7.3.3" 32 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.3.tgz#185962ade59a52e00ca2bdfcfd1d58e528d4e39e" 33 | dependencies: 34 | "@babel/types" "^7.3.3" 35 | jsesc "^2.5.1" 36 | lodash "^4.17.11" 37 | source-map "^0.5.0" 38 | trim-right "^1.0.1" 39 | 40 | "@babel/helper-function-name@^7.1.0": 41 | version "7.1.0" 42 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" 43 | dependencies: 44 | "@babel/helper-get-function-arity" "^7.0.0" 45 | "@babel/template" "^7.1.0" 46 | "@babel/types" "^7.0.0" 47 | 48 | "@babel/helper-get-function-arity@^7.0.0": 49 | version "7.0.0" 50 | resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" 51 | dependencies: 52 | "@babel/types" "^7.0.0" 53 | 54 | "@babel/helper-split-export-declaration@^7.0.0": 55 | version "7.0.0" 56 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" 57 | dependencies: 58 | "@babel/types" "^7.0.0" 59 | 60 | "@babel/helpers@^7.2.0": 61 | version "7.3.1" 62 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" 63 | dependencies: 64 | "@babel/template" "^7.1.2" 65 | "@babel/traverse" "^7.1.5" 66 | "@babel/types" "^7.3.0" 67 | 68 | "@babel/highlight@^7.0.0": 69 | version "7.0.0" 70 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" 71 | dependencies: 72 | chalk "^2.0.0" 73 | esutils "^2.0.2" 74 | js-tokens "^4.0.0" 75 | 76 | "@babel/parser@^7.2.2", "@babel/parser@^7.2.3", "@babel/parser@^7.3.3": 77 | version "7.3.3" 78 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87" 79 | 80 | "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": 81 | version "7.2.2" 82 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" 83 | dependencies: 84 | "@babel/code-frame" "^7.0.0" 85 | "@babel/parser" "^7.2.2" 86 | "@babel/types" "^7.2.2" 87 | 88 | "@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2": 89 | version "7.2.3" 90 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" 91 | dependencies: 92 | "@babel/code-frame" "^7.0.0" 93 | "@babel/generator" "^7.2.2" 94 | "@babel/helper-function-name" "^7.1.0" 95 | "@babel/helper-split-export-declaration" "^7.0.0" 96 | "@babel/parser" "^7.2.3" 97 | "@babel/types" "^7.2.2" 98 | debug "^4.1.0" 99 | globals "^11.1.0" 100 | lodash "^4.17.10" 101 | 102 | "@babel/types@^7.0.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3": 103 | version "7.3.3" 104 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.3.tgz#6c44d1cdac2a7625b624216657d5bc6c107ab436" 105 | dependencies: 106 | esutils "^2.0.2" 107 | lodash "^4.17.11" 108 | to-fast-properties "^2.0.0" 109 | 110 | abstract-leveldown@^6.0.0, abstract-leveldown@~6.0.0: 111 | version "6.0.1" 112 | resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.0.1.tgz#2d5dd4c26799a38b7ca52026b3b7e8e5283bd165" 113 | dependencies: 114 | level-concat-iterator "~2.0.0" 115 | xtend "~4.0.0" 116 | 117 | abstract-leveldown@~5.0.0: 118 | version "5.0.0" 119 | resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz#f7128e1f86ccabf7d2893077ce5d06d798e386c6" 120 | dependencies: 121 | xtend "~4.0.0" 122 | 123 | ansi-regex@^2.0.0: 124 | version "2.1.1" 125 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 126 | 127 | ansi-regex@^3.0.0: 128 | version "3.0.0" 129 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 130 | 131 | ansi-styles@^3.2.1: 132 | version "3.2.1" 133 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 134 | dependencies: 135 | color-convert "^1.9.0" 136 | 137 | aproba@^1.0.3: 138 | version "1.2.0" 139 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 140 | 141 | are-we-there-yet@~1.1.2: 142 | version "1.1.5" 143 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" 144 | dependencies: 145 | delegates "^1.0.0" 146 | readable-stream "^2.0.6" 147 | 148 | bindings@~1.3.0: 149 | version "1.3.1" 150 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5" 151 | 152 | bl@^1.0.0: 153 | version "1.2.2" 154 | resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" 155 | dependencies: 156 | readable-stream "^2.3.5" 157 | safe-buffer "^5.1.1" 158 | 159 | buffer-alloc-unsafe@^1.1.0: 160 | version "1.1.0" 161 | resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" 162 | 163 | buffer-alloc@^1.2.0: 164 | version "1.2.0" 165 | resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" 166 | dependencies: 167 | buffer-alloc-unsafe "^1.1.0" 168 | buffer-fill "^1.0.0" 169 | 170 | buffer-fill@^1.0.0: 171 | version "1.0.0" 172 | resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" 173 | 174 | chalk@^2.0.0: 175 | version "2.4.2" 176 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 177 | dependencies: 178 | ansi-styles "^3.2.1" 179 | escape-string-regexp "^1.0.5" 180 | supports-color "^5.3.0" 181 | 182 | chownr@^1.0.1: 183 | version "1.1.1" 184 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" 185 | 186 | code-point-at@^1.0.0: 187 | version "1.1.0" 188 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 189 | 190 | color-convert@^1.9.0: 191 | version "1.9.3" 192 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 193 | dependencies: 194 | color-name "1.1.3" 195 | 196 | color-name@1.1.3: 197 | version "1.1.3" 198 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 199 | 200 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 201 | version "1.1.0" 202 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 203 | 204 | convert-source-map@^1.1.0: 205 | version "1.6.0" 206 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" 207 | dependencies: 208 | safe-buffer "~5.1.1" 209 | 210 | core-util-is@~1.0.0: 211 | version "1.0.2" 212 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 213 | 214 | debug@^4.1.0: 215 | version "4.1.1" 216 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 217 | dependencies: 218 | ms "^2.1.1" 219 | 220 | decompress-response@^3.3.0: 221 | version "3.3.0" 222 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" 223 | dependencies: 224 | mimic-response "^1.0.0" 225 | 226 | deep-extend@^0.6.0: 227 | version "0.6.0" 228 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 229 | 230 | deferred-leveldown@~5.0.0: 231 | version "5.0.0" 232 | resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.0.0.tgz#28717f5da3c4e4dc42c367338e9596f04c5cb310" 233 | dependencies: 234 | abstract-leveldown "~6.0.0" 235 | inherits "^2.0.3" 236 | 237 | delegates@^1.0.0: 238 | version "1.0.0" 239 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 240 | 241 | detect-libc@^1.0.3: 242 | version "1.0.3" 243 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 244 | 245 | encoding-down@^6.0.1: 246 | version "6.0.1" 247 | resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.0.1.tgz#d8257c1842441f4fa3e90ed4d0790ad4540fa96c" 248 | dependencies: 249 | abstract-leveldown "^6.0.0" 250 | inherits "^2.0.3" 251 | level-codec "^9.0.0" 252 | level-errors "^2.0.0" 253 | 254 | end-of-stream@^1.0.0, end-of-stream@^1.1.0: 255 | version "1.4.1" 256 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" 257 | dependencies: 258 | once "^1.4.0" 259 | 260 | errno@~0.1.1: 261 | version "0.1.7" 262 | resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" 263 | dependencies: 264 | prr "~1.0.1" 265 | 266 | escape-string-regexp@^1.0.5: 267 | version "1.0.5" 268 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 269 | 270 | esutils@^2.0.2: 271 | version "2.0.2" 272 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 273 | 274 | expand-template@^1.0.2: 275 | version "1.1.1" 276 | resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" 277 | 278 | fast-future@~1.0.2: 279 | version "1.0.2" 280 | resolved "https://registry.yarnpkg.com/fast-future/-/fast-future-1.0.2.tgz#8435a9aaa02d79248d17d704e76259301d99280a" 281 | 282 | fs-constants@^1.0.0: 283 | version "1.0.0" 284 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 285 | 286 | gauge@~2.7.3: 287 | version "2.7.4" 288 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 289 | dependencies: 290 | aproba "^1.0.3" 291 | console-control-strings "^1.0.0" 292 | has-unicode "^2.0.0" 293 | object-assign "^4.1.0" 294 | signal-exit "^3.0.0" 295 | string-width "^1.0.1" 296 | strip-ansi "^3.0.1" 297 | wide-align "^1.1.0" 298 | 299 | github-from-package@0.0.0: 300 | version "0.0.0" 301 | resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" 302 | 303 | globals@^11.1.0: 304 | version "11.11.0" 305 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" 306 | 307 | has-flag@^3.0.0: 308 | version "3.0.0" 309 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 310 | 311 | has-unicode@^2.0.0: 312 | version "2.0.1" 313 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 314 | 315 | highland@^2.13.3: 316 | version "2.13.3" 317 | resolved "https://registry.yarnpkg.com/highland/-/highland-2.13.3.tgz#d3c841d9fa2416f6210ab0255ee1d0feae06d2af" 318 | dependencies: 319 | util-deprecate "^1.0.2" 320 | 321 | inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: 322 | version "2.0.3" 323 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 324 | 325 | ini@~1.3.0: 326 | version "1.3.5" 327 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 328 | 329 | is-fullwidth-code-point@^1.0.0: 330 | version "1.0.0" 331 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 332 | dependencies: 333 | number-is-nan "^1.0.0" 334 | 335 | is-fullwidth-code-point@^2.0.0: 336 | version "2.0.0" 337 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 338 | 339 | isarray@~1.0.0: 340 | version "1.0.0" 341 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 342 | 343 | js-tokens@^4.0.0: 344 | version "4.0.0" 345 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 346 | 347 | jsesc@^2.5.1: 348 | version "2.5.2" 349 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 350 | 351 | json5@^2.1.0: 352 | version "2.1.0" 353 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" 354 | dependencies: 355 | minimist "^1.2.0" 356 | 357 | level-codec@^9.0.0: 358 | version "9.0.0" 359 | resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.0.tgz#2d3a0e835c4aa8339ec63de3f5a37480b74a5f87" 360 | 361 | level-concat-iterator@~2.0.0: 362 | version "2.0.0" 363 | resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.0.tgz#20f20242f75307540c5819b768a76881a518627b" 364 | 365 | level-errors@^2.0.0, level-errors@~2.0.0: 366 | version "2.0.0" 367 | resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.0.tgz#2de5b566b62eef92f99e19be74397fbc512563fa" 368 | dependencies: 369 | errno "~0.1.1" 370 | 371 | level-iterator-stream@~4.0.0: 372 | version "4.0.0" 373 | resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.0.tgz#35ae79e714558ccf5d0c21075b2f25532bfe0270" 374 | dependencies: 375 | inherits "^2.0.1" 376 | readable-stream "^3.0.2" 377 | xtend "^4.0.0" 378 | 379 | leveldown@^4.0.1: 380 | version "4.0.1" 381 | resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-4.0.1.tgz#7bc3df93c9fa574feb39ce45a0c4073aa948cfef" 382 | dependencies: 383 | abstract-leveldown "~5.0.0" 384 | bindings "~1.3.0" 385 | fast-future "~1.0.2" 386 | nan "~2.10.0" 387 | prebuild-install "^4.0.0" 388 | 389 | levelup@^4.0.0: 390 | version "4.0.0" 391 | resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.0.0.tgz#87aa76d7ff2e4da641b3e90ef274061201adf3fa" 392 | dependencies: 393 | deferred-leveldown "~5.0.0" 394 | level-errors "~2.0.0" 395 | level-iterator-stream "~4.0.0" 396 | xtend "~4.0.0" 397 | 398 | lodash@^4.17.10, lodash@^4.17.11: 399 | version "4.17.15" 400 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 401 | 402 | mimic-response@^1.0.0: 403 | version "1.0.1" 404 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" 405 | 406 | minimist@0.0.8: 407 | version "0.0.8" 408 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 409 | 410 | minimist@^1.2.0: 411 | version "1.2.0" 412 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 413 | 414 | mkdirp@^0.5.1: 415 | version "0.5.1" 416 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 417 | dependencies: 418 | minimist "0.0.8" 419 | 420 | ms@^2.1.1: 421 | version "2.1.1" 422 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 423 | 424 | nan@~2.10.0: 425 | version "2.10.0" 426 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" 427 | 428 | node-abi@^2.2.0: 429 | version "2.7.1" 430 | resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.7.1.tgz#a8997ae91176a5fbaa455b194976e32683cda643" 431 | dependencies: 432 | semver "^5.4.1" 433 | 434 | node-fetch@^2.3.0: 435 | version "2.3.0" 436 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" 437 | 438 | noop-logger@^0.1.1: 439 | version "0.1.1" 440 | resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" 441 | 442 | npmlog@^4.0.1: 443 | version "4.1.2" 444 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 445 | dependencies: 446 | are-we-there-yet "~1.1.2" 447 | console-control-strings "~1.1.0" 448 | gauge "~2.7.3" 449 | set-blocking "~2.0.0" 450 | 451 | number-is-nan@^1.0.0: 452 | version "1.0.1" 453 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 454 | 455 | object-assign@^4.1.0: 456 | version "4.1.1" 457 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 458 | 459 | once@^1.3.1, once@^1.4.0: 460 | version "1.4.0" 461 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 462 | dependencies: 463 | wrappy "1" 464 | 465 | os-homedir@^1.0.1: 466 | version "1.0.2" 467 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 468 | 469 | path-parse@^1.0.6: 470 | version "1.0.6" 471 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 472 | 473 | prebuild-install@^4.0.0: 474 | version "4.0.0" 475 | resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-4.0.0.tgz#206ce8106ce5efa4b6cf062fc8a0a7d93c17f3a8" 476 | dependencies: 477 | detect-libc "^1.0.3" 478 | expand-template "^1.0.2" 479 | github-from-package "0.0.0" 480 | minimist "^1.2.0" 481 | mkdirp "^0.5.1" 482 | node-abi "^2.2.0" 483 | noop-logger "^0.1.1" 484 | npmlog "^4.0.1" 485 | os-homedir "^1.0.1" 486 | pump "^2.0.1" 487 | rc "^1.1.6" 488 | simple-get "^2.7.0" 489 | tar-fs "^1.13.0" 490 | tunnel-agent "^0.6.0" 491 | which-pm-runs "^1.0.0" 492 | 493 | process-nextick-args@~2.0.0: 494 | version "2.0.0" 495 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 496 | 497 | prr@~1.0.1: 498 | version "1.0.1" 499 | resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" 500 | 501 | pump@^1.0.0: 502 | version "1.0.3" 503 | resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" 504 | dependencies: 505 | end-of-stream "^1.1.0" 506 | once "^1.3.1" 507 | 508 | pump@^2.0.1: 509 | version "2.0.1" 510 | resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" 511 | dependencies: 512 | end-of-stream "^1.1.0" 513 | once "^1.3.1" 514 | 515 | rc@^1.1.6: 516 | version "1.2.8" 517 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 518 | dependencies: 519 | deep-extend "^0.6.0" 520 | ini "~1.3.0" 521 | minimist "^1.2.0" 522 | strip-json-comments "~2.0.1" 523 | 524 | readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5: 525 | version "2.3.6" 526 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 527 | dependencies: 528 | core-util-is "~1.0.0" 529 | inherits "~2.0.3" 530 | isarray "~1.0.0" 531 | process-nextick-args "~2.0.0" 532 | safe-buffer "~5.1.1" 533 | string_decoder "~1.1.1" 534 | util-deprecate "~1.0.1" 535 | 536 | readable-stream@^3.0.2: 537 | version "3.1.1" 538 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.1.1.tgz#ed6bbc6c5ba58b090039ff18ce670515795aeb06" 539 | dependencies: 540 | inherits "^2.0.3" 541 | string_decoder "^1.1.1" 542 | util-deprecate "^1.0.1" 543 | 544 | resolve@^1.3.2: 545 | version "1.10.0" 546 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" 547 | dependencies: 548 | path-parse "^1.0.6" 549 | 550 | safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 551 | version "5.1.2" 552 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 553 | 554 | semver@^5.4.1: 555 | version "5.6.0" 556 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" 557 | 558 | set-blocking@~2.0.0: 559 | version "2.0.0" 560 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 561 | 562 | signal-exit@^3.0.0: 563 | version "3.0.2" 564 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 565 | 566 | simple-concat@^1.0.0: 567 | version "1.0.0" 568 | resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" 569 | 570 | simple-get@^2.7.0: 571 | version "2.8.1" 572 | resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" 573 | dependencies: 574 | decompress-response "^3.3.0" 575 | once "^1.3.1" 576 | simple-concat "^1.0.0" 577 | 578 | source-map@^0.5.0: 579 | version "0.5.7" 580 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 581 | 582 | string-width@^1.0.1: 583 | version "1.0.2" 584 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 585 | dependencies: 586 | code-point-at "^1.0.0" 587 | is-fullwidth-code-point "^1.0.0" 588 | strip-ansi "^3.0.0" 589 | 590 | "string-width@^1.0.2 || 2": 591 | version "2.1.1" 592 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 593 | dependencies: 594 | is-fullwidth-code-point "^2.0.0" 595 | strip-ansi "^4.0.0" 596 | 597 | string_decoder@^1.1.1: 598 | version "1.2.0" 599 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" 600 | dependencies: 601 | safe-buffer "~5.1.0" 602 | 603 | string_decoder@~1.1.1: 604 | version "1.1.1" 605 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 606 | dependencies: 607 | safe-buffer "~5.1.0" 608 | 609 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 610 | version "3.0.1" 611 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 612 | dependencies: 613 | ansi-regex "^2.0.0" 614 | 615 | strip-ansi@^4.0.0: 616 | version "4.0.0" 617 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 618 | dependencies: 619 | ansi-regex "^3.0.0" 620 | 621 | strip-json-comments@~2.0.1: 622 | version "2.0.1" 623 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 624 | 625 | supports-color@^5.3.0: 626 | version "5.5.0" 627 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 628 | dependencies: 629 | has-flag "^3.0.0" 630 | 631 | tar-fs@^1.13.0: 632 | version "1.16.3" 633 | resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" 634 | dependencies: 635 | chownr "^1.0.1" 636 | mkdirp "^0.5.1" 637 | pump "^1.0.0" 638 | tar-stream "^1.1.2" 639 | 640 | tar-stream@^1.1.2: 641 | version "1.6.2" 642 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" 643 | dependencies: 644 | bl "^1.0.0" 645 | buffer-alloc "^1.2.0" 646 | end-of-stream "^1.0.0" 647 | fs-constants "^1.0.0" 648 | readable-stream "^2.3.0" 649 | to-buffer "^1.1.1" 650 | xtend "^4.0.0" 651 | 652 | to-buffer@^1.1.1: 653 | version "1.1.1" 654 | resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" 655 | 656 | to-fast-properties@^2.0.0: 657 | version "2.0.0" 658 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 659 | 660 | trim-right@^1.0.1: 661 | version "1.0.1" 662 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 663 | 664 | tunnel-agent@^0.6.0: 665 | version "0.6.0" 666 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 667 | dependencies: 668 | safe-buffer "^5.0.1" 669 | 670 | util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: 671 | version "1.0.2" 672 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 673 | 674 | which-pm-runs@^1.0.0: 675 | version "1.0.0" 676 | resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" 677 | 678 | wide-align@^1.1.0: 679 | version "1.1.3" 680 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 681 | dependencies: 682 | string-width "^1.0.2 || 2" 683 | 684 | wrappy@1: 685 | version "1.0.2" 686 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 687 | 688 | xtend@^4.0.0, xtend@~4.0.0: 689 | version "4.0.1" 690 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 691 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | .cache 3 | node_modules 4 | yarn-error.log 5 | 6 | # Build directory 7 | /public 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | ``` 4 | yarn 5 | ``` 6 | 7 | ## Develop 8 | 9 | ``` 10 | yarn develop 11 | ``` 12 | 13 | ## Travis Status 14 | 15 | [![Build Status](https://travis-ci.org/nikgraf/react-hooks.svg?branch=master)](https://travis-ci.org/nikgraf/react-hooks) 16 | -------------------------------------------------------------------------------- /site/gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | title: "Collection of React Hooks", 4 | }, 5 | plugins: [ 6 | "gatsby-plugin-styled-components", 7 | "gatsby-plugin-react-helmet", 8 | { 9 | resolve: `gatsby-plugin-google-analytics`, 10 | options: { 11 | trackingId: "UA-128821753-1", 12 | // Puts tracking script in the head instead of the body 13 | head: false, 14 | anonymize: true, 15 | cookieExpires: 0, 16 | }, 17 | }, 18 | { 19 | resolve: `gatsby-plugin-manifest`, 20 | options: { 21 | icon: `src/images/react-hooks.png`, 22 | }, 23 | }, 24 | ], 25 | pathPrefix: "/react-hooks", 26 | }; 27 | -------------------------------------------------------------------------------- /site/jest-preprocess.js: -------------------------------------------------------------------------------- 1 | const babelOptions = { 2 | presets: ["babel-preset-gatsby"] 3 | }; 4 | 5 | module.exports = require("babel-jest").createTransformer(babelOptions); 6 | -------------------------------------------------------------------------------- /site/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | "^.+\\.jsx?$": `/jest-preprocess.js` 4 | }, 5 | testPathIgnorePatterns: [`node_modules`, `.cache`], 6 | transformIgnorePatterns: [`node_modules/(?!(gatsby)/)`] 7 | }; 8 | -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-hooks", 3 | "version": "1.0.0", 4 | "author": "Nik Graf", 5 | "dependencies": { 6 | "babel-jest": "^24.1.0", 7 | "babel-plugin-styled-components": "^1.8.0", 8 | "babel-preset-gatsby": "^0.1.7", 9 | "gatsby": "^2.0.19", 10 | "gatsby-plugin-google-analytics": "^2.0.7", 11 | "gatsby-plugin-manifest": "^2.3.3", 12 | "gatsby-plugin-react-helmet": "^3.0.0", 13 | "gatsby-plugin-styled-components": "^3.0.0", 14 | "react": "^16.8.1", 15 | "react-dom": "^16.8.1", 16 | "react-helmet": "^5.2.0", 17 | "react-highlight-words": "^0.16.0", 18 | "styled-components": "^4.0.2", 19 | "tmp-cache": "^1.0.0" 20 | }, 21 | "license": "MIT", 22 | "scripts": { 23 | "build": "gatsby build --prefix-paths", 24 | "build:local": "gatsby build", 25 | "develop": "gatsby develop", 26 | "deploy": "gatsby build --prefix-paths && gh-pages -d public", 27 | "test": "jest" 28 | }, 29 | "devDependencies": { 30 | "gh-pages": "^2.0.1", 31 | "jest": "^24.1.0", 32 | "prettier": "^1.14.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /site/src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "gatsby"; 3 | 4 | const Header = ({ siteTitle }) => ( 5 |
11 |
18 | 24 | 28 | 32 | 36 | 40 | 41 |

42 | 49 | {siteTitle} 50 | 51 |

52 |
53 |
54 | ); 55 | 56 | export default Header; 57 | -------------------------------------------------------------------------------- /site/src/components/layout.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto|Space+Mono'); 2 | 3 | html { 4 | font-family: sans-serif; 5 | -ms-text-size-adjust: 100%; 6 | -webkit-text-size-adjust: 100%; 7 | font-family: 'Roboto', sans-serif; 8 | } 9 | body { 10 | margin: 0; 11 | } 12 | article, 13 | aside, 14 | details, 15 | figcaption, 16 | figure, 17 | footer, 18 | header, 19 | main, 20 | menu, 21 | nav, 22 | section, 23 | summary { 24 | display: block; 25 | } 26 | audio, 27 | canvas, 28 | progress, 29 | video { 30 | display: inline-block; 31 | } 32 | audio:not([controls]) { 33 | display: none; 34 | height: 0; 35 | } 36 | progress { 37 | vertical-align: baseline; 38 | } 39 | [hidden], 40 | template { 41 | display: none; 42 | } 43 | a { 44 | background-color: transparent; 45 | -webkit-text-decoration-skip: objects; 46 | } 47 | a:active, 48 | a:hover { 49 | outline-width: 0; 50 | } 51 | abbr[title] { 52 | border-bottom: none; 53 | text-decoration: underline; 54 | text-decoration: underline dotted; 55 | } 56 | b, 57 | strong { 58 | font-weight: inherit; 59 | font-weight: bolder; 60 | } 61 | dfn { 62 | font-style: italic; 63 | } 64 | h1 { 65 | font-size: 2em; 66 | margin: .67em 0; 67 | } 68 | mark { 69 | background-color: #ff0; 70 | color: #000; 71 | } 72 | small { 73 | font-size: 80%; 74 | } 75 | sub, 76 | sup { 77 | font-size: 75%; 78 | line-height: 0; 79 | position: relative; 80 | vertical-align: baseline; 81 | } 82 | sub { 83 | bottom: -.25em; 84 | } 85 | sup { 86 | top: -.5em; 87 | } 88 | img { 89 | border-style: none; 90 | } 91 | svg:not(:root) { 92 | overflow: hidden; 93 | } 94 | code, 95 | kbd, 96 | pre, 97 | samp { 98 | font-family: monospace, monospace; 99 | font-size: 1em; 100 | } 101 | figure { 102 | margin: 1em 40px; 103 | } 104 | hr { 105 | box-sizing: content-box; 106 | height: 0; 107 | overflow: visible; 108 | } 109 | button, 110 | input, 111 | optgroup, 112 | select, 113 | textarea { 114 | font: inherit; 115 | margin: 0; 116 | } 117 | optgroup { 118 | font-weight: 700; 119 | } 120 | button, 121 | input { 122 | overflow: visible; 123 | } 124 | button, 125 | select { 126 | text-transform: none; 127 | } 128 | [type=reset], 129 | [type=submit], 130 | button, 131 | html [type=button] { 132 | -webkit-appearance: button; 133 | } 134 | [type=button]::-moz-focus-inner, 135 | [type=reset]::-moz-focus-inner, 136 | [type=submit]::-moz-focus-inner, 137 | button::-moz-focus-inner { 138 | border-style: none; 139 | padding: 0; 140 | } 141 | [type=button]:-moz-focusring, 142 | [type=reset]:-moz-focusring, 143 | [type=submit]:-moz-focusring, 144 | button:-moz-focusring { 145 | outline: 1px dotted ButtonText; 146 | } 147 | fieldset { 148 | border: 1px solid silver; 149 | margin: 0 2px; 150 | padding: .35em .625em .75em; 151 | } 152 | legend { 153 | box-sizing: border-box; 154 | color: inherit; 155 | display: table; 156 | max-width: 100%; 157 | padding: 0; 158 | white-space: normal; 159 | } 160 | textarea { 161 | overflow: auto; 162 | } 163 | [type=checkbox], 164 | [type=radio] { 165 | box-sizing: border-box; 166 | padding: 0; 167 | } 168 | [type=number]::-webkit-inner-spin-button, 169 | [type=number]::-webkit-outer-spin-button { 170 | height: auto; 171 | } 172 | [type=search] { 173 | -webkit-appearance: textfield; 174 | outline-offset: -2px; 175 | } 176 | [type=search]::-webkit-search-cancel-button, 177 | [type=search]::-webkit-search-decoration { 178 | -webkit-appearance: none; 179 | } 180 | ::-webkit-input-placeholder { 181 | color: inherit; 182 | opacity: .54; 183 | } 184 | ::-webkit-file-upload-button { 185 | -webkit-appearance: button; 186 | font: inherit; 187 | } 188 | html { 189 | font: 112.5%/1.45em georgia, serif; 190 | box-sizing: border-box; 191 | overflow-y: scroll; 192 | } 193 | * { 194 | box-sizing: inherit; 195 | } 196 | *:before { 197 | box-sizing: inherit; 198 | } 199 | *:after { 200 | box-sizing: inherit; 201 | } 202 | body { 203 | color: hsla(0, 0%, 0%, 0.8); 204 | font-family: georgia, serif; 205 | font-family: 'Roboto', sans-serif; 206 | font-weight: normal; 207 | word-wrap: break-word; 208 | font-kerning: normal; 209 | -moz-font-feature-settings: "kern", "liga", "clig", "calt"; 210 | -ms-font-feature-settings: "kern", "liga", "clig", "calt"; 211 | -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; 212 | font-feature-settings: "kern", "liga", "clig", "calt"; 213 | } 214 | img { 215 | max-width: 100%; 216 | margin-left: 0; 217 | margin-right: 0; 218 | margin-top: 0; 219 | padding-bottom: 0; 220 | padding-left: 0; 221 | padding-right: 0; 222 | padding-top: 0; 223 | margin-bottom: 1.45rem; 224 | } 225 | h1 { 226 | margin-left: 0; 227 | margin-right: 0; 228 | margin-top: 0; 229 | padding-bottom: 0; 230 | padding-left: 0; 231 | padding-right: 0; 232 | padding-top: 0; 233 | margin-bottom: 1.45rem; 234 | color: inherit; 235 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 236 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 237 | font-weight: bold; 238 | text-rendering: optimizeLegibility; 239 | font-size: 2.25rem; 240 | line-height: 1.1; 241 | } 242 | h2 { 243 | margin-left: 0; 244 | margin-right: 0; 245 | margin-top: 0; 246 | padding-bottom: 0; 247 | padding-left: 0; 248 | padding-right: 0; 249 | padding-top: 0; 250 | margin-bottom: 1.45rem; 251 | color: inherit; 252 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 253 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 254 | font-weight: bold; 255 | text-rendering: optimizeLegibility; 256 | font-size: 1.62671rem; 257 | line-height: 1.1; 258 | } 259 | h3 { 260 | margin-left: 0; 261 | margin-right: 0; 262 | margin-top: 0; 263 | padding-bottom: 0; 264 | padding-left: 0; 265 | padding-right: 0; 266 | padding-top: 0; 267 | margin-bottom: 1.45rem; 268 | color: inherit; 269 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 270 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 271 | font-weight: bold; 272 | text-rendering: optimizeLegibility; 273 | font-size: 1.38316rem; 274 | line-height: 1.1; 275 | } 276 | h4 { 277 | margin-left: 0; 278 | margin-right: 0; 279 | margin-top: 0; 280 | padding-bottom: 0; 281 | padding-left: 0; 282 | padding-right: 0; 283 | padding-top: 0; 284 | margin-bottom: 1.45rem; 285 | color: inherit; 286 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 287 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 288 | font-weight: bold; 289 | text-rendering: optimizeLegibility; 290 | font-size: 1rem; 291 | line-height: 1.1; 292 | } 293 | h5 { 294 | margin-left: 0; 295 | margin-right: 0; 296 | margin-top: 0; 297 | padding-bottom: 0; 298 | padding-left: 0; 299 | padding-right: 0; 300 | padding-top: 0; 301 | margin-bottom: 1.45rem; 302 | color: inherit; 303 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 304 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 305 | font-weight: bold; 306 | text-rendering: optimizeLegibility; 307 | font-size: 0.85028rem; 308 | line-height: 1.1; 309 | } 310 | h6 { 311 | margin-left: 0; 312 | margin-right: 0; 313 | margin-top: 0; 314 | padding-bottom: 0; 315 | padding-left: 0; 316 | padding-right: 0; 317 | padding-top: 0; 318 | margin-bottom: 1.45rem; 319 | color: inherit; 320 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 321 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 322 | font-weight: bold; 323 | text-rendering: optimizeLegibility; 324 | font-size: 0.78405rem; 325 | line-height: 1.1; 326 | } 327 | hgroup { 328 | margin-left: 0; 329 | margin-right: 0; 330 | margin-top: 0; 331 | padding-bottom: 0; 332 | padding-left: 0; 333 | padding-right: 0; 334 | padding-top: 0; 335 | margin-bottom: 1.45rem; 336 | } 337 | ul { 338 | margin-left: 1.45rem; 339 | margin-right: 0; 340 | margin-top: 0; 341 | padding-bottom: 0; 342 | padding-left: 0; 343 | padding-right: 0; 344 | padding-top: 0; 345 | margin-bottom: 1.45rem; 346 | list-style-position: outside; 347 | list-style-image: none; 348 | } 349 | ol { 350 | margin-left: 1.45rem; 351 | margin-right: 0; 352 | margin-top: 0; 353 | padding-bottom: 0; 354 | padding-left: 0; 355 | padding-right: 0; 356 | padding-top: 0; 357 | margin-bottom: 1.45rem; 358 | list-style-position: outside; 359 | list-style-image: none; 360 | } 361 | dl { 362 | margin-left: 0; 363 | margin-right: 0; 364 | margin-top: 0; 365 | padding-bottom: 0; 366 | padding-left: 0; 367 | padding-right: 0; 368 | padding-top: 0; 369 | margin-bottom: 1.45rem; 370 | } 371 | dd { 372 | margin-left: 0; 373 | margin-right: 0; 374 | margin-top: 0; 375 | padding-bottom: 0; 376 | padding-left: 0; 377 | padding-right: 0; 378 | padding-top: 0; 379 | margin-bottom: 1.45rem; 380 | } 381 | p { 382 | margin-left: 0; 383 | margin-right: 0; 384 | margin-top: 0; 385 | padding-bottom: 0; 386 | padding-left: 0; 387 | padding-right: 0; 388 | padding-top: 0; 389 | margin-bottom: 1.45rem; 390 | } 391 | figure { 392 | margin-left: 0; 393 | margin-right: 0; 394 | margin-top: 0; 395 | padding-bottom: 0; 396 | padding-left: 0; 397 | padding-right: 0; 398 | padding-top: 0; 399 | margin-bottom: 1.45rem; 400 | } 401 | pre { 402 | margin-left: 0; 403 | margin-right: 0; 404 | margin-top: 0; 405 | padding-bottom: 0; 406 | padding-left: 0; 407 | padding-right: 0; 408 | padding-top: 0; 409 | margin-bottom: 1.45rem; 410 | font-size: 0.85rem; 411 | line-height: 1.42; 412 | background: hsla(0, 0%, 0%, 0.04); 413 | border-radius: 3px; 414 | overflow: auto; 415 | word-wrap: normal; 416 | padding: 1.45rem; 417 | } 418 | table { 419 | margin-left: 0; 420 | margin-right: 0; 421 | margin-top: 0; 422 | padding-bottom: 0; 423 | padding-left: 0; 424 | padding-right: 0; 425 | padding-top: 0; 426 | margin-bottom: 1.45rem; 427 | font-size: 1rem; 428 | line-height: 1.45rem; 429 | border-collapse: collapse; 430 | width: 100%; 431 | } 432 | fieldset { 433 | margin-left: 0; 434 | margin-right: 0; 435 | margin-top: 0; 436 | padding-bottom: 0; 437 | padding-left: 0; 438 | padding-right: 0; 439 | padding-top: 0; 440 | margin-bottom: 1.45rem; 441 | } 442 | blockquote { 443 | margin-left: 1.45rem; 444 | margin-right: 1.45rem; 445 | margin-top: 0; 446 | padding-bottom: 0; 447 | padding-left: 0; 448 | padding-right: 0; 449 | padding-top: 0; 450 | margin-bottom: 1.45rem; 451 | } 452 | form { 453 | margin-left: 0; 454 | margin-right: 0; 455 | margin-top: 0; 456 | padding-bottom: 0; 457 | padding-left: 0; 458 | padding-right: 0; 459 | padding-top: 0; 460 | margin-bottom: 1.45rem; 461 | } 462 | noscript { 463 | margin-left: 0; 464 | margin-right: 0; 465 | margin-top: 0; 466 | padding-bottom: 0; 467 | padding-left: 0; 468 | padding-right: 0; 469 | padding-top: 0; 470 | margin-bottom: 1.45rem; 471 | } 472 | iframe { 473 | margin-left: 0; 474 | margin-right: 0; 475 | margin-top: 0; 476 | padding-bottom: 0; 477 | padding-left: 0; 478 | padding-right: 0; 479 | padding-top: 0; 480 | margin-bottom: 1.45rem; 481 | } 482 | hr { 483 | margin-left: 0; 484 | margin-right: 0; 485 | margin-top: 0; 486 | padding-bottom: 0; 487 | padding-left: 0; 488 | padding-right: 0; 489 | padding-top: 0; 490 | margin-bottom: calc(1.45rem - 1px); 491 | background: hsla(0, 0%, 0%, 0.2); 492 | border: none; 493 | height: 1px; 494 | } 495 | address { 496 | margin-left: 0; 497 | margin-right: 0; 498 | margin-top: 0; 499 | padding-bottom: 0; 500 | padding-left: 0; 501 | padding-right: 0; 502 | padding-top: 0; 503 | margin-bottom: 1.45rem; 504 | } 505 | b { 506 | font-weight: bold; 507 | } 508 | strong { 509 | font-weight: bold; 510 | } 511 | dt { 512 | font-weight: bold; 513 | } 514 | th { 515 | font-weight: bold; 516 | } 517 | li { 518 | margin-bottom: calc(1.45rem / 2); 519 | } 520 | ol li { 521 | padding-left: 0; 522 | } 523 | ul li { 524 | padding-left: 0; 525 | } 526 | li > ol { 527 | margin-left: 1.45rem; 528 | margin-bottom: calc(1.45rem / 2); 529 | margin-top: calc(1.45rem / 2); 530 | } 531 | li > ul { 532 | margin-left: 1.45rem; 533 | margin-bottom: calc(1.45rem / 2); 534 | margin-top: calc(1.45rem / 2); 535 | } 536 | blockquote *:last-child { 537 | margin-bottom: 0; 538 | } 539 | li *:last-child { 540 | margin-bottom: 0; 541 | } 542 | p *:last-child { 543 | margin-bottom: 0; 544 | } 545 | li > p { 546 | margin-bottom: calc(1.45rem / 2); 547 | } 548 | code { 549 | font-size: 0.85rem; 550 | line-height: 1.45rem; 551 | } 552 | kbd { 553 | font-size: 0.85rem; 554 | line-height: 1.45rem; 555 | } 556 | samp { 557 | font-size: 0.85rem; 558 | line-height: 1.45rem; 559 | } 560 | abbr { 561 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 562 | cursor: help; 563 | } 564 | acronym { 565 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 566 | cursor: help; 567 | } 568 | abbr[title] { 569 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 570 | cursor: help; 571 | text-decoration: none; 572 | } 573 | thead { 574 | text-align: left; 575 | } 576 | td, 577 | th { 578 | text-align: left; 579 | border-bottom: 1px solid hsla(0, 0%, 0%, 0.12); 580 | font-feature-settings: "tnum"; 581 | -moz-font-feature-settings: "tnum"; 582 | -ms-font-feature-settings: "tnum"; 583 | -webkit-font-feature-settings: "tnum"; 584 | padding-left: 0.96667rem; 585 | padding-right: 0.96667rem; 586 | padding-top: 0.725rem; 587 | padding-bottom: calc(0.725rem - 1px); 588 | } 589 | th:first-child, 590 | td:first-child { 591 | padding-left: 0; 592 | } 593 | th:last-child, 594 | td:last-child { 595 | padding-right: 0; 596 | } 597 | tt, 598 | code { 599 | background-color: hsla(0, 0%, 0%, 0.04); 600 | border-radius: 3px; 601 | font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", 602 | "Liberation Mono", Menlo, Courier, monospace; 603 | padding: 0; 604 | padding-top: 0.2em; 605 | padding-bottom: 0.2em; 606 | } 607 | pre code { 608 | background: none; 609 | line-height: 1.42; 610 | } 611 | code:before, 612 | code:after, 613 | tt:before, 614 | tt:after { 615 | letter-spacing: -0.2em; 616 | content: " "; 617 | } 618 | pre code:before, 619 | pre code:after, 620 | pre tt:before, 621 | pre tt:after { 622 | content: ""; 623 | } 624 | @media only screen and (max-width: 480px) { 625 | html { 626 | font-size: 100%; 627 | } 628 | } 629 | 630 | a, 631 | a:visited { 632 | color: rgb(28, 165, 79); 633 | text-decoration: none; 634 | } 635 | 636 | a:hover { 637 | color: #0c7533; 638 | text-decoration: underline; 639 | } 640 | -------------------------------------------------------------------------------- /site/src/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Helmet from 'react-helmet' 3 | import { StaticQuery, graphql } from 'gatsby' 4 | 5 | import Header from './header' 6 | import './layout.css' 7 | 8 | const Layout = ({ children }) => ( 9 | ( 20 | <> 21 | 28 | 29 | 30 |
31 |
39 | {children} 40 |
41 | 42 | )} 43 | /> 44 | ) 45 | 46 | export default Layout 47 | -------------------------------------------------------------------------------- /site/src/hooks.json.test.js: -------------------------------------------------------------------------------- 1 | import hooks from "../../hooks.json"; 2 | 3 | describe("hooks.json", () => { 4 | test("no duplicated hooks", () => { 5 | const findDuplicatedHook = (hooks) => { 6 | const keys = new Set(); 7 | for (const hook of hooks) { 8 | const key = `${hook.repositoryUrl}-${hook.name}`; 9 | if (keys.has(key)) { 10 | return hook; 11 | } 12 | keys.add(key); 13 | } 14 | return null; 15 | }; 16 | expect( 17 | findDuplicatedHook(hooks) 18 | ).toBeNull(); 19 | }); 20 | }); -------------------------------------------------------------------------------- /site/src/images/react-hooks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikgraf/react-hooks/a95ae8db0621783a1a0b65889d70bdcd415907a1/site/src/images/react-hooks.png -------------------------------------------------------------------------------- /site/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Layout from '../components/layout' 3 | 4 | const NotFoundPage = () => ( 5 | 6 |

NOT FOUND

7 |

You just hit a route that doesn't exist... the sadness.

8 |
9 | ) 10 | 11 | export default NotFoundPage 12 | -------------------------------------------------------------------------------- /site/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "styled-components"; 3 | import Highlighter from "react-highlight-words"; 4 | 5 | import unsortedHooks from "../../../hooks.json"; 6 | import Layout from "../components/layout"; 7 | import { 8 | findHooks, 9 | githubName, 10 | sortHooks, 11 | getSubHooks, 12 | getTags, 13 | parseSearchString, 14 | toggleTag, 15 | toggleSubHook, 16 | searchQueryToString, 17 | getTerms, 18 | sortTags 19 | } from "../utils"; 20 | 21 | const device = { 22 | desktop: "(min-width: 768px)" 23 | }; 24 | 25 | const Hook = styled.div` 26 | margin-bottom: 4rem; 27 | `; 28 | 29 | const RepositoryLink = styled.a` 30 | display: block; 31 | font-size: 0.85em; 32 | 33 | @media ${device.desktop} { 34 | display: initial; 35 | font-size: inherit; 36 | float: right; 37 | } 38 | `; 39 | 40 | const Name = styled.h2` 41 | font-family: "Space Mono", monospace; 42 | margin-bottom: 0.2rem; 43 | 44 | @media ${device.desktop} { 45 | display: inline-block; 46 | } 47 | `; 48 | 49 | const Pre = styled.pre` 50 | display: block; 51 | margin: 5% 0; 52 | padding: 0.6rem; 53 | 54 | @media ${device.desktop} { 55 | margin: 3% 0; 56 | } 57 | `; 58 | 59 | const Tag = styled.a` 60 | font-size: 0.8rem; 61 | background: #d9ffab; 62 | border-bottom: 1px solid #b6de86; 63 | padding: 0.1rem 0.7rem; 64 | border-radius: 1rem; 65 | margin-right: 0.5rem; 66 | margin-bottom: 0.5rem; 67 | display: inline-block; 68 | `; 69 | 70 | const SubHook = styled.a` 71 | font-size: 0.8rem; 72 | background: #ffabcc; 73 | color: hsla(0, 0%, 0%, 0.8); 74 | border-bottom: 1px solid #ab6081; 75 | padding: 0.1rem 0.7rem; 76 | border-radius: 1rem; 77 | margin-right: 0.5rem; 78 | margin-bottom: 0.5rem; 79 | display: inline-block; 80 | &:hover { 81 | color: hsla(0, 0%, 0%, 0.8); 82 | } 83 | `; 84 | 85 | const FilterInput = styled.input` 86 | width: 100%; 87 | margin: 1rem 0; 88 | padding: 0.4rem 0.8rem; 89 | font-family: "Roboto", sans-serif; 90 | `; 91 | 92 | const ResultsCount = styled.div` 93 | font-size: 0.7rem; 94 | color: grey; 95 | margin-top: 0.5rem; 96 | margin-bottom: 3rem; 97 | `; 98 | 99 | const allHooks = sortHooks(unsortedHooks).map((x, i) => { 100 | x.key = i; 101 | return x; 102 | }); 103 | const allTags = sortTags(allHooks); 104 | 105 | const IndexPage = () => { 106 | const [term, setTerm] = useState(""); 107 | const search = term.trim().toLowerCase(); 108 | const results = findHooks(search, allHooks); 109 | 110 | const query = parseSearchString(term); 111 | const tagsToSearch = getTags(query); 112 | const hooksToSearch = getSubHooks(query); 113 | const termsToSearch = getTerms(query); 114 | 115 | const POPULAR_TAG_COUNT = 5; 116 | const popularTags = allTags.slice(0, POPULAR_TAG_COUNT); 117 | 118 | return ( 119 | 120 |

121 | You can add your hooks by opening a pull-request at{" "} 122 | 123 | https://github.com/nikgraf/react-hooks 124 | 125 | . 126 |

127 | { 130 | setTerm(value); 131 | }} 132 | placeholder="filter by name" 133 | /> 134 | {popularTags.map((tag) => ( 135 | { 139 | event.preventDefault(); 140 | setTerm(searchQueryToString(toggleTag(query, tag.name))); 141 | }} 142 | > 143 | 148 | 149 | ))} 150 | 151 | Found {results.length} {results.length === 1 ? "entry" : "entries"} 152 | 153 | {results.map(hook => ( 154 | 155 | 156 | 161 | 162 | 163 | 168 | 169 |
170 |             {hook.importStatement}
171 |           
172 |
173 | {hook.tags.map(tag => ( 174 | { 178 | event.preventDefault(); 179 | setTerm(searchQueryToString(toggleTag(query, tag))); 180 | }} 181 | > 182 | 187 | 188 | ))} 189 | {hook.subHooks && 190 | hook.subHooks.map(subHook => ( 191 | { 195 | event.preventDefault(); 196 | setTerm(searchQueryToString(toggleSubHook(query, subHook))); 197 | }} 198 | > 199 | 204 | 205 | ))} 206 |
207 |
208 | ))} 209 |
210 | ); 211 | }; 212 | 213 | export default IndexPage; 214 | -------------------------------------------------------------------------------- /site/src/utils.js: -------------------------------------------------------------------------------- 1 | import Cache from "tmp-cache"; 2 | 3 | const memoize = fn => { 4 | const cache = new Cache(300); 5 | return arg => { 6 | if (!cache.has(arg)) cache.set(arg, fn(arg)); 7 | return cache.get(arg); 8 | }; 9 | }; 10 | 11 | const toggle = type => (query, tag) => { 12 | const index = query.findIndex( 13 | ([type, term]) => type === type && term.toLowerCase() === tag.toLowerCase() 14 | ); 15 | if (index > -1) { 16 | return [...query.slice(0, index), ...query.slice(index + 1)]; 17 | } else { 18 | return [...query, [type, tag]]; 19 | } 20 | }; 21 | 22 | const get = ofType => query => 23 | query.filter(([type]) => type === ofType).map(([_, term]) => term); 24 | 25 | export const getTags = get("tag"); 26 | export const toggleTag = toggle("tag"); 27 | 28 | export const getSubHooks = get("hook"); 29 | export const toggleSubHook = toggle("hook"); 30 | 31 | export const getTerms = get("text"); 32 | 33 | const unquote = str => str.replace(/^"(.*)"$|/g, "$1").replace('\\"', '"'); 34 | const quote = str => 35 | str.includes(" ") ? `"${str.replace('"', '\\"')}"` : str.replace('"', '\\"'); 36 | 37 | // https://stackoverflow.com/questions/13796594/how-to-split-string-into-arguments-and-options-in-javascript 38 | const parseRegexp = /((?:"[^"\\]*(?:\\[\S\s][^"\\]*)*"|(?:\\\s|\S))+)(?=\s|$)/g; 39 | 40 | /** 41 | * converts input like this 42 | * 43 | * some text "quted text" tag:network tag:"state management" 44 | * 45 | * to 46 | * 47 | * [[tesx, some], [text, text], [text, quted text], [tag, network], [tag, state management]] 48 | */ 49 | export const parseSearchString = memoize(query => 50 | (query.match(parseRegexp) || []).map(term => { 51 | const colonPosition = term.indexOf(":"); 52 | if (colonPosition === -1) return ["text", unquote(term)]; 53 | const type = term.substring(0, colonPosition); 54 | if (type !== "tag" && type !== "hook") return ["text", unquote(term)]; 55 | return [type, unquote(term.substring(colonPosition + 1))]; 56 | }) 57 | ); 58 | 59 | export const searchQueryToString = query => { 60 | return query 61 | .map(([type, term]) => 62 | type === "text" ? quote(term) : `${type}:${quote(term)}` 63 | ) 64 | .join(" "); 65 | }; 66 | 67 | const memoizeSearch = fn => { 68 | const cache = new Cache(30); 69 | return (arg, arr) => { 70 | if (!cache.has(arg)) { 71 | const query = parseSearchString(arg); 72 | arg = arg.toLowerCase(); 73 | 74 | const texts = query 75 | .filter(([type]) => type === "text") 76 | .map(([_, term]) => term); 77 | 78 | let prev = texts.join(" ").substring(0, texts.join(" ").length - 1); 79 | if (cache.has(prev)) { 80 | cache.set(arg, fn(arg, cache.get(prev))); 81 | } else { 82 | cache.set(arg, fn(arg, arr)); 83 | } 84 | } 85 | return cache.get(arg); 86 | }; 87 | }; 88 | 89 | export const githubName = memoize(link => 90 | link.replace(/^https:\/\/github.com\//, "") 91 | ); 92 | 93 | export const findHooks = memoizeSearch((search, hooks) => { 94 | if (search === "") return hooks; 95 | search = search.toLowerCase(); 96 | const query = parseSearchString(search); 97 | const tags = getTags(query); 98 | const subHooks = getSubHooks(query); 99 | const terms = getTerms(query); 100 | 101 | if (terms.length > 0) { 102 | hooks = hooks.filter( 103 | hook => 104 | terms.some(term => hook.name.toLowerCase().includes(term)) || 105 | terms.some(term => hook.repositoryUrl.toLowerCase().includes(term)) 106 | ); 107 | } 108 | 109 | if (subHooks.length > 0) { 110 | hooks = hooks 111 | .filter(hook => Boolean(hook.subHooks)) 112 | .filter(hook => 113 | subHooks.every(madeOfHook => 114 | hook.subHooks.map(x => x.toLowerCase()).includes(madeOfHook) 115 | ) 116 | ); 117 | } 118 | 119 | if (tags.length > 0) { 120 | hooks = hooks.filter(hook => 121 | tags.every(tag => hook.tags.map(x => x.toLowerCase()).includes(tag)) 122 | ); 123 | } 124 | 125 | return hooks; 126 | }); 127 | 128 | function compare(hookA, hookB) { 129 | if ( 130 | hookA.name.substring(0, 3) === "use" && 131 | hookB.name.substring(0, 3) !== "use" 132 | ) { 133 | return -1; 134 | } 135 | if ( 136 | hookB.name.substring(0, 3) === "use" && 137 | hookA.name.substring(0, 3) !== "use" 138 | ) { 139 | return 1; 140 | } 141 | if (hookA.name < hookB.name) return -1; 142 | if (hookA.name > hookB.name) return 1; 143 | if (githubName(hookA.repositoryUrl) < githubName(hookB.repositoryUrl)) 144 | return -1; 145 | if (githubName(hookA.repositoryUrl) > githubName(hookB.repositoryUrl)) 146 | return 1; 147 | return 0; 148 | } 149 | 150 | export const sortHooks = hooks => hooks.sort(compare); 151 | 152 | const compareTags = (tagA, tagB) => tagB.count - tagA.count; 153 | 154 | export const sortTags = (hooks) => 155 | hooks.reduce((tags, hook) => { 156 | hook.tags.forEach((tag) => { 157 | if (tags.map((t) => t.name).includes(tag)) { 158 | const index = tags.map((t) => t.name).indexOf(tag); 159 | tags[index].count++; 160 | } else { 161 | tags.push({ 162 | name: tag, 163 | count: 1 164 | }); 165 | } 166 | }); 167 | return tags.sort(compareTags); 168 | }, []); 169 | -------------------------------------------------------------------------------- /site/src/utils.test.js: -------------------------------------------------------------------------------- 1 | import { findHooks, sortHooks } from "./utils"; 2 | 3 | describe("findHooks", () => { 4 | test("filter by string", () => { 5 | expect( 6 | findHooks("ab", [ 7 | { name: "createBb", repositoryUrl: "" }, 8 | { name: "useAb", repositoryUrl: "" }, 9 | { name: "createCc", repositoryUrl: "" }, 10 | { name: "useZa", repositoryUrl: "" }, 11 | { name: "createAb", repositoryUrl: "" } 12 | ]) 13 | ).toEqual([ 14 | { name: "useAb", repositoryUrl: "" }, 15 | { name: "createAb", repositoryUrl: "" } 16 | ]); 17 | }); 18 | }); 19 | 20 | describe("sortHooks", () => { 21 | test("sorts hooks alphabetically", () => { 22 | expect( 23 | sortHooks([ 24 | { name: "dd" }, 25 | { name: "aa" }, 26 | { name: "ca" }, 27 | { name: "ab" } 28 | ]) 29 | ).toEqual([{ name: "aa" }, { name: "ab" }, { name: "ca" }, { name: "dd" }]); 30 | }); 31 | 32 | test("move hooks with use prefix before others", () => { 33 | expect( 34 | sortHooks([ 35 | { name: "createBb" }, 36 | { name: "useAb" }, 37 | { name: "createCc" }, 38 | { name: "useZa" }, 39 | { name: "createA" } 40 | ]) 41 | ).toEqual([ 42 | { name: "useAb" }, 43 | { name: "useZa" }, 44 | { name: "createA" }, 45 | { name: "createBb" }, 46 | { name: "createCc" } 47 | ]); 48 | }); 49 | }); 50 | --------------------------------------------------------------------------------