Components
Loading preview...
Interactive battery component with themes and animations
@jatin-yadav05
npx shadcn@latest add https://21st.dev/r/jatin-yadav05/battery-indicator"use client"
import { useState } from 'react'
import { Battery } from '@/components/ui/battery-indicator'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { Switch } from '@/components/ui/switch'
import { Label } from '@/components/ui/label'
export default function Component() {
const [level, setLevel] = useState(65)
const [isCharging, setIsCharging] = useState(false)
const [showPercentage, setShowPercentage] = useState(true)
const [showBolt, setShowBolt] = useState(true)
const [theme, setTheme] = useState<'default' | 'minimal' | 'neon' | 'glass'>('default')
const presetLevels = [5, 25, 50, 75, 100]
return (
<div className="min-h-screen flex items-center w-full p-8 transition-colors duration-300">
<div className="max-w-4xl mx-auto space-y-8">
{/* Main Demo */}
<Card className="bg-white dark:bg-neutral-900 border-gray-400 dark:border-neutral-700">
<CardContent className="space-y-6 pt-6">
{/* Large Battery Display */}
<div className="flex justify-center p-8 bg-gray-50 dark:bg-neutral-950 rounded-lg">
<Battery
level={level}
size={200}
isCharging={isCharging}
showPercentage={showPercentage}
showBolt={showBolt}
theme={theme}
colorScheme="auto"
className="text-gray-600 dark:text-gray-300"
/>
</div>
{/* Controls */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Level Control */}
<div className="space-y-4">
<div>
<Label htmlFor="level-slider" className="text-sm font-medium text-gray-700 dark:text-gray-300">
Battery Level: {level}%
</Label>
<input
id="level-slider"
type="range"
min="0"
max="100"
value={level}
onChange={(e) => setLevel(Number(e.target.value))}
className="w-full h-2 mt-2 bg-neutral-200 dark:bg-neutral-600 rounded-lg appearance-none cursor-pointer"
/>
</div>
{/* Preset Buttons */}
<div className="flex gap-2 flex-wrap">
{presetLevels.map((preset) => (
<Button
key={preset}
variant={level === preset ? "default" : "outline"}
size="sm"
onClick={() => setLevel(preset)}
className={`dark:border-neutral-600 dark:hover:bg-neutral-800 ${
level === preset ? 'dark:text-black dark:hover:text-neutral-300' : 'dark:text-gray-300'
}`}
>
{preset}%
</Button>
))}
</div>
</div>
{/* Options */}
<div className="space-y-4">
<div className="flex items-center space-x-2">
<Switch
id="percentage"
checked={showPercentage}
onCheckedChange={setShowPercentage}
/>
<Label htmlFor="percentage" className="text-gray-700 dark:text-gray-300">Show Percentage</Label>
</div>
{/* Theme Selection */}
<div>
<Label className="text-sm font-medium mb-2 block text-gray-700 dark:text-gray-300">Theme</Label>
<div className="grid grid-cols-2 gap-2">
{(['default', 'minimal', 'neon', 'glass'] as const).map((t) => (
<Button
key={t}
variant={theme === t ? "default" : "outline"}
size="sm"
onClick={() => setTheme(t)}
className={`capitalize dark:border-neutral-600 dark:hover:bg-neutral-800 ${
theme === t ? 'dark:text-neutral-900 dark:hover:text-neutral-300' : 'dark:text-gray-300'
}`}
>
{t}
</Button>
))}
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
)
}