AppUpdate
An update pill with download progress, an update sheet with release notes and speed, a forced-update gate for unsupported builds, and an admin release manager with the minimum supported build.
Code
import { UpdatePill, UpdateSheet } from "@fadymondy/nasaq/web";import { useState } from "react";export function Updates({ updater }: { updater: MyUpdater }) { const [open, setOpen] = useState(false); return ( <> <UpdatePill status={updater.status} progress={updater.percent} onClick={() => setOpen(true)} /> <UpdateSheet open={open} onOpenChange={setOpen} release={updater.release} status={updater.status} progress={updater.percent} speed={updater.bytesPerSecond} onDownload={updater.download} onRestart={updater.restart} /> </> );}Alerts & Notifications · beta
Live examples and controls: AppUpdate in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/app-update.jsonFour pieces for an app that updates itself (Electron, Tauri or a PWA with a service worker). UpdatePill sits in the
header and shows the state. UpdateSheet gives the release notes and the download. ForcedUpdateGate blocks builds
that are too old. ReleaseManager is the admin side: releases, rollout, and the minimum supported build. They only
draw: your updater downloads and restarts, and you feed status, progress and speed in.
When to use
- A desktop or installed app with its own update channel.
- A mobile or web app where old clients must be stopped after a breaking API change.
When not to use
- A one-off announcement of what is new: use a
DialogorAlert. - Asking people to install the app: use
InstallPrompt.
Import
import { UpdatePill, UpdateSheet } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"Quick start
import { UpdatePill, UpdateSheet } from "@fadymondy/nasaq/web";
import { useState } from "react";
export function Updates({ updater }: { updater: MyUpdater }) {
const [open, setOpen] = useState(false);
return (
<>
<UpdatePill status={updater.status} progress={updater.percent} onClick={() => setOpen(true)} />
<UpdateSheet
open={open}
onOpenChange={setOpen}
release={updater.release}
status={updater.status}
progress={updater.percent}
speed={updater.bytesPerSecond}
onDownload={updater.download}
onRestart={updater.restart}
/>
</>
);
}Anatomy
UpdatePill data-slot="update-pill" (data-status), a button with a download fill
UpdateSheet data-slot="update-sheet", Sheet with notes, size, progress, Later and Restart
ForcedUpdateGate data-slot="forced-update-gate", renders children unless the build is too old
ReleaseManager data-slot="release-manager": minimum build field, warning, releases tableAPI
UpdatePill: button props except children and type, plus status ("available" | "downloading" | "ready" | "error"), progress (0 to 100), version, labels.
UpdateSheet: open, onOpenChange, release (AppRelease: version, build, date, notes, size in bytes, channel), status, progress, speed (bytes per second), onDownload, onRestart, onLater, side ("end"), labels.
ForcedUpdateGate: currentBuild, minSupportedBuild, release, status, progress, speed, onDownload, onRestart, logo, children, labels.
ReleaseManager: releases (ManagedRelease[]: an AppRelease plus id, status, rollout), minSupportedBuild, usage ({ build, users }[], optional), onSetMinSupportedBuild(build), onPublish(id), onRollback(id), labels. The async callbacks return void or { error }.
Helpers (pure, in app-update-format.ts): isUpdateRequired, clampUpdatePercent, formatUpdateSize, formatUpdateSpeed, secondsLeft, formatUpdateTime, countBelow, minBuildProblem.
Examples
Block old builds
<ForcedUpdateGate currentBuild={APP_BUILD} minSupportedBuild={config.minBuild} release={latest} status={status} onDownload={download} onRestart={restart}>
<App />
</ForcedUpdateGate>Accessibility
- The pill announces changes through a polite live region; the download is a real
progressbarwith a name. - The sheet is a dialog with focus trapped and Escape to close. The forced gate is a
<main>with the only action being update. - Note types are words (New, Improved, Fixed), not colour alone.
RTL & i18n
- English and Arabic follow the locale. Speeds, sizes, versions and builds stay left-to-right with Latin digits. The pill fill grows from the inline start.
Styling & tokens
- Uses
bg-card,border-border, the success and danger soft tokens, andProgress. Target[data-slot="update-pill"],[data-slot="release-manager"].
Do / Don't
- Do offer "Later" for ordinary updates and keep the forced gate for builds the server really cannot serve.
- Do warn before raising the minimum build: pass
usageso the admin sees how many people it blocks. - Don't restart without telling: the restart is a button, not a timer.
Related
AlertList
Alert triage lists, AlertList and SecurityAlerts, with status tabs and counts, search, severity and source filters, sorting, acknowledge, resolve and reopen, and an expandable timeline per alert.
Attention
A short, domain-independent list of things the user should act on now (unread conversations, failed deployments, approvals, setup steps), ordered by urgency.