Generated by create-react-hooks.
-
useClientHydrated
-
useElementSize
-
useFocusTrap
-
useId
-
useInteraction
-
useLazyRef
-
useMedia
-
useNativeLazyLoading
-
useScript
-
useToggle
-
useWindowSize
-
useListenAlong https://github.com/punctuations
-
useFetch
-
usePagination https://github.com/itsfaqih
-
useEffectDebounced https://github.com/nas5w
-
useWindowDimensions
-
useWindowHeight
-
useWindowWidth https://github.com/jacobdcastro
-
captanhooks-unsorted https://github.com/stevenpersia
-
gilbarbarahooks-unsorted https://github.com/gilbarbara
-
useLastFM https://github.com/alii
-
useInputValue https://github.com/rehooks
https://github.com/domitriusclark
-
react-hooks-lib https://github.com/beizhedenglong
-
cubic-bezier-hook https://github.com/beizhedenglong
-
usePagination-react https://github.com/berat
-
xooks-unsorted https://github.com/rtivital
-
react-recipes-unsorted https://github.com/craig1123
-
useLocalStorageState https://github.com/astoilkov
-
usePlatform
-
useSelectedItems https://github.com/LauraBeatris
-
usePagination-headless https://github.com/lucasmogari
-
classForm
-
hookForm https://github.com/tiagofsanchez
-
react-firebase-hooks-unsorted https://github.com/CSFrequency
-
useBoolean
-
useCounter https://github.com/iamludal
-
useHooks-unsorted https://github.com/uidotdev
-
useAsync
-
useKeypress
-
useWebStorage
-
usePrevious
-
useComponentSize
-
useWindowSize https://github.com/talves
-
useMediaBreakPoints
-
hookToHoc
-
hookToRenderProps https://github.com/beizhedenglong
-
useCloudinary
-
use-cloudinary https://github.com/domitriusclark
-
usePrevious
-
useReducer
-
useFriendStatus
-
react-state-hooks
-
simple-state
-
complex-state
-
global-state https://www.robinwieruch.de/react-state-usereducer-usestate-usecontext
-
use-local-storage https://github.com/nas5w
useLocalStorage
behaves just like the native react useState
hook, except that any and all state updates are automatically saved in the browser's localstorage under the provided key. The first argument is the name of the key to save it under, and the second argument is the initial value. The hook returns the current state and an updater function just like useState
.
When the app reloads, the hook will first look for a previously cached value. If one is found, it will be used as the initial value instead of the provided initial value.
import { useLocalStorage } from 'crooks'
const App = () => {
const [state, setState] = useLocalStorage("LOCAL_STORAGE_KEY", initialValue)
return (
<div>App</div>
)
}
useFiler
manages a simple virtual file system using the browser's localstorage. This is especially useful for quick prototyping. Any type of data can be saved in a file provided that it's JSON-serializable.
When the hook is first initialized it returns the files as an empty object.
import { useFiler } from 'crooks'
const App = () => {
const [files, {add, remove, update, clear}] = useFiler("LOCAL_STORAGE_KEY")
return (
<div>App</div>
)
}
By default, each file has an automatically generated id generated using the shortid package. Each single file is structured as follows:
{
id: "ogn41na",
created: 489108491,
modified: 489108561,
data: "The file's data."
}
The files
object returned as the first parameter of the hook represents all of the current files as an object, with each file's ID as the key, and the file as the value.
The first parameter of the add function may be any JSON-serializable data and is required. The data will be saved as a new file with an automatically generated ID. If you would like to override the automatically-generated ID, you may pass a String or Int as the second parameter and it will be used as the ID. If the ID already exists, the existing file will be overwritten.
add("Any JSON-serializable data to be saved as a new file.")
To update a file, pass as the first parameter, the ID of the file you want to update. The second parameter is the data you want to overwrite the file with.
update("jal31af", "The new data to overwrite the file with.")
As with the native useState
, update()
accepts a callback function injected with the previous file.
update("jal31af", file => ([...file.data, "New item"]))
The remove function simply accepts a file ID of the file you wish to remove.
remove("zoep31a")
clear()
The useKeyboardShortcut
hook listens to "keydown" events on the Document, and will call the provided action when the specified Javascript keyCode is detected. The shortcut listener is enabled by default, but can be declaratively disabled by passing disabled: true
to the hook.
keyboard.info is a great resource for finding Javascript keyCodes.
import { useKeyboardShortcut } from 'crooks'
const App = () => {
const submit = () => {
console.log('Submitted')
}
const {enable, disable} = useKeyboardShortcut({
keyCode: 13,
action: submit,
disabled: false // This key is not required
})
return (
<div>
<button onClick={enable}>Enable</button>
<button onClick={disable}>Disable</button>
</div>
)
}
With keyboard shortcuts, there are times when you may want to imperatively enable or disable the shortcut listener. For these occasions, the hook returns enable
and disable
functions.
useOnClickOutside
accepts a function that will be called when there's a click outside of a target element. The hook returns a ref, which you pass to the ref attribute of the element you want to target.
import { useOnClickOutside } from 'crooks'
const App = () => {
const handleClickOutside = () => {
console.log("You clicked outside of the blue box")
}
const outsideRef = useOnClickOutside(handleClickOutside)
return (
<div>
<div ref={outsideRef}> I'm a blue box </div>
</div>
)
}
For performance reasons, you may not want to always listen for clicks outside of an element. For these times you can pass a Boolean
as a second parameter to this hook representing whether or not the listener should be disabled like so:
import { useState } from 'react'
import { useOnClickOutside } from 'crooks'
const App = () => {
const [isDisabled, setIsDisabled] = useState(false)
const disableOnOutside = () => setIsDisabled(true)
const handleClickOutside = () => {
console.log("You clicked outside of the blue box")
}
const outsideRef = useOnClickOutside(handleClickOutside, isDisabled)
return (
<div>
<button onClick={disableOnOutside}>Stop listening for outside clicks</button>
<div ref={outsideRef}> I'm a blue box </div>
</div>
)
}
/**
* Params
* @param {string} url - The image url
*/
/**
* Returns
* @param {array} size - The image size [width, height]
*/
import React from 'react';
import useImageSize from '@use-hooks/image-size';
export default function App() {
const url = 'https://cdn.int64ago.org/ogk39i54.png';
const [width, height] = useImageSize(url);
return (
<div>
<h2>DEMO of <span style={{ color: '#F44336' }}>@use-hooks/image-size</span></h2>
<div>
<img src={url} width={100} height={100} alt="" />
<div>Natural size: {width} x {height}</div>
</div>
</div>
);
}
import usePermissions from '../src';
const format = hasPermissions => {
switch (hasPermissions) {
// User has granted permissions
case true: {
return "Permissions granted";
}
// User has denied permissions
case false: {
return "Permissions denied";
}
// User will be prompted for permissions
case null: {
return "Asking for permissions";
}
}
}
function App() {
const hasPermissions = usePermissions("geolocation");
const content = format(hasPermissions);
return <h1>{content}</h1>;
}
const output = useClientHydrated()
import React, { useEffect, useState } from 'react'
import useClientHydrated from '@charlietango/use-client-hydrated'
const Component = () => {
const hydrated = useClientHydrated()
// Set the initial ready state based on hydrated. Will be `false` first time the component is rendered, but true after hydration.
const [ready, setReady] = useState(hydrated)
useEffect(() => {
// We have been hydrated correctly now
setReady(true)
}, [])
return <div>{ready ? 'Hydrated' : 'Hydrating'}</div>
}
export default Component
const [ref, size] = useElementSize()
The hook returns an Array with a ref
function, and the measured size
.
Assign the ref
to the element you want to measure.
import React from 'react'
import useElementSize from '@charlietango/use-element-size'
const Component = () => {
const [ref, size] = useElementSize()
return (
<div ref={ref}>
<pre>
<code>{JSON.stringify(size, null, 2)}</code>
</pre>
</div>
)
}
export default Component
const ref = useFocusTrap(active, options)
The useFocusTrap
hook returns a ref
that you should assign to the DOM element that needs to trap focus.
Anything outside that element, will no longer be able to receive focus.
You can toggle the trap by setting the active
boolean. By default it's activated once the ref
is assigned.
The focus trap accepts an object with these optional options, that give you a bit more control.
Name | Type | Default | Required | Description |
---|---|---|---|---|
focusSelector | string / HTMLElement |
undefined |
false | Assign focus when activated to the element matching this selector - or a specific element you supply. By default focus will be set to the first valid tab target. |
disableAriaHider | boolean |
false |
false | Disables setting aria-hidden on other elements inside the document.body while the trap is active. |
import React from 'react'
import useFocusTrap from '@charlietango/use-focus-trap'
const Component = () => {
const ref = useFocusTrap()
return (
<div ref={ref}>
<button>Trapped to the button</button>
</div>
)
}
export default Component
When using this hook to create a Modal, there are still a few things you need to handle, that's outside the scope of this hook:
- Trap focus
- Close on escape
- Close on backdrop clicked
This is the base component for creating a <Modal />
. It receives an onRequestClose
method,
that can be triggered to tell the containing component to update it's state to close the modal.
It doesn't contain a <Backdrop />
, but that would be a absolute positioned component, that
when clicked triggers the onRequestClose
method.
import React, { useEffect } from 'react'
import ReactDOM from 'react-dom'
import useFocusTrap from '@charlietango/use-focus-trap'
import styled from 'styled-components'
type Props = {
onRequestClose?: () => void
children?: React.ReactNode
isOpen: boolean
className?: string
}
const Wrapper = styled.div`
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 5;
`
function BaseModal({ children, isOpen, onRequestClose, className }: Props) {
const ref = useFocusTrap()
function handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
if (onRequestClose) onRequestClose()
}
}
useEffect(() => {
if (isOpen) {
document.addEventListener('keydown', handleKeyDown)
return () => {
document.removeEventListener('keydown', handleKeyDown)
}
}
return
}, [isOpen])
const modal = (
<Wrapper
ref={ref}
style={{ pointerEvents: !isOpen ? 'none' : undefined }}
role="dialog"
className={className}
>
{children}
</Wrapper>
)
return ReactDOM.createPortal(modal, window.document.body)
}
BaseModal.displayName = 'BaseModal'
BaseModal.defaultProps = {}
export default BaseModal
const id = useId(prefix?: string)
https://github.com/charlie-tango
All of our Hooks are published into their own NPM module, so you can pick and choose exactly the ones you need.
- @charlietango/use-client-hydrated (useClientHydrated) - Check if the client has been hydrated
- @charlietango/use-element-size (useElementSize) - Measure the size of a DOM element using ResizeObserver
- @charlietango/use-focus-trap (useFocusTrap) - Trap keyboard focus inside a DOM element, to prevent the user navigating outside a modal
- @charlietango/use-id (useId) - Generate a deterministic id using a Context Provider
- @charlietango/use-interaction (useInteraction) - Monitor the user interactions on an element
- @charlietango/use-lazy-ref (useLazyRef) - Create a new ref with lazy instantiated value
- @charlietango/use-media (useMedia) - Detect if the browser matches a media query
- @charlietango/use-native-lazy-loading (useNativeLazyLoading) - Detect if the browser supports the new 'loading' attribute on Image elements.
- @charlietango/use-script (useScript) - Load an external third party script
- @charlietango/use-toggle (useToggle) - Simple boolean state toggler
- @charlietango/use-window-size (useWindowSize) - Get the width and height of the viewport
The @charlietango/hooks module collects all of the individual modules into a single dependency. The module is optimized for tree shaking, so you application should only include the dependencies you actually use.