Battery
Read the device's battery level, charging state and time estimates through the Battery Status API - one typed snapshot call, no interop code.
@inject Bit.Butil.Battery batteryMDN reference
IsSupported returns false and GetStatus reports a
charged-on-AC-power stub so your code doesn't have to special-case missing data.
Returns true when the runtime exposes navigator.getBattery. Because the check runs over JS interop, defer it to OnAfterRenderAsync when prerendering.
@inject Bit.Butil.Battery battery
var supported = await battery.IsSupported();Takes a one-shot snapshot of the battery: charge level in the [0, 1] range, whether the device is charging, and the estimated seconds until fully charged or discharged (null when the browser can't estimate).
var status = await battery.GetStatus();
var level = status.Level; // 0.87
var charging = status.Charging; // true / false
var untilFull = status.ChargingTime; // seconds, or null
var untilEmpty = status.DischargingTime; // seconds, or nullThe same snapshot rendered as UI state instead of raw values - a typical pattern for a status-bar battery indicator.
var status = await battery.GetStatus();
batteryLabel = status.Charging
? $"{status.Level:P0} - charging"
: $"{status.Level:P0} - on battery";Polling GetStatus is the wrong shape for a battery indicator. SubscribeChange hands you a fresh snapshot every time anything moves - plugged in, unplugged, or the level ticked. The spec has no single change event, so this attaches to all four (chargingchange, levelchange, chargingtimechange, dischargingtimechange) and always reports the whole state, meaning your handler never has to work out which field changed. Returns null where the API doesn't exist, since the AC-power stub can never change.
private ButilSubscription? subscription;
subscription = await battery.SubscribeChange(status =>
{
_snapshot = status;
InvokeAsync(StateHasChanged);
});
if (subscription is null)
{
// No Battery Status API here - nothing to watch.
}
// later
await subscription.DisposeAsync();API reference
ValueTask<bool> IsSupported()ValueTask<BatteryStatus> GetStatus()ValueTask<ButilSubscription?> SubscribeChange(Action<BatteryStatus> handler)bool Charging { get; set; }double? ChargingTime { get; set; }double? DischargingTime { get; set; }double Level { get; set; }