Context provider for the Thermal family: tracks heat and an idle, warming, combustion, cooling or depleted status from window activity, with a timed cool-down. Parts fall back to a warm resting state without it.
The source comes with full access.
One payment of $149 ($49 for now) opens the source right here and lets the CLI install every paid component, with lifetime updates.
pnpm dlx shadcn add @01orbital/thermal-providernpx shadcn add @01orbital/thermal-provideryarn shadcn add @01orbital/thermal-providerbunx --bun shadcn add @01orbital/thermal-providerPart of the 01orbital library. With a license, put ORBITAL_TOKEN in .env.local and the same command installs it (licensed install, pricing).
It lands at components/thermal/thermal-provider.tsx, as source you own and edit.
The example also uses thermal-atoms and thermal-shell. Install them too:
pnpm dlx shadcn add @01orbital/thermal-atoms @01orbital/thermal-shellnpx shadcn add @01orbital/thermal-atoms @01orbital/thermal-shellyarn shadcn add @01orbital/thermal-atoms @01orbital/thermal-shellbunx --bun shadcn add @01orbital/thermal-atoms @01orbital/thermal-shell"use client"
import {
EmberLayer,
ThermalText,
} from "@/components/thermal/thermal-atoms"
import {
ThermalProvider,
useThermalStatus,
} from "@/components/thermal/thermal-provider"
import { ThermalShell } from "@/components/thermal/thermal-shell"
// The provider is state; the shell, the embers and the readout make it
// visible. Move the cursor and the scene ignites; go idle and it cools.
function Status() {
const status = useThermalStatus()
return <ThermalText>{status}</ThermalText>
}
export default function ThermalProviderDemo() {
return (
<ThermalProvider cooldownDelay={3000} depletionTime={5000}>
<ThermalShell className="grid min-h-full w-full flex-1 place-items-center">
<EmberLayer particleCount={18} />
<Status />
</ThermalShell>
</ThermalProvider>
)
}Thermal Provider is built from 2 parts. In the example they nest like this:
ThermalProviderThermalProvider: Holds the shared heat state for the thermal parts inside it, such as EmberLayer and ThermalText. By default, activity anywhere in the window (moving the mouse, typing, scrolling or touching) warms it through "WARMING" to "COMBUSTION"; after a pause it moves to "COOLING", then "DEPLETED".ThermalStatusContext: The current thermal status on its own: "IDLE", "WARMING", "COMBUSTION", "COOLING" or "DEPLETED", or null outside a provider. ThermalProvider supplies it, and ThermalShell can override it with its status prop. Read it with useThermalStatus, which falls back to "WARMING".Holds the shared heat state for the thermal parts inside it, such as EmberLayer and ThermalText. By default, activity anywhere in the window (moving the mouse, typing, scrolling or touching) warms it through "WARMING" to "COMBUSTION"; after a pause it moves to "COOLING", then "DEPLETED".
Read and change the state with useThermal.
Prop
Type
The current thermal status on its own: "IDLE", "WARMING", "COMBUSTION", "COOLING" or "DEPLETED", or null outside a provider. ThermalProvider supplies it, and ThermalShell can override it with its status prop. Read it with useThermalStatus, which falls back to "WARMING".
It is kept apart from heat, which can change every 200ms during activity, so parts that only read the status, such as EmberLayer and ThermalText, do not re-render on each heat change.
It accepts the HTML attributes of the element it renders.
No other registry pieces.
Thermal Atoms
Thermal parts driven by ThermalProvider status: EmberLayer, rising sparks that brighten toward combustion, and ThermalText, a word that warms and glows. Uses motion; embers hold still under reduced motion.
Thermal Shell
Dark Thermal container painting a void-to-ember radial ground, a status-driven ember glow with heat haze at combustion, and SoftGrain. Uses motion; haze is skipped under reduced motion.