8 |
9 | `;
10 |
11 | exports[`useOptimize should throw without dataLayer or gtag 1`] = `
12 | Array [
13 | "[@react-hook/google-optimize] Google Tag Manager was not found on your site. Neither \\"gtag()\\" or \\"dataLayer[]\\" could be located on the \\"window\\". If you are not using Google Tag Manager in dev you can ignore this warning. Otherwise, see the Google Tag Manager dev guide for examples: https://developers.google.com/tag-manager/devguide",
14 | ]
15 | `;
16 |
17 | exports[`useOptimize should timeout and default to "1":
1
1`] = `
18 |
19 |
20 | 1
21 |
22 |
23 | `;
24 |
25 | exports[`useOptimize should timeout and default to "1":
null
1`] = `
26 |
27 |
28 | null
29 |
30 |
31 | `;
32 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | > IMPORTANT: Please do not create a Pull Request without creating an issue first.
2 | > **Any change needs to be discussed before proceeding.** Failure to do so may result
3 | > in the rejection of the pull request.
4 |
5 | ## Thank you for contributing to react-hook
6 |
7 | ### Before submitting
8 |
9 | Read the [CONTRIBUTING.md](https://github.com/jaredLunde/react-hook/blob/master/CONTRIBUTING.md) file and confirm that you're following
10 | all of the guidelines
11 |
12 | ### Please provide enough information so that others can review your pull request
13 |
14 | - What does this implement/fix? Explain your changes.
15 | - Does this close any currently open issues?
16 | - Include the package name or names you're updating in your PR title, e.g. `[async] Fixes #129`, `[debounce, throttle] Updates build scripts`
17 |
18 | ### Testing
19 |
20 | Confirm that your pull request contains tests and that all existing tests pass.
21 |
22 | ### Closing issues
23 |
24 | Put closes #XXXX in your comment to auto-close the issue that your PR fixes (if such).
25 |
--------------------------------------------------------------------------------
/packages/window-size/test/test-utils.js:
--------------------------------------------------------------------------------
1 | // Simulate window resize event
2 | const resizeEvent = document.createEvent('Event')
3 | resizeEvent.initEvent('resize', true, true)
4 | const orientationEvent = document.createEvent('Event')
5 | orientationEvent.initEvent('orientationchange', true, true)
6 |
7 | export const resizeTo = (width, height) => {
8 | Object.defineProperty(document.documentElement, 'clientWidth', {
9 | value: width,
10 | configurable: true,
11 | })
12 | Object.defineProperty(document.documentElement, 'clientHeight', {
13 | value: height,
14 | configurable: true,
15 | })
16 | window.dispatchEvent(resizeEvent)
17 | }
18 |
19 | export const changeOrientation = (width, height) => {
20 | Object.defineProperty(document.documentElement, 'clientWidth', {
21 | value: width,
22 | configurable: true,
23 | })
24 | Object.defineProperty(document.documentElement, 'clientHeight', {
25 | value: height,
26 | configurable: true,
27 | })
28 | window.dispatchEvent(orientationEvent)
29 | }
30 |
31 | export const resetSize = () => {
32 | resizeTo(0, 0)
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/async/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/cache/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/change/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/click/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/copy/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/counter/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/debounce/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/event/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/hotkey/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/hover/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/latest/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/previous/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/size/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/switch/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/throttle/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/timeout/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/toggle/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/media-query/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/merged-ref/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/previous/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import {renderHook, act} from '@testing-library/react-hooks'
3 | // import {render} from '@testing-library/react'
4 | // import userEvent from '@testing-library/user-event
5 | import usePrevious from './index'
6 |
7 | describe('usePrevious()', () => {
8 | it('should pass', () => {
9 | const handleChange = jest.fn()
10 | const useChanged = (onChange: typeof handleChange) => {
11 | const [status, setStatus] = React.useState('off')
12 | const prevStatus = usePrevious(status, status)
13 |
14 | React.useEffect(() => {
15 | if (status !== prevStatus) onChange(status, prevStatus)
16 | // eslint-disable-next-line react-hooks/exhaustive-deps
17 | }, [status])
18 |
19 | return [status, setStatus] as const
20 | }
21 |
22 | const {result} = renderHook(() => useChanged(handleChange))
23 | expect(result.current[0]).toBe('off')
24 | expect(handleChange).not.toBeCalled()
25 | act(() => result.current[1]('on'))
26 | expect(result.current[0]).toBe('on')
27 | expect(handleChange).toBeCalledWith('on', 'off')
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/packages/window-scroll/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/window-size/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/google-optimize/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/mouse-position/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/resize-observer/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/server-promises/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/intersection-observer/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/passive-layout-effect/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jared Lunde
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.
--------------------------------------------------------------------------------
/packages/event/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | declare function useEvent(target: Window | null, type: K, listener: WindowEventListener, cleanup?: (...args: any[]) => void): void;
3 | declare function useEvent(target: Document | null, type: K, listener: DocumentEventListener, cleanup?: (...args: any[]) => void): void;
4 | declare function useEvent(target: React.RefObject | T | null, type: K, listener: ElementEventListener, cleanup?: (...args: any[]) => void): void;
5 | export declare type ElementEventListener = (this: HTMLElement, ev: HTMLElementEventMap[K]) => any;
6 | export declare type DocumentEventListener = (this: Document, ev: DocumentEventMap[K]) => any;
7 | export declare type WindowEventListener = (this: Document, ev: WindowEventMap[K]) => any;
8 | export default useEvent;
9 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | To contribute to this project, first:
4 |
5 | 1. Fork this repo to your account
6 | 2. `git clone https://github.com/[your-username]/react-hook.git`
7 | 3. `cd react-hook`
8 |
9 | Packages must be installed individually. They must also be installed using the `yarn` packager. An example for working on `throttle`:
10 |
11 | 1. `cd packages/throttle`
12 | 2. `yarn install`
13 |
14 | ### Development scripts
15 |
16 | Each individual package includes the following scripts:
17 |
18 | - `build`: Builds cjs/esm, types, and umd
19 | - `dev`: Runs cjs and esm builds in `--watch` mode
20 | - `check-types`: Checks TypeScript types
21 | - `format`: Formats the package w/ Prettier
22 | - `lint`: Lints the package w/ eslint
23 | - `test`: Tests the package w/ Jest
24 | - `validate`: Tests, lints, and checks types for the package
25 |
26 | ### Submitting a pull request
27 |
28 | Prior to submitting a pull request please ensure that:
29 |
30 | 1. `yarn validate` passes
31 | 2. You've included a tag with the packages you updated in your commit message e.g. `[throttle] fix: setState was not called on the leading edge`.
32 | 3. You've opened an issue prior to large or breaking changes. Talking about it first will increase the likelihood of merging.
33 |
--------------------------------------------------------------------------------
/packages/latest/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import {fireEvent} from '@testing-library/react'
3 | import {renderHook} from '@testing-library/react-hooks'
4 | import useLatest from './index'
5 |
6 | describe('useLatest()', () => {
7 | it('should store the latest value', () => {
8 | const fnA = () => {}
9 | const fnB = () => {}
10 | const {result, rerender} = renderHook(({fn}) => useLatest(fn), {
11 | initialProps: {fn: fnA},
12 | })
13 | expect(result.current.current).toBe(fnA)
14 | rerender({fn: fnB})
15 | expect(result.current.current).toBe(fnB)
16 | })
17 |
18 | it('should work as expected in useEffect()', () => {
19 | const fnA = jest.fn()
20 | const fnB = jest.fn()
21 | const {rerender} = renderHook(
22 | ({fn}) => {
23 | const latest = useLatest(fn)
24 | React.useEffect(() => {
25 | window.addEventListener('click', () => latest.current())
26 | }, [latest])
27 | },
28 | {
29 | initialProps: {fn: fnA},
30 | }
31 | )
32 |
33 | fireEvent.click(window)
34 | expect(fnA).toBeCalledTimes(1)
35 | rerender({fn: fnB})
36 | fireEvent.click(window)
37 | expect(fnA).toBeCalledTimes(1)
38 | expect(fnB).toBeCalledTimes(1)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/packages/change/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import {renderHook, act} from '@testing-library/react-hooks'
3 | // import {render} from '@testing-library/react'
4 | // import userEvent from '@testing-library/user-event
5 | import useChange from './index'
6 |
7 | describe('useChange()', () => {
8 | it('should call change handler when value changes', () => {
9 | const handleChange = jest.fn()
10 |
11 | const {result} = renderHook(() => {
12 | const [value, setValue] = React.useState('off')
13 | useChange(value, handleChange)
14 | return [value, setValue] as const
15 | })
16 |
17 | expect(result.current[0]).toBe('off')
18 | expect(handleChange).not.toBeCalled()
19 | act(() => result.current[1]('on'))
20 | expect(result.current[0]).toBe('on')
21 | expect(handleChange).toBeCalledWith('on', 'off')
22 | })
23 |
24 | it('should not call change handler when value does not change', () => {
25 | const handleChange = jest.fn()
26 |
27 | const {rerender} = renderHook(({value}) => useChange(value, handleChange), {
28 | initialProps: {value: 'off'},
29 | })
30 |
31 | expect(handleChange).not.toBeCalled()
32 | rerender({value: 'off'})
33 | expect(handleChange).not.toBeCalled()
34 | rerender({value: 'on'})
35 | expect(handleChange).toBeCalledWith('on', 'off')
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/packages/media-query/types/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A hook that returns a [`MediaQueryMatches`](#mediaquerymatches) object which will
3 | * tell you if specific media queries matched, all media queries matched, or
4 | * any media queries matched. Matches in this hook will always return `false` when
5 | * rendering on the server.
6 | *
7 | * @param queryMap The media queries you want to match against e.g. `{screen: "screen", width: "(min-width: 12em)"}`
8 | */
9 | export declare function useMediaQueries(
10 | queryMap: MediaQueries
11 | ): MediaQueryMatches
12 | /**
13 | * A hook that returns `true` if the media query matched and `false` if not. This
14 | * hook will always return `false` when rendering on the server.
15 | *
16 | * @param query The media query you want to match against e.g. `"only screen and (min-width: 12em)"`
17 | */
18 | export declare function useMediaQuery(query: string): boolean
19 | export declare type MediaQueries = {
20 | [Name in keyof T]: string
21 | }
22 | export declare type Matches = {
23 | [Name in keyof T]: boolean
24 | }
25 | export interface MediaQueryMatches {
26 | /**
27 | * Returns a map of query key/didMatch pairs
28 | */
29 | matches: Matches
30 | /**
31 | * `true` if any of the media queries matched
32 | */
33 | matchesAny: boolean
34 | /**
35 | * `true` if all of the media queries matched
36 | */
37 | matchesAll: boolean
38 | }
39 |
--------------------------------------------------------------------------------
/packages/async/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | export declare function useAsync<
3 | ValueType extends any = any,
4 | ErrorType extends any = Error,
5 | Args extends any[] = any[]
6 | >(
7 | asyncCallback: (...args: Args) => Promise
8 | ): readonly [
9 | {
10 | status: AsyncStatus
11 | value: ValueType | undefined
12 | error: ErrorType | undefined
13 | cancel: () => void
14 | },
15 | ((...args: Args) => Promise) & {
16 | cancel: () => void
17 | }
18 | ]
19 | export declare function useAsyncEffect<
20 | ValueType extends any = any,
21 | ErrorType extends any = Error
22 | >(
23 | asyncCallback: () => Promise,
24 | dependencies?: React.DependencyList
25 | ): {
26 | status: AsyncStatus
27 | value: ValueType | undefined
28 | error: ErrorType | undefined
29 | cancel: () => void
30 | }
31 | export interface AsyncReducerState {
32 | status: AsyncStatus
33 | value?: ValueType
34 | error?: ErrorType
35 | }
36 | export declare type AsyncAction =
37 | | {
38 | status: 'idle' | 'loading' | 'cancelled'
39 | }
40 | | {
41 | status: 'success'
42 | value: ValueType
43 | }
44 | | {
45 | status: 'error'
46 | error?: ErrorType
47 | }
48 | export declare type AsyncStatus =
49 | | 'idle'
50 | | 'loading'
51 | | 'success'
52 | | 'error'
53 | | 'cancelled'
54 |
--------------------------------------------------------------------------------
/packages/intersection-observer/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import 'intersection-observer'
2 | import * as React from 'react'
3 | declare function useIntersectionObserver(
4 | target: React.RefObject | T | null,
5 | options?: IntersectionObserverOptions
6 | ): MockIntersectionObserverEntry | IntersectionObserverEntry
7 | export declare type UseIntersectionObserverCallback = (
8 | entry: IntersectionObserverEntry,
9 | observer: IntersectionObserver
10 | ) => any
11 | export interface IntersectionObserverOptions {
12 | root?: HTMLElement | null
13 | pollInterval?: number | null
14 | useMutationObserver?: boolean
15 | rootMargin?: string
16 | threshold?: number | number[]
17 | initialIsIntersecting?: boolean
18 | }
19 | export interface IntersectionObserverBounds {
20 | readonly height: number
21 | readonly width: number
22 | readonly top: number
23 | readonly left: number
24 | readonly right: number
25 | readonly bottom: number
26 | }
27 | export interface MockIntersectionObserverEntry {
28 | readonly time: number | null
29 | readonly rootBounds: IntersectionObserverBounds | null
30 | readonly boundingClientRect: IntersectionObserverBounds | null
31 | readonly intersectionRect: IntersectionObserverBounds | null
32 | readonly intersectionRatio: number | null
33 | readonly target: HTMLElement | null
34 | readonly isIntersecting: boolean
35 | }
36 | export default useIntersectionObserver
37 |
--------------------------------------------------------------------------------
/packages/counter/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import useLatest from '@react-hook/latest'
3 |
4 | const useCounter = (initialValue = 0, options: UseCounterOptions = {}) => {
5 | const {min, max, cast = Number, step = 1, onMin, onMax} = options
6 | const [value, _setValue] = React.useState(
7 | Math.min(
8 | Math.max(initialValue, min ?? initialValue),
9 | max ?? min ?? initialValue
10 | )
11 | )
12 | const storedOnMin = useLatest(onMin)
13 | const storedOnMax = useLatest(onMax)
14 | const set = React.useCallback(
15 | (value: number) => {
16 | if (min === void 0 || min === null || value >= min) {
17 | if (max === void 0 || max === null || value <= max) {
18 | _setValue(cast(value))
19 | } else {
20 | _setValue(max)
21 | storedOnMax.current?.(set)
22 | }
23 | } else {
24 | _setValue(min)
25 | storedOnMin.current?.(set)
26 | }
27 | },
28 | [min, max, cast, storedOnMin, storedOnMax]
29 | )
30 |
31 | return {
32 | value,
33 | set,
34 | incr: React.useCallback((by = step) => set(value + by), [value, set, step]),
35 | decr: React.useCallback((by = step) => set(value - by), [value, set, step]),
36 | }
37 | }
38 |
39 | export interface UseCounterOptions {
40 | min?: number
41 | max?: number
42 | cast?: (value: number) => number
43 | step?: number
44 | onMin?: (set: (value: number) => void) => void
45 | onMax?: (set: (value: number) => void) => void
46 | }
47 |
48 | export default useCounter
49 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | cache:
4 | yarn: true
5 | directories:
6 | - node_modules
7 | notifications:
8 | email: false
9 | node_js: "12"
10 | branches:
11 | only:
12 | - master
13 | matrix:
14 | include:
15 | - env: TARGET=packages/async
16 | - env: TARGET=packages/cache
17 | - env: TARGET=packages/change
18 | - env: TARGET=packages/click
19 | - env: TARGET=packages/copy
20 | - env: TARGET=packages/counter
21 | - env: TARGET=packages/debounce
22 | - env: TARGET=packages/event
23 | - env: TARGET=packages/google-optimize
24 | - env: TARGET=packages/hotkey
25 | - env: TARGET=packages/hover
26 | - env: TARGET=packages/intersection-observer
27 | - env: TARGET=packages/latest
28 | - env: TARGET=packages/media-query
29 | - env: TARGET=packages/merged-ref
30 | - env: TARGET=packages/mouse-position
31 | - env: TARGET=packages/passive-layout-effect
32 | - env: TARGET=packages/previous
33 | - env: TARGET=packages/resize-observer
34 | - env: TARGET=packages/server-promises
35 | - env: TARGET=packages/size
36 | - env: TARGET=packages/switch
37 | - env: TARGET=packages/throttle
38 | - env: TARGET=packages/timeout
39 | - env: TARGET=packages/toggle
40 | - env: TARGET=packages/window-scroll
41 | - env: TARGET=packages/window-size
42 |
43 | before_script:
44 | - chmod +x ./.travis/build-condition.sh
45 | script: if .travis/build-condition.sh $TRAVIS_COMMIT_RANGE $TARGET; then echo "$TARGET is being built" && cd $TARGET && yarn install && yarn validate; else echo "$TARGET is NOT being built"; fi
46 |
--------------------------------------------------------------------------------
/packages/window-size/src/index.tsx:
--------------------------------------------------------------------------------
1 | import {useDebounce} from '@react-hook/debounce'
2 | import useEvent from '@react-hook/event'
3 |
4 | const emptyObj = {}
5 |
6 | export interface DebouncedWindowSizeOptions {
7 | initialWidth?: number
8 | initialHeight?: number
9 | wait?: number
10 | leading?: boolean
11 | }
12 |
13 | const win = typeof window === 'undefined' ? null : window
14 | const wv =
15 | win && typeof win.visualViewport !== 'undefined' ? win.visualViewport : null
16 | const getSize = () =>
17 | [
18 | document.documentElement.clientWidth,
19 | document.documentElement.clientHeight,
20 | ] as const
21 |
22 | export const useWindowSize = (
23 | options: DebouncedWindowSizeOptions = emptyObj
24 | ): readonly [number, number] => {
25 | const {wait, leading, initialWidth = 0, initialHeight = 0} = options
26 | const [size, setDebouncedSize] = useDebounce(
27 | /* istanbul ignore next */
28 | typeof document === 'undefined' ? [initialWidth, initialHeight] : getSize,
29 | wait,
30 | leading
31 | )
32 | const setSize = (): void => setDebouncedSize(getSize)
33 |
34 | useEvent(win, 'resize', setSize)
35 | // @ts-expect-error
36 | useEvent(wv, 'resize', setSize)
37 | useEvent(win, 'orientationchange', setSize)
38 |
39 | return size
40 | }
41 |
42 | export const useWindowHeight = (
43 | options?: Omit
44 | ): number => useWindowSize(options)[1]
45 |
46 | export const useWindowWidth = (
47 | options?: Omit
48 | ): number => useWindowSize(options)[0]
49 |
--------------------------------------------------------------------------------
/packages/switch/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import useLatest from '@react-hook/latest'
3 |
4 | /**
5 | * A hook for creating controlled toggles with on, off, and toggle callbacks.
6 | * This is extremely useful for creating controlled inputs for components like Checkbox.
7 | *
8 | * @param defaultValue Sets the default value of the switch
9 | * @param controlledValue Sets the controlled value of the switch, which will override
10 | * the defaultValue
11 | * @param onChange A callback invoked whenever toggle callbacks that change state are invoked
12 | */
13 | function useSwitch(
14 | defaultValue = false,
15 | controlledValue?: boolean,
16 | onChange: (value: boolean) => any = noop
17 | ) {
18 | const [current, setCurrent] = React.useState(controlledValue ?? defaultValue)
19 | const storedOnChange = useLatest(onChange)
20 |
21 | if (typeof controlledValue === 'boolean' && controlledValue !== current) {
22 | setCurrent(controlledValue)
23 | }
24 |
25 | const toggle = React.useCallback(() => {
26 | setCurrent(!current)
27 | storedOnChange.current(!current)
28 | }, [storedOnChange, current])
29 |
30 | return [
31 | controlledValue ?? current,
32 | Object.assign(toggle, {
33 | on: React.useCallback(() => {
34 | setCurrent(true)
35 | if (!current) storedOnChange.current(true)
36 | }, [storedOnChange, current]),
37 | off: React.useCallback(() => {
38 | setCurrent(false)
39 | if (current) storedOnChange.current(false)
40 | }, [storedOnChange, current]),
41 | }),
42 | ] as const
43 | }
44 |
45 | function noop() {}
46 |
47 | export default useSwitch
48 |
--------------------------------------------------------------------------------
/packages/hover/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import useEvent from '@react-hook/event'
3 |
4 | function useHover(
5 | target: React.RefObject | T | null,
6 | options: UseHoverOptions = {}
7 | ): boolean {
8 | const {enterDelay, leaveDelay} = options
9 | const timeout = React.useRef()
10 | const [hovering, setHovering] = React.useState(false)
11 |
12 | const toggle = (which: boolean) => {
13 | if (!canHover()) return
14 | const delay = which ? enterDelay : leaveDelay
15 | window.clearTimeout(timeout.current)
16 |
17 | if (delay) {
18 | timeout.current = window.setTimeout(() => setHovering(which), delay)
19 | } else {
20 | setHovering(which)
21 | }
22 | }
23 |
24 | useEvent(target, 'mouseenter', () => toggle(true))
25 | useEvent(target, 'mouseleave', () => toggle(false))
26 |
27 | // Cleans up timeout on unmount
28 | React.useEffect(
29 | () => () => {
30 | window.clearTimeout(timeout.current)
31 | },
32 | // eslint-disable-next-line react-hooks/exhaustive-deps
33 | []
34 | )
35 |
36 | return hovering
37 | }
38 |
39 | const canHover = (): boolean =>
40 | typeof window !== 'undefined'
41 | ? !window.matchMedia('(hover: none)').matches
42 | : false
43 |
44 | export interface UseHoverOptions {
45 | enterDelay?: number
46 | leaveDelay?: number
47 | }
48 |
49 | export interface UseHoverState {
50 | status: 'idle' | 'hovering'
51 | timeout: number | undefined
52 | }
53 |
54 | export type UseHoverAction = {
55 | type: 'setStatus'
56 | value: 'idle' | 'hovering'
57 | force?: boolean
58 | }
59 |
60 | export default useHover
61 |
--------------------------------------------------------------------------------
/packages/window-size/throttled/src/index.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import useEvent from '@react-hook/event'
3 | import {useThrottle} from '@react-hook/throttle'
4 |
5 | const emptyObj = {}
6 |
7 | export interface ThrottledWindowSizeOptions {
8 | initialWidth?: number
9 | initialHeight?: number
10 | fps?: number
11 | leading?: boolean
12 | }
13 |
14 | const win = typeof window === 'undefined' ? null : window
15 | const wv =
16 | win && typeof win.visualViewport !== 'undefined' ? win.visualViewport : null
17 | const getSize = () =>
18 | [
19 | document.documentElement.clientWidth,
20 | document.documentElement.clientHeight,
21 | ] as const
22 |
23 | export const useWindowSize = (
24 | options: ThrottledWindowSizeOptions = emptyObj
25 | ): readonly [number, number] => {
26 | const {fps, leading, initialWidth = 0, initialHeight = 0} = options
27 | const [size, setThrottledSize] = useThrottle(
28 | /* istanbul ignore next */
29 | typeof document === 'undefined' ? [initialWidth, initialHeight] : getSize,
30 | fps,
31 | leading
32 | )
33 | const setSize = (): void => setThrottledSize(getSize)
34 |
35 | useEvent(win, 'resize', setSize)
36 | // @ts-expect-error
37 | useEvent(wv, 'resize', setSize)
38 | useEvent(win, 'orientationchange', setSize)
39 |
40 | return size
41 | }
42 |
43 | export const useWindowHeight = (
44 | options?: Omit
45 | ): number => useWindowSize(options)[1]
46 |
47 | export const useWindowWidth = (
48 | options?: Omit
49 | ): number => useWindowSize(options)[0]
50 |
--------------------------------------------------------------------------------
/packages/size/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import useResizeObserver from '@react-hook/resize-observer'
3 | import useLayoutEffect from '@react-hook/passive-layout-effect'
4 |
5 | /**
6 | * A React hook for measuring the size of HTML elements including when they change
7 | *
8 | * @param target A React ref created by `useRef()` or an HTML element
9 | * @param options Configures the initial width and initial height of the hook's state
10 | */
11 | const useSize = (
12 | target: React.RefObject | T | null,
13 | options?: UseSizeOptions
14 | ): [number, number] => {
15 | const [size, setSize] = React.useState<[number, number]>(() => {
16 | const targetEl = target && 'current' in target ? target.current : target
17 | return targetEl
18 | ? [targetEl.offsetWidth, targetEl.offsetHeight]
19 | : [options?.initialWidth ?? 0, options?.initialHeight ?? 0]
20 | })
21 |
22 | useLayoutEffect(() => {
23 | const targetEl = target && 'current' in target ? target.current : target
24 | if (!targetEl) return
25 | setSize([targetEl.offsetWidth, targetEl.offsetHeight])
26 | }, [target])
27 |
28 | // Where the magic happens
29 | useResizeObserver(target, (entry) => {
30 | const target = entry.target as HTMLElement
31 | setSize([target.offsetWidth, target.offsetHeight])
32 | })
33 |
34 | return size
35 | }
36 |
37 | export interface UseSizeOptions {
38 | // The initial width to set into state.
39 | // This is useful for SSR environments.
40 | initialWidth: number
41 | // The initial height to set into state.
42 | // This is useful for SSR environments.
43 | initialHeight: number
44 | }
45 |
46 | export default useSize
47 |
--------------------------------------------------------------------------------
/packages/server-promises/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {renderHook} from '@testing-library/react-hooks'
3 | import {renderToString} from 'react-dom/server'
4 | import {useServerPromises, loadPromises} from './index'
5 |
6 | describe('useServerPromises()', () => {
7 | it('should add promises', () => {
8 | const {result} = renderHook(() => useServerPromises())
9 | result.current.push(Promise.resolve('foo'))
10 | expect(result.current.promises.length).toBe(1)
11 | })
12 |
13 | it('should render to string w/ resolved promises', async () => {
14 | const Component = ({value, stop = false}) => {
15 | const {push} = useServerPromises()
16 |
17 | React.useEffect(() => {
18 | push(Promise.resolve(value))
19 | }, [push, value])
20 |
21 | return (
22 |
27 |
28 |
29 | A React hook for updating components when the scroll position of the window on the y-axis changes.
30 | This hook throttles updates to the scroll position using [useThrottle()](https://github.com/jaredLunde/react-hook/tree/master/packages/throttle)
31 | at `30fps` by default, but this rate is configurable.
32 |
33 | ## Quick Start
34 |
35 | [Check out the example on **CodeSandbox**](https://codesandbox.io/s/react-hookwindow-size-and-react-hookwindow-scroll-examples-oqmer?file=/src/App.js)
36 |
37 | ```jsx harmony
38 | import { useWindowScroll } from '@react-hook/window-scroll'
39 |
40 | const Component = (props) => {
41 | const scrollY = useWindowScroll(60 /*fps*/)
42 | return
scroll pos: {scrollY}
43 | }
44 | ```
45 |
46 | ## API
47 |
48 | ### useWindowScroll(fps?: number): number
49 |
50 | A hook that performantly updates its scroll position at a constant frame rate.
51 |
52 | #### Arguments
53 |
54 | | | Type | Default | Description |
55 | | --- | -------- | ------- | ----------------------------------------------------------------------------- |
56 | | fps | `number` | `30` | Defines the rate in frames per second at which the scroll position is updated |
57 |
58 | #### Returns `scrollY: number`
59 |
60 | | | Type | Description |
61 | | ------- | -------- | ------------------------------------------------------- |
62 | | scrollY | `number` | The current scroll position of the window on the y-axis |
63 |
64 | ## LICENSE
65 |
66 | MIT
67 |
--------------------------------------------------------------------------------
/packages/debounce/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | import {renderHook, act} from '@testing-library/react-hooks'
2 | import {useDebounce, useDebounceCallback} from './index'
3 |
4 | const renderDebounce = (callback, ...args) =>
5 | renderHook(() => useDebounce(callback, ...args))
6 | const renderDebounceCallback = (fn, ...args) =>
7 | renderHook(() => useDebounceCallback(fn, ...args))
8 |
9 | describe('useDebounce()', () => {
10 | jest.useFakeTimers()
11 |
12 | it('should wait 100ms before invoking the callback', () => {
13 | const cb = jest.fn()
14 | const {result} = renderDebounceCallback(cb)
15 |
16 | act(result.current)
17 | act(result.current)
18 | act(result.current)
19 |
20 | act(() => jest.advanceTimersByTime(50))
21 | expect(cb).toBeCalledTimes(0)
22 | act(() => jest.advanceTimersByTime(100))
23 | expect(cb).toBeCalledTimes(1)
24 |
25 | act(result.current)
26 | act(result.current)
27 | act(result.current)
28 |
29 | act(() => jest.advanceTimersByTime(99))
30 | expect(cb).toHaveBeenCalledTimes(1)
31 | act(() => jest.advanceTimersByTime(1))
32 | expect(cb).toHaveBeenCalledTimes(2)
33 | })
34 |
35 | it('should invoke the callback on the leading edge', () => {
36 | const cb = jest.fn()
37 | const {result} = renderDebounceCallback(cb, 100, true)
38 |
39 | act(result.current)
40 | expect(cb).toHaveBeenCalledTimes(1)
41 |
42 | act(result.current)
43 | act(result.current)
44 | act(result.current)
45 | expect(cb).toHaveBeenCalledTimes(1)
46 |
47 | act(() => jest.advanceTimersByTime(100))
48 | expect(cb).toHaveBeenCalledTimes(2)
49 |
50 | act(result.current)
51 | expect(cb).toHaveBeenCalledTimes(3)
52 |
53 | act(result.current)
54 | act(result.current)
55 | act(result.current)
56 |
57 | expect(cb).toHaveBeenCalledTimes(3)
58 | act(() => jest.advanceTimersByTime(100))
59 | expect(cb).toHaveBeenCalledTimes(4)
60 | })
61 |
62 | it('should set the last value the callback was invoked with after 100ms', () => {
63 | const {result} = renderDebounce(1, 100)
64 |
65 | act(() => result.current[1](2))
66 | expect(result.current[0]).toBe(1)
67 |
68 | act(() => result.current[1](3))
69 | act(() => jest.advanceTimersByTime(50))
70 |
71 | act(() => result.current[1](4))
72 | act(() => jest.advanceTimersByTime(50))
73 | expect(result.current[0]).toBe(1)
74 |
75 | act(() => jest.advanceTimersByTime(50))
76 | expect(result.current[0]).toBe(4)
77 | })
78 |
79 | test('it should set the value on the leading edge', () => {
80 | const {result} = renderDebounce(1, 100, true)
81 |
82 | act(() => result.current[1](2))
83 | expect(result.current[0]).toBe(2)
84 |
85 | act(() => result.current[1](3))
86 | act(() => result.current[1](4))
87 |
88 | act(() => jest.advanceTimersByTime(50))
89 | expect(result.current[0]).toBe(2)
90 |
91 | act(() => jest.advanceTimersByTime(50))
92 | expect(result.current[0]).toBe(4)
93 | })
94 | })
95 |
--------------------------------------------------------------------------------
/packages/google-optimize/src/index.tsx:
--------------------------------------------------------------------------------
1 | import {useEffect, useState} from 'react'
2 |
3 | // Usage:
4 | // const Page = useGoogleOptimize('hhWP8gOsTvvT2P_KlFjw', [PageA, PageB])
5 | // return
6 | function useGoogleOptimize(
7 | experimentId: string,
8 | variants: T[],
9 | timeout = Infinity
10 | ): T | null {
11 | const [variant, setVariant] = useState(null)
12 |
13 | useEffect(
14 | () => {
15 | // Sets a timeout
16 | let optimizeTimedOut: ReturnType
17 |
18 | if (timeout !== Infinity) {
19 | optimizeTimedOut = setTimeout(() => {
20 | // Clears the callback just in case this was a network timeout
21 | removeCallback()
22 | // Defaults to the 'Original'
23 | setVariant(0)
24 | }, timeout)
25 | }
26 | // Sets the variant returned by Optimize and clears the timeout check
27 | const callback = (value: number) => {
28 | optimizeTimedOut && clearTimeout(optimizeTimedOut)
29 | setVariant(Number(value))
30 | }
31 | // Documented here:
32 | // https://support.google.com/optimize/answer/9059383?hl=en
33 | // @ts-ignore
34 | gtag('event', 'optimize.callback', {
35 | name: experimentId,
36 | callback,
37 | })
38 |
39 | // Cleans up the optimize callback if the request times out
40 | const removeCallback = () => {
41 | optimizeTimedOut && clearTimeout(optimizeTimedOut)
42 | // @ts-ignore
43 | gtag('event', 'optimize.callback', {
44 | name: experimentId,
45 | callback,
46 | remove: true,
47 | })
48 | }
49 | // Unregisters the event when the parent is unmounted or the experiment
50 | // id is changed
51 | return removeCallback
52 | },
53 | // Only update if the experiment ID changes
54 | [experimentId, timeout]
55 | )
56 | // When testing functions you should use null checks. No special treatment
57 | // is necessary with React components.
58 | return variant === null ? null : variants[variant]
59 | }
60 |
61 | function gtag() {
62 | if (typeof window !== 'undefined') {
63 | if (typeof window.gtag === 'function') {
64 | // eslint-disable-next-line prefer-rest-params
65 | window.gtag.apply(null, arguments as any)
66 | } else if (Array.isArray(window.dataLayer)) {
67 | // eslint-disable-next-line prefer-rest-params
68 | window.dataLayer.push(arguments)
69 | } else {
70 | if (
71 | typeof process !== 'undefined' &&
72 | process.env.NODE_ENV !== 'production' &&
73 | !didWarn
74 | ) {
75 | didWarn = true
76 | console.warn(
77 | '[@react-hook/google-optimize] Google Tag Manager was not found on your site. Neither "gtag()" or "dataLayer[]" could be located on the "window". If you are not using Google Tag Manager in dev you can ignore this warning. Otherwise, see the Google Tag Manager dev guide for examples: https://developers.google.com/tag-manager/devguide'
78 | )
79 | }
80 | }
81 | }
82 | }
83 |
84 | let didWarn = false
85 |
86 | declare global {
87 | interface Window {
88 | dataLayer: any[]
89 | }
90 | }
91 |
92 | export default useGoogleOptimize
93 |
--------------------------------------------------------------------------------
/packages/google-optimize/src/index.test.tsx:
--------------------------------------------------------------------------------
1 | /* jest */
2 | import * as React from 'react'
3 | import {render, act} from '@testing-library/react'
4 | import useGoogleOptimize from './index'
5 |
6 | jest.useFakeTimers()
7 | afterEach(() => jest.clearAllTimers())
8 |
9 | describe('useOptimize', () => {
10 | it('should pick "3"', () => {
11 | // @ts-ignore
12 | window.gtag = (command, eventName, eventParams) => {
13 | if (eventParams.remove) return
14 | eventParams.callback(2)
15 | }
16 |
17 | const Optimize = () => {
18 | const variant = useGoogleOptimize('abc', [1, 2, 3])
19 | return
27 |
28 |
29 | A React hook for tracking the hover state of DOM elements in browsers
30 | where hovering is possible. If the browser does not support hover states
31 | (e.g. a phone) the `isHovering` value will always be `false`.
32 |
33 | ## Quick Start
34 |
35 | [Check out the example on **CodeSandbox**](https://codesandbox.io/s/react-hookhover-example-oohtc)
36 |
37 | ```jsx harmony
38 | import * as React from 'react'
39 | import useHover from '@react-hook/hover'
40 |
41 | const Component = (props) => {
42 | const target = React.useRef(null)
43 | const isHovering = useHover(target, {enterDelay: 200, leaveDelay: 200})
44 | return
{isHovering ? 'Hovering' : 'Not hovering'}
45 | }
46 | ```
47 |
48 | ## API
49 |
50 | ### useHover(target, options?)
51 |
52 | ```tsx
53 | function useHover(
54 | target: React.RefObject | T | null,
55 | options: UseHoverOptions = {}
56 | ): boolean
57 | ```
58 |
59 | #### Arguments
60 |
61 | | Argument | Type | Required? | Description |
62 | | -------- | ---------------------------------------------------- | --------- | ------------------------------------------------------------------------------------ |
63 | | target | React.RefObject | T | null | Yes | A React ref created by `useRef()` or an HTML element |
64 | | options | [`UseHoverOptions`](#usehoveroptions) | Yes | Configuration options for the hook. See [`UseHoverOptions`](#usehoveroptions) below. |
65 |
66 | #### Returns `boolean`
67 |
68 | This hook returns `true` if the element in `ref` is in a hover state, otherwise `false`. This value
69 | is always `false` on devices that don't have hover states, i.e. phones.
70 |
71 | #### UseHoverOptions
72 |
73 | | Property | Type | Description |
74 | | ---------- | ------ | -------------------------------------------------------------- |
75 | | enterDelay | number | Delays setting `isHovering` to `true` for this amount in `ms` |
76 | | leaveDelay | number | Delays setting `isHovering` to `false` for this amount in `ms` |
77 |
78 | ## LICENSE
79 |
80 | MIT
81 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at jared.lunde@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/packages/size/README.md:
--------------------------------------------------------------------------------
1 |
2 |
27 |
28 |
29 | A React hook for measuring the size of HTML elements including when they change
30 |
31 | ## Features
32 |
33 | - [x] Determines the size of the element including any padding, borders, and scroll bars.
34 | - [x] The size reported by the hook updates each time the size of the element changes.
35 | - [x] Uses a single `ResizeObserver` for tracking all elements used by the hooks.
36 | [This approach is astoundingly more performant](https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/z6ienONUb5A/F5-VcUZtBAAJ)
37 | than using a `ResizeObserver` per element which most hook implementations do.
38 | - [x] Uses [`@juggle/resize-observer`](https://github.com/juggle/resize-observer) as a ponyfill when `ResizeObserver` isn't supported
39 | by the current browser.
40 | - [x] Automatically unobserves the target element when the hook unmounts.
41 |
42 | ## Quick Start
43 |
44 | [Check out an example on **CodeSandbox**](https://codesandbox.io/s/react-hooksize-example-vbpnl)
45 |
46 | ```jsx harmony
47 | import * as React from 'react'
48 | import useSize from '@react-hook/size'
49 |
50 | const Component = () => {
51 | const target = React.useRef(null)
52 | const [width, height] = useSize(target)
53 |
54 | return (
55 |