New: Activity Terrain +12 more

useDelayedLoading

Shows a loading state only when work is actually slow, then keeps it up long enough that it never flickers.

2 examplesFrom HextaUI (MIT)

Installation

Run this in your project. It adds the files, installs the npm packages and anything this builds on, and sets up the theme:

npx shadcn@latest add https://kryptonite-ui.vercel.app/r/use-delayed-loading.json
Install manually
  1. Copy this into hooks/use-delayed-loading.ts:

    use-delayed-loading.ts
    import * as React from "react"
    
    type DelayedLoadingOptions = {
      delay?: number
      minDuration?: number
    }
    
    function useDelayedLoading(
      loading: boolean,
      { delay = 150, minDuration = 400 }: DelayedLoadingOptions = {}
    ) {
      const [visible, setVisible] = React.useState(false)
      const shownAt = React.useRef(0)
    
      React.useEffect(() => {
        if (loading === visible) {
          return
        }
        if (loading) {
          const timer = setTimeout(
            () => {
              shownAt.current = Date.now()
              setVisible(true)
            },
            Math.max(0, delay)
          )
          return () => clearTimeout(timer)
        }
        const remaining = Math.max(0, minDuration - (Date.now() - shownAt.current))
        const timer = setTimeout(() => setVisible(false), remaining)
        return () => clearTimeout(timer)
      }, [loading, visible, delay, minDuration])
    
      return visible
    }
    
    export { useDelayedLoading }
    export type { DelayedLoadingOptions }

Usage

Skeletons

Feedback

Questions, bugs or ideas for useDelayedLoading? Post them here, or reply to someone else. Sign in with GitHub to comment.