Skip to content

Latest commit

 

History

History
297 lines (215 loc) · 7.17 KB

README.md

File metadata and controls

297 lines (215 loc) · 7.17 KB

React Addons Hooks

Allows asynchronous fetch operations to be run, whilst handling success, error and processing states.

Usage

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 the scrollWidth of the container is larger than the containers width
  • list--scrolling - added when a scroll event is fired on the container
  • list--dragging - added when the user begins dragging the container

Usage

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.

Usage

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}</>
  }
}

Attach event listeners conditionally

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.

Usage

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.

Usage

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)

Usage

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.

Usage

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)

Usage

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.

Usage

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))

Usage

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()

Usage

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>
  )
}