Signals
The reactive core on its own: a counter, derived values, a 20 Hz progress bar and a list rebuilt from a signal.
Run it
swift run halo start --config examples/signals # from a clone
halo start --config "$(brew --prefix)/share/halo/examples/signals" # Homebrew
Source
main.tsx
import { Box, PerScreen, Surface, Text } from "halo";
import { clock } from "halo/services";
import { computed, signal } from "halo/signals";
const accent = "#89b4fa";
const muted = "#9399b2";
function Showcase() {
const ticks = signal(0);
const progress = signal(0);
setInterval(() => ticks.update((n) => n + 1), 500);
setInterval(() => progress.update((p) => (p + 2) % 102), 50);
const even = computed(() => ticks() % 2 === 0);
const dots = computed(() => ticks() % 9);
return (
<Box style={{ padding: 18, gap: 14, background: "#1e1e2ef0", radius: 18 }}>
<Box style={{ flexDirection: "row", justify: "space-between", align: "center" }}>
<Text style={{ fontSize: 13, fontWeight: "semibold", color: muted }}>
SIGNALS
</Text>
<Text style={{ fontSize: 13, color: muted }}>{clock.format("HH:mm:ss")}</Text>
</Box>
<Box style={{ flexDirection: "row", align: "center", gap: 12 }}>
<Text
style={{
fontSize: 34,
fontWeight: "bold",
color: () => (even() ? accent : "#f9e2af"),
}}
>
{() => String(ticks())}
</Text>
<Text style={{ fontSize: 14, color: muted }}>
{() => (even() ? "even" : "odd")}
</Text>
</Box>
<Box style={{ height: 8, background: "#313244", radius: 4 }}>
<Box
style={{
height: 8,
width: () => `${Math.min(progress(), 100)}%`,
background: accent,
radius: 4,
}}
/>
</Box>
<Box style={{ flexDirection: "row", gap: 6, height: 12 }}>
{() =>
Array.from({ length: dots() }, () => (
<Box style={{ width: 12, height: 12, radius: 6, background: accent }} />
))
}
</Box>
</Box>
);
}
export default () => (
<PerScreen>
{(screen) => (
<Surface screen={screen} size={{ width: 360, height: 210 }} layer="aboveMenu">
<Showcase />
</Surface>
)}
</PerScreen>
);