async
lifecycle
browser
utilities
API not supported, make sure to check for compatibility with different browsers when using this API
import { useBattery } from '@siberiacancode/reactuse';
import {
BatteryChargingIcon,
BatteryFullIcon,
BatteryLowIcon,
BatteryMediumIcon,
BatteryWarningIcon,
Loader2Icon
} from 'lucide-react';
import { cn } from '@/utils/lib';
const getBatteryIcon = (level: number) => {
if (level > 80) return BatteryFullIcon;
if (level > 40) return BatteryMediumIcon;
if (level > 15) return BatteryLowIcon;
return BatteryWarningIcon;
};
const formatTime = (seconds: number) => {
if (!Number.isFinite(seconds) || seconds <= 0) return '--';
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
if (h > 0) return `${h}h ${m}m`;
return `${m}m`;
};
const Demo = () => {
const battery = useBattery();
if (!battery.supported)
return (
<p>
API not supported, make sure to check for compatibility with different browsers when using
this{' '}
<a
href='https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getBattery'
rel='noreferrer'
target='_blank'
>
API
</a>
</p>
);
if (battery.value.loading) {
return (
<section className='flex justify-center'>
<div className='relative flex h-[520px] w-76 items-center justify-center rounded-4xl border pt-12'>
<div className='bg-border absolute top-3 left-1/2 h-5 w-18 -translate-x-1/2 rounded-full' />
<Loader2Icon className='size-5 animate-spin' />
</div>
</section>
);
}
const level = Math.round((battery.value.level ?? 0) * 100);
const Icon = battery.value.charging ? BatteryChargingIcon : getBatteryIcon(level);
const lowBattery = level <= 15 && !battery.value.charging;
return (
<section className='flex justify-center'>
<div className='relative flex h-[430px] w-70 flex-col gap-7 rounded-4xl border px-6 pt-10 pb-8'>
<div className='bg-border absolute top-3 left-1/2 h-5 w-18 -translate-x-1/2 rounded-full' />
<div className='flex h-full flex-col gap-6 pt-6'>
<div className='flex flex-col items-center gap-2'>
<Icon className={cn('ml-2 size-30', lowBattery ? 'text-red-500' : 'text-foreground')} />
<div className='flex flex-col items-center gap-1'>
<div className='text-5xl font-semibold tracking-tight'>{level}%</div>
<span className='text-muted-foreground text-xs tracking-wider uppercase'>
{battery.value.charging ? 'Charging' : 'Battery'}
</span>
</div>
</div>
<div className='mt-auto flex flex-col gap-2 border-t pt-4'>
<div className='flex items-center justify-between text-xs'>
<span className='text-muted-foreground'>Status</span>
<span className='font-medium'>
{battery.value.charging ? 'Charging' : 'Discharging'}
</span>
</div>
<div className='flex items-center justify-between text-xs'>
<span className='text-muted-foreground'>Charge time</span>
<span className='font-medium'>
{formatTime(battery.value.chargingTime ?? Infinity)}
</span>
</div>
<div className='flex items-center justify-between text-xs'>
<span className='text-muted-foreground'>Time left</span>
<span className='font-medium'>
{formatTime(battery.value.dischargingTime ?? Infinity)}
</span>
</div>
</div>
</div>
</div>
</section>
);
};
export default Demo;
This hook uses navigator.getBattery browser api to provide enhanced functionality. Make sure to check for compatibility with different browsers when using this api
Installation
pnpm add @siberiacancode/reactuseUsage
const { supported, loading, charging, chargingTime, dischargingTime, level } = useBattery();Type Declarations
export interface BatteryManager extends EventTarget {
charging: boolean;
chargingTime: number;
dischargingTime: number;
level: number;
}
interface Navigator {
readonly getBattery: () => Promise<BatteryManager>;
}
export interface UseBatteryValue {
/** Is charging battery? */
charging: boolean;
/** Time until the battery is fully charged */
chargingTime: number;
/** Time until the battery is completely discharged */
dischargingTime: number;
/** Battery charge level from 0 to 1 */
level: number;
/** Is battery information loading? */
loading: boolean;
}
export interface UseBatteryReturn {
/** Whether the battery api is supported*/
supported: boolean;
/** The use battery value type */
value: UseBatteryValue;
}API
Returns
UseBatteryStateReturnContributors
ddebabinbbabinhhywaxNNikitaGGorilla Dev
Last updated on