Command Palette

Search for a command to run...

1.4k
Components
PreviousNext

Slide to Unlock

Interactive slider inspired by the classic iPhone "slide to unlock" gesture.

Loading...
"use client"
 
import { toast } from "sonner"
 
import { useSound } from "@/hooks/use-sound"
import { SOUNDS } from "@/lib/sounds"
import { ShimmeringText } from "@/components/ncdai/shimmering-text"
import {
  SlideToUnlock,
  SlideToUnlockHandle,
  SlideToUnlockText,
  SlideToUnlockTrack,
} from "@/components/ncdai/slide-to-unlock"
 
export function SlideToUnlockDemo1() {
  const playSound = useSound(SOUNDS.unlock)
 
  return (
    <SlideToUnlock
      onUnlock={() => {
        playSound()
        toast.success("Unlocked")
      }}
    >
      <SlideToUnlockTrack>
        <SlideToUnlockText>
          {({ isDragging }) => (
            <ShimmeringText text="slide to unlock" isStopped={isDragging} />
          )}
        </SlideToUnlockText>
        <SlideToUnlockHandle />
      </SlideToUnlockTrack>
    </SlideToUnlock>
  )
}

awesome. Love the components, especially slide-to-unlock. Great job

Guillermo Rauch
Guillermo Rauch
CEO @Vercel

Features

  • Smooth drag interaction with spring physics via Motion.
  • Composable compound components (track, handle, text).
  • Customizable handle and colors.
  • Built-in shimmering text effect.

Installation

$ pnpm dlx shadcn add @ncdai/slide-to-unlock

Usage

import {
  SlideToUnlock,
  SlideToUnlockHandle,
  SlideToUnlockText,
  SlideToUnlockTrack,
} from "@/components/ncdai/slide-to-unlock"
 
import { ShimmeringText } from "@/component/ncdai/shimmering-text"
<SlideToUnlock>
  <SlideToUnlockTrack>
    <SlideToUnlockText>
      <ShimmeringText />
    </SlideToUnlockText>
    <SlideToUnlockHandle />
  </SlideToUnlockTrack>
</SlideToUnlock>

API Reference

SlideToUnlock

Prop

Type

SlideToUnlockText

Prop

Type

Examples

Default

Loading...
"use client"
 
import { toast } from "sonner"
 
import { useSound } from "@/hooks/use-sound"
import { SOUNDS } from "@/lib/sounds"
import { ShimmeringText } from "@/components/ncdai/shimmering-text"
import {
  SlideToUnlock,
  SlideToUnlockHandle,
  SlideToUnlockText,
  SlideToUnlockTrack,
} from "@/components/ncdai/slide-to-unlock"
 
export function SlideToUnlockDemo1() {
  const playSound = useSound(SOUNDS.unlock)
 
  return (
    <SlideToUnlock
      onUnlock={() => {
        playSound()
        toast.success("Unlocked")
      }}
    >
      <SlideToUnlockTrack>
        <SlideToUnlockText>
          {({ isDragging }) => (
            <ShimmeringText text="slide to unlock" isStopped={isDragging} />
          )}
        </SlideToUnlockText>
        <SlideToUnlockHandle />
      </SlideToUnlockTrack>
    </SlideToUnlock>
  )
}

Custom Color

Loading...
"use client"
 
import { toast } from "sonner"
 
import { ShimmeringText } from "@/components/ncdai/shimmering-text"
import {
  SlideToUnlock,
  SlideToUnlockHandle,
  SlideToUnlockText,
  SlideToUnlockTrack,
} from "@/components/ncdai/slide-to-unlock"
 
export function SlideToUnlockDemo2() {
  return (
    <>
      <SlideToUnlock
        className="bg-linear-to-b from-zinc-800 to-zinc-900"
        onUnlock={() => {
          const myPromise = new Promise((resolve) => {
            setTimeout(() => {
              resolve(true)
            }, 1000)
          })
 
          toast.promise(myPromise, {
            loading: "Connecting...",
            success: () => `Connected`,
            error: ({ message }) => `Error: ${message}`,
          })
        }}
      >
        <SlideToUnlockTrack>
          <SlideToUnlockText>
            {({ isDragging }) => (
              <ShimmeringText
                className="[--color:var(--color-zinc-600)] [--shimmering-color:var(--color-zinc-50)]"
                text="slide to answer"
                isStopped={isDragging}
              />
            )}
          </SlideToUnlockText>
 
          <SlideToUnlockHandle className="bg-linear-to-b from-emerald-500 to-emerald-700 text-white" />
        </SlideToUnlockTrack>
      </SlideToUnlock>
    </>
  )
}

Custom Handle

Loading...
"use client"
 
import { toast } from "sonner"
 
import { ShimmeringText } from "@/components/ncdai/shimmering-text"
import {
  SlideToUnlock,
  SlideToUnlockHandle,
  SlideToUnlockText,
  SlideToUnlockTrack,
} from "@/components/ncdai/slide-to-unlock"
 
export function SlideToUnlockDemo3() {
  return (
    <SlideToUnlock
      className="w-[180px] rounded-full ring-0"
      handleWidth={40}
      onUnlock={() => toast.success("Stopped")}
    >
      <SlideToUnlockTrack>
        <SlideToUnlockText className="pl-0">
          {({ isDragging }) => (
            <ShimmeringText text="slide to stop" isStopped={isDragging} />
          )}
        </SlideToUnlockText>
 
        <SlideToUnlockHandle className="w-10 rounded-full dark:bg-zinc-700">
          <svg
            className="size-5 dark:text-white"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 256 256"
          >
            <path
              d="M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z"
              fill="currentColor"
            />
          </svg>
        </SlideToUnlockHandle>
      </SlideToUnlockTrack>
    </SlideToUnlock>
  )
}