Slide to Unlock
lyminhnghia/slide-to-unlockFreeComponent
Interactive slider inspired by the classic iPhone 'slide to unlock' gesture.
Install it
npx shadcn@latest add https://lyminhnghia.github.io/r/slide-to-unlock.jsonSource
1"use client"23import {4 animate,5 motion,6 type MotionValue,7 useMotionValue,8 useTransform,9} from "motion/react"10import type { ComponentProps, ComponentPropsWithoutRef, JSX } from "react"11import { createContext, useCallback, useContext, useRef, useState } from "react"1213import { cn } from "@/lib/utils"1415type SlideToUnlockContextValue = {16 x: MotionValue<number>17 trackRef: React.RefObject<HTMLDivElement | null>18 isDragging: boolean19 handleWidth: number20 textOpacity: MotionValue<number>21 onDragStart: () => void22 onDragEnd: () => void23}2425const SlideToUnlockContext = createContext<SlideToUnlockContextValue | null>(26 null27)2829function useSlideToUnlock() {30 const context = useContext(SlideToUnlockContext)31 if (!context) {32 throw new Error(33 `SlideToUnlock components must be used within SlideToUnlock`34 )35 }36 return context37}3839export type SlideToUnlockRootProps = ComponentProps<"div"> & {40 /**41 * Width of the drag handle in pixels.42 * @defaultValue 5643 * */44 handleWidth?: number45 /** Called when the handle is dragged fully to the end. */46 onUnlock?: () => void47}4849export function SlideToUnlock({50 className,51 handleWidth = 56,52 children,53 onUnlock,54 ...props55}: SlideToUnlockRootProps) {56 const trackRef = useRef<HTMLDivElement>(null)57 const [isDragging, setIsDragging] = useState(false)58 const x = useMotionValue(0)5960 const fadeDistance = handleWidth61 const textOpacity = useTransform(x, [0, fadeDistance], [1, 0])6263 const handleDragStart = useCallback(() => {64 setIsDragging(true)65 }, [])6667 const handleDragEnd = useCallback(() => {68 setIsDragging(false)6970 const trackWidth = trackRef.current?.offsetWidth || 071 const maxX = trackWidth - handleWidth7273 if (x.get() >= maxX) {74 onUnlock?.()75 } else {76 animate(x, 0, { type: "spring", bounce: 0, duration: 0.25 })77 }78 }, [x, onUnlock, handleWidth])7980 return (81 <SlideToUnlockContext.Provider82 value={{83 x,84 trackRef,85 isDragging,86 handleWidth,87 textOpacity,88 onDragStart: handleDragStart,89 onDragEnd: handleDragEnd,90 }}91 >92 <div93 data-slot="slide-to-unlock"94 className={cn(95 "w-54 rounded-xl bg-muted p-1 shadow-inner ring-1 ring-foreground/10 ring-inset",96 className97 )}98 {...props}99 >100 {children}101 </div>102 </SlideToUnlockContext.Provider>103 )104}105106export type SlideToUnlockTrackProps = ComponentProps<"div">107108// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from lyminhnghia
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Apple Hello Effectapple-hello-effect | lyminhnghia | Components | Free | 1 dep | |
| chevrons-up-down-iconchevrons-up-down-icon | lyminhnghia | Components | Free | no deps | |
| Code Block Commandcode-block-command | lyminhnghia | Components | Free | 4 deps · 3 files | |
| Consent Managerconsent-manager | lyminhnghia | Components | Free | 1 dep | |
| Copy Buttoncopy-button | lyminhnghia | Components | Free | 2 deps · 2 files | |
| GitHub Starsgithub-stars | lyminhnghia | Components | Free | no deps | |
| Scroll Fade Effectscroll-fade-effect | lyminhnghia | Components | Free | no deps | |
| Shimmering Textshimmering-text | lyminhnghia | Components | Free | 1 dep |
