ComponentsUpdated Sep 9, 2026
Loadstone
Highlight’s grid-of-cells loading mark. A config describes the grid and per-cell timing; presets cover the product states, and LoadstoneSequence crossfades between configs.
Import
Source: packages/ui/src/components/loadstone
tsx
import { Loadstone, LoadstoneSequence, thinkingLoadstoneConfig, LoadstoneConfig } from '@highlight/ui'Thinking preset
size scales the whole grid; paused freezes the animation; label is the accessible name.
tsx
import { Loadstone, thinkingLoadstoneConfig } from '@highlight/ui'
export default function LoadstoneBasic() {
return (
<div className="flex items-center gap-8">
<Loadstone config={thinkingLoadstoneConfig} size={24} label="Thinking" />
<Loadstone config={thinkingLoadstoneConfig} size={32} label="Thinking" />
<Loadstone config={thinkingLoadstoneConfig} size={48} label="Thinking" />
<Loadstone config={thinkingLoadstoneConfig} size={48} label="Paused" paused />
</div>
)
}Custom config
rows, columns, and a cells array with order for stagger. lightColor and darkColor per cell.
tsx
import { Loadstone, type LoadstoneConfig } from '@highlight/ui'
const ring: LoadstoneConfig = {
rows: 3,
columns: 3,
animation: 'glow',
duration: 1200,
stagger: 120,
gap: 4,
radius: 99,
ledMode: true,
cells: [
[0, 0, 0],
[0, 1, 1],
[0, 2, 2],
[1, 2, 3],
[2, 2, 4],
[2, 1, 5],
[2, 0, 6],
[1, 0, 7],
].map(([row, column, order]) => ({
row,
column,
order,
opacity: 1,
scale: 1,
lightColor: '#e8e21c',
darkColor: '#fff66e',
})),
}
export default function LoadstoneCustom() {
return <Loadstone config={ring} size={48} label="Recording" />
}Props
Props added on top of the underlying element or Base UI part.
| Prop | Type | Default | Description |
|---|---|---|---|
config | LoadstoneConfig | — | Grid, animation, duration, stagger, gap, radius, ledMode, cells. |
size | number | 32 | Rendered size in px. |
colorMode | 'light' | 'dark' | — | Force a theme; defaults to following the page. |
paused | boolean | false | Freeze. |
label | string | 'Working' | Accessible name. |