Allows asynchronous fetch operations to be run, whilst handling success, error and processing states.
import React, { useCallback } from 'react'
import { useAsync } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const onSubmit = useCallback(async (data) => {
return validate(data)
})
// Passing `true` as the second argument, will also run the callback immediately on page load
// The third argument is a dependency array, which works in the same way as `useEffect`.
// When a change to an item in the dependency array occurs, the hooks state is reset
const { execute, status, error } = useAsync(onSubmit, false, [onSubmit])
return (
{status === 'success' ? (
<div>
{'Success message'}
</div>
) : (
<form onSubmit={execute}>
{status === 'error' && (
<span>{error}</span>
)}
{status !== 'pending' && (
<button type="submit">Submit</button>
)}
</form>
)}
)
}
Enables click and drag to scroll an element with overflow.
The className
passed to the object should match the container. The component then adds and removes the following classes as you interact with it (based on a class of list
):
list--draggable
- automatically added when thescrollWidth
of the container is larger than the containers widthlist--scrolling
- added when ascroll
event is fired on the containerlist--dragging
- added when the user begins dragging the container
import React, { useRef, MutableRefObject } from 'react'
import { useDraggableScroll } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const scrollContainer =
useRef<HTMLUListElement>() as MutableRefObject<HTMLUListElement>
const { events } = useDraggableScroll(scrollContainer, { className: 'list' })
return (
<ul class="list" ref={scrollContainer} {...events}>
{items.map((item) => (
<Item item={item} />
))}
</ul>
)
}
Adds an event listener to an object, with an optional conditional flag.
import React, { useCallback, useState } from 'react'
import { useEventListener } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const [yPos, setYPos] = useState<number>(0)
const handleScroll = useCallback((event) => {
setYPos(window.scrollY)
}, [])
useEventListener(
'scroll',
handleScroll,
{ passive: true },
typeof window !== 'undefined' ? window : null,
)
return () => {
;<>{yPos}</>
}
}
Passing a 5th boolean parameter, allows the event listener to be added when the parameter resolves to true, for example, using the isInViewport
to only attach the event listener when the component is within the viewport.
import React, { useCallback, useState } from 'react'
import { useEventListener } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const [yPos, setYPos] = useState<number>(0)
const { isInViewport, setRef } = useIsInViewport(false)
const handleScroll = useCallback((event) => {
setYPos(window.scrollY)
}, [])
useEventListener(
'scroll',
handleScroll,
{ passive: true },
typeof window !== 'undefined' ? window : null,
isInViewport,
)
return () => {
;<div ref={setRef}>{yPos}</div>
}
}
Used to hide an element on scroll down, and show it on scroll up. Usually used for fixed navigation.
import React from 'react'
import { useHideOnScroll } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const hidden = useHideOnScroll(false) // Argument determines whether element is hidden before first scroll
return <div aria-hidden={hidden}></div>
}
Generate a unique ID for a component with a given prefix.
import React from 'react'
import { useId } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const id = useId('my-component-')
return <div id={id}></div>
}
Returns true/false depending on whether or not the given ref is visible on screen.
import React from 'react'
import { useIsInViewport } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const { isInViewport, setRef } = useIsInViewport(false)
return (
<div ref={setRef}>{isInViewport ? 'Now you see me' : "Now you don't"}</div>
)
}
Root margin and threshold for the internal IntersectionObserver can be overridden by passing them to the hook
const { isInViewport, setRef } = useIsInViewport(
false,
'100px 100px',
[0, 0.25, 0.5, 0.75, 1],
)
Returns true/false depending on whether the screen size is smaller than a given size (default: 63.75em
)
import React from 'react'
import { useIsMobile } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const isMobile = useIsMobile(false, '90em')
return (
<>
{isMobile : 'This is a mobile device' : 'This is a desktop device'}
</>
)
}
Returns true if the passed ref contains enough content to cause it to scroll.
const element = useRef<HTMLElement>() as MutableRefObject<HTMLElement>
const isOverflowing = useIsOverflowing(element.current)
return (
<div ref={element} />
)
Use a boolean flag to determine whether scrolling should be disabled on the body (for example when a modal is open)
import React, { useState } from 'react'
import { useLockBodyScroll } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const [open, setOpen] = useState<boolean>(false)
useLockBodyScroll(open)
}
When used in conjunction with the Modal
component, provides methods for opening/closing the modal from another component.
const { isOpen, openModal, closeModal } = useModal('newsletter')
if (isOpen) {
closeModal()
}
Returns true/false depending on whether the users would prefer reduced motion (based on @media (prefers-reduced-motion: reduce)
)
import React from 'react'
import { useMotionAllowed } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const isMotionAllowed = useMotionAllowed(false)
return <>{motionAllowed ? <Animation /> : 'No animation'}</>
}
Provides efficient parallax calculations for a given ref
, without use of element.getBoundingClientRect()
import React, { useRef } from 'react'
import { useParallax } from '@superrb/gatsby-addons/hooks'
const MyComponent = () => {
const ref = useRef<HTMLElement>() as MutableRefObject<HTMLElement>
const pos = useParallax(ref)
return (
<div ref={ref}>
<div style={{ transform: `translateY(${pos / 5}%)` }} />
</div>
)
}