Thermal

Thermal Provider

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.

Installation

pnpm dlx shadcn add @01orbital/thermal-provider
npx shadcn add @01orbital/thermal-provider
yarn shadcn add @01orbital/thermal-provider
bunx --bun shadcn add @01orbital/thermal-provider

Part 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-shell
npx shadcn add @01orbital/thermal-atoms @01orbital/thermal-shell
yarn shadcn add @01orbital/thermal-atoms @01orbital/thermal-shell
bunx --bun shadcn add @01orbital/thermal-atoms @01orbital/thermal-shell

Usage

"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>
  )
}

Anatomy

Thermal Provider is built from 2 parts. In the example they nest like this:

ThermalProvider
  • ThermalProvider: 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".

API reference

ThermalProvider

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

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".

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.

Dependencies

No other registry pieces.