Toolbar Expandable
Expandable toolbar with step-based navigation
Installation
Dependencies
Examples
Controlled
Active: none · Collapsed
"use client"
import { useState } from "react"
import { FileText, Image, Music, Video } from "lucide-react"
import { Button } from "@/components/vritti/button"
import ToolbarExpandable from "@/components/vritti/toolbar-expandable"
const mediaSteps = [
{
id: "documents",
title: "Documents",
description: "Browse and manage your document files.",
icon: FileText,
content: (
<div className="space-y-3">
<div className="flex items-center justify-between rounded-md border border-border p-3">
<div className="flex items-center gap-2">
<FileText className="h-4 w-4 text-blue-500" />
<span className="text-sm">report-2024.pdf</span>
</div>
<span className="text-xs text-muted-foreground">2.4 MB</span>
</div>
<div className="flex items-center justify-between rounded-md border border-border p-3">
<div className="flex items-center gap-2">
<FileText className="h-4 w-4 text-blue-500" />
<span className="text-sm">notes.docx</span>
</div>
<span className="text-xs text-muted-foreground">128 KB</span>
</div>
</div>
),
},
{
id: "images",
title: "Images",
description: "View and organize your image library.",
icon: Image,
content: (
<div className="grid grid-cols-3 gap-2">
{["bg-blue-100", "bg-green-100", "bg-purple-100", "bg-orange-100", "bg-pink-100", "bg-yellow-100"].map(
(color, i) => (
<div
key={i}
className={`${color} dark:opacity-50 aspect-square rounded-md flex items-center justify-center`}
>
<Image className="h-4 w-4 text-muted-foreground" />
</div>
)
)}
</div>
),
},
{
id: "videos",
title: "Videos",
description: "Access your video collection.",
icon: Video,
content: (
<div className="space-y-3">
<div className="flex items-center justify-between rounded-md border border-border p-3">
<div className="flex items-center gap-2">
<Video className="h-4 w-4 text-red-500" />
<span className="text-sm">intro-video.mp4</span>
</div>
<span className="text-xs text-muted-foreground">24 MB</span>
</div>
</div>
),
},
{
id: "audio",
title: "Audio",
description: "Manage your audio files and playlists.",
icon: Music,
content: (
<div className="space-y-3">
<div className="flex items-center justify-between rounded-md border border-border p-3">
<div className="flex items-center gap-2">
<Music className="h-4 w-4 text-green-500" />
<span className="text-sm">podcast-ep1.mp3</span>
</div>
<span className="text-xs text-muted-foreground">8.2 MB</span>
</div>
</div>
),
},
]
export function ToolbarExpandableControlled() {
const [expanded, setExpanded] = useState(false)
const [activeStep, setActiveStep] = useState<string | null>(null)
return (
<div className="max-w-2xl mx-auto space-y-4">
<div className="flex items-center gap-2 justify-center">
<Button
variant="outline"
size="sm"
onClick={() => {
setExpanded(!expanded)
if (expanded) {
setActiveStep(null)
} else {
setActiveStep("documents")
}
}}
>
{expanded ? "Collapse" : "Expand"}
</Button>
<Button
variant="outline"
size="sm"
onClick={() => {
setActiveStep(null)
setExpanded(false)
}}
>
Reset
</Button>
</div>
<ToolbarExpandable
steps={mediaSteps}
expanded={expanded}
onExpandedChange={setExpanded}
activeStep={activeStep}
onActiveStepChange={setActiveStep}
/>
<p className="text-center text-xs text-muted-foreground">
Active: {activeStep ?? "none"} ·{" "}
{expanded ? "Expanded" : "Collapsed"}
</p>
</div>
)
}
Deployment
"use client"
import {
CheckCircle,
Code,
Database,
Palette,
Rocket,
Settings,
Upload,
} from "lucide-react"
import { Button } from "@/components/vritti/button"
import ToolbarExpandable from "@/components/vritti/toolbar-expandable"
const deploymentSteps = [
{
id: "setup",
title: "Project Setup",
description:
"Initialize your project with the required dependencies and configuration.",
icon: Settings,
content: (
<div className="space-y-4">
<div className="space-y-2">
<label htmlFor="project-name" className="text-sm font-medium block">
Project Name
</label>
<input
id="project-name"
placeholder="my-awesome-app"
className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium block">Framework</label>
<select className="w-full h-10 px-3 border border-border rounded-md bg-background text-sm">
<option>Next.js</option>
<option>React</option>
<option>Vue.js</option>
</select>
</div>
<Button className="w-full">
<Code className="w-4 h-4 mr-2" />
Initialize Project
</Button>
</div>
),
},
{
id: "configure",
title: "Configuration",
description:
"Set up environment variables and project settings for optimal performance.",
icon: Database,
content: (
<div className="space-y-4">
<div className="space-y-2">
<label htmlFor="api-key" className="text-sm font-medium block">
API Key
</label>
<input
id="api-key"
type="password"
placeholder="Enter your API key"
className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
/>
</div>
<div className="space-y-2">
<label htmlFor="database-url" className="text-sm font-medium block">
Database URL
</label>
<input
id="database-url"
placeholder="postgresql://..."
className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
/>
</div>
<Button variant="outline" className="w-full bg-transparent">
<Settings className="w-4 h-4 mr-2" />
Save Configuration
</Button>
</div>
),
},
{
id: "customize",
title: "Customize Design",
description:
"Personalize your application's appearance and branding elements.",
icon: Palette,
content: (
<div className="space-y-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="space-y-2">
<label className="text-sm font-medium block">Primary Color</label>
<div className="flex gap-2">
<div className="w-8 h-8 bg-blue-500 rounded-md border-2 border-blue-600"></div>
<div className="w-8 h-8 bg-green-500 rounded-md"></div>
<div className="w-8 h-8 bg-purple-500 rounded-md"></div>
</div>
</div>
<div className="space-y-2">
<label className="text-sm font-medium block">Theme</label>
<select className="w-full h-10 px-3 border border-border rounded-md bg-background text-sm">
<option>Light</option>
<option>Dark</option>
<option>Auto</option>
</select>
</div>
</div>
<Button variant="outline" className="w-full bg-transparent">
<Palette className="w-4 h-4 mr-2" />
Apply Theme
</Button>
</div>
),
},
{
id: "upload",
title: "Upload Assets",
description:
"Upload your project files, images, and other assets to the platform.",
icon: Upload,
content: (
<div className="space-y-4">
<div className="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center">
<Upload className="w-8 h-8 mx-auto mb-2 text-gray-400" />
<p className="text-sm text-gray-600 mb-2">
Drag and drop files here
</p>
<Button variant="outline" size="sm">
Choose Files
</Button>
</div>
<Button className="w-full">
<Upload className="w-4 h-4 mr-2" />
Upload Assets
</Button>
</div>
),
},
{
id: "deploy",
title: "Deploy",
description:
"Deploy your application to production with automatic scaling and monitoring.",
icon: Rocket,
content: (
<div className="space-y-4">
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
<div className="flex items-center gap-2 mb-2">
<CheckCircle className="w-5 h-5 text-green-600" />
<span className="font-medium text-green-800">Ready to Deploy</span>
</div>
<p className="text-sm text-green-700">
All checks passed. Your application is ready for production
deployment.
</p>
</div>
<div className="space-y-2">
<label className="text-sm font-medium block">
Deployment Region
</label>
<select className="w-full h-10 px-3 border border-border rounded-md bg-background text-sm">
<option>US East (Virginia)</option>
<option>US West (California)</option>
<option>Europe (Frankfurt)</option>
<option>Asia Pacific (Singapore)</option>
</select>
</div>
<Button className="w-full bg-green-600 hover:bg-green-700">
<Rocket className="w-4 h-4 mr-2" />
Deploy to Production
</Button>
</div>
),
},
]
export function ToolbarExpandableDeployment() {
return (
<div className="max-w-2xl mx-auto">
<ToolbarExpandable steps={deploymentSteps} />
</div>
)
}