Interactive Slide Action•Swipe to Unlock
Slide to Grow Tactile Slider
Smooth gesture swipe-to-grow slider button featuring dynamic laser channel reveal, spring damping, and physical knob transformation.
preview.tsx
Lets Grow!
Get Started
Completions:0
Hover or click to interact
Customizer
PRESETS & VARIATIONS
All Variants Preview
Drag knob or click channel to trigger animated slider unlock
Figma Silvertheme="silver"
Lets Grow!
Get Started
UI Pirate Magmatheme="uipirate"
Welcome!
Swipe to Unlock
Dark Obsidiantheme="dark"
Confirmed
Slide To Confirm
Cyberpunk Violettheme="cyberpunk"
Deployed!
Slide to Deploy
Neon Emeraldtheme="emerald"
Authorized
Swipe Access
Magma Flaretheme="orange"
Paid!
Pay $49
Installation & Setup
Install required peer dependencies for Framer Motion spring dragging:
npm install framer-motion clsx
Code & Integration
SlideGrowButton.tsx• Production Ready
"use client";
import React, { useState } from "react";
import { motion } from "framer-motion";
export type SlideGrowTheme = "silver" | "uipirate" | "dark" | "cyberpunk" | "emerald";
export type SlideGrowSize = "xs" | "sm" | "md" | "lg" | "xl";
export interface SlideGrowButtonProps {
startLabel?: string;
activeLabel?: string;
theme?: SlideGrowTheme;
size?: SlideGrowSize;
onComplete?: () => void;
className?: string;
}
export function SlideGrowButton({
startLabel = "Get Started",
activeLabel = "Lets Grow!",
theme = "silver",
size = "md",
onComplete,
className = "",
}: SlideGrowButtonProps) {
const [isSlid, setIsSlid] = useState(false);
const themeConfig = {
silver: {
bg: "bg-[#E6E8ED]",
border: "border-white/80",
channel: "bg-[#0077FF]",
text: "text-[#333333]",
slidText: "text-white",
},
uipirate: {
bg: "bg-[#1C1815]",
border: "border-orange-500/30",
channel: "bg-[#FF5B04]",
text: "text-[#F5F5F5]",
slidText: "text-white",
},
}[theme as "silver" | "uipirate"] || {
bg: "bg-[#E6E8ED]",
border: "border-white/80",
channel: "bg-[#0077FF]",
text: "text-[#333333]",
slidText: "text-white",
};
return (
<div
className={`relative inline-flex items-center select-none p-2 rounded-full ${themeConfig.bg} ${themeConfig.border} border shadow-xl ${className}`}
>
<div className="relative w-[230px] h-[52px] flex items-center justify-between px-6 rounded-full overflow-hidden">
{/* Animated Slide Channel */}
<motion.div
animate={{ width: isSlid ? "100%" : "0%" }}
transition={{ type: "spring", stiffness: 350, damping: 28 }}
className={`absolute left-0 top-0 bottom-0 ${themeConfig.channel} rounded-full`}
/>
{/* Text */}
<span
className={`relative z-10 font-bold text-sm transition-colors duration-200 ${
isSlid ? themeConfig.slidText : themeConfig.text
}`}
>
{isSlid ? activeLabel : startLabel}
</span>
{/* Drag / Click Slider Knob */}
<motion.button
type="button"
onClick={() => {
setIsSlid((s) => !s);
if (!isSlid && onComplete) onComplete();
}}
animate={{ x: isSlid ? 0 : 0 }}
className="relative z-10 w-10 h-10 rounded-full bg-white shadow-md flex items-center justify-center cursor-pointer focus:outline-none"
>
<svg
className={`w-4 h-4 text-neutral-800 transition-transform duration-300 ${
isSlid ? "rotate-180" : ""
}`}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M9 5l7 7-7 7" />
</svg>
</motion.button>
</div>
</div>
);
}Component API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| startLabel | string | "Get Started" | Initial label displayed in resting state |
| activeLabel | string | "Lets Grow!" | Active label revealed when slider completes |
| theme | SlideGrowTheme | "silver" | Color scheme theme preset |
| size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Scale multiplier |
| onComplete | () => void | undefined | Callback fired when slider is pulled to completion |
Personalized Help
Struggling with gesture swipe sliders or interactive web controls? Let's talk about your product.
UI Pirate is a product design & development agency trusted by 50+ SaaS founders and enterprise teams across the US, UK & beyond. Tell us what you need.