Skip to content
islandcn
Esc
↑↓navigate↵open⌘Jpreview
On this page

IslandNumber and IslandProgress

Content primitives that animate a changed number or a moving bar on the island's clock, as a live status activity's content does.

import { IslandNumber, IslandProgress, numberMotion } from "@/lib/island";

Both run on the island’s clock, so captures and stepped clocks see the same frames, and both follow the provider’s reduced-motion setting. Use them inside activity content; outside a provider they use a requestAnimationFrame clock and the system’s setting. When to use them rather than a crossfade is in Numbers and progress.

<IslandNumber>

Text whose changed characters turn over with a blur when value changes.

import { IslandNumber } from "@/lib/island";

export const Percent = ({ percent }: { percent: number }) => (
  <IslandNumber value={`${percent}%`} style={{ fontSize: 34, fontWeight: 700, color: "#0a84ff" }} />
);
import type { CSSProperties } from "react";

interface IslandNumberProps {
  value: number | string;
  className?: string;
  style?: CSSProperties;
}
PropType
valuenumber | string

The value. Numbers render with toString(); pass a string such as "4:07" to format it yourself.

Typenumber | string
className?string

Class on the wrapper.

Typestring
style?CSSProperties

Style on the wrapper: font size, weight, colour.

TypeCSSProperties

The old and new text are aligned from the right, and only the characters that changed move. Use tabular figures (fontVariantNumeric: "tabular-nums") so the width holds still. The wrapper is an inline-flex with an aria-label of the whole text; screen readers read the value once, not per digit. Because it is not plain text, a slot too narrow for it clips it rather than ending it in an ellipsis.

numberMotion holds the timing, measured on the simulator: the old character shrinks to 0.7 and blurs from 0.03 to 0.21 s, then fades out by 0.26 s; the new one starts at 0.2 s, fades in within 0.08 s, grows from 0.72 and is sharp by about 0.48 s. Under reduced motion the text changes with a plain fade.

<IslandProgress>

A capsule bar whose fill springs to each new value.

import { IslandProgress } from "@/lib/island";

export const Charge = ({ level }: { level: number }) => <IslandProgress value={level} color="#30D158" track="#414141" height={8} />;
import type { CSSProperties } from "react";

import type { SpringConfig } from "@/lib/island";

interface IslandProgressProps {
  value: number;
  color?: string;
  track?: string;
  height?: number;
  radius?: number;
  spring?: SpringConfig;
  className?: string;
  style?: CSSProperties;
}
PropType
valuenumber

Fill from 0 to 1.

Typenumber
color?string

Fill colour.

Typestring
Default"#30D158"
track?string

Track colour.

Typestring
Default"#414141"
height?number

Bar height in px.

Typenumber
Default8
radius?number

Corner radius in px.

Typenumber
Defaulthalf the height
spring?{ response, dampingFraction }

How the fill moves to a new value, fitted on the simulator's bar.

Type{ response, dampingFraction }
Default{ response: 0.97, dampingFraction: 0.74 }
className?string

Class on the track.

Typestring
style?CSSProperties

Style on the track.

TypeCSSProperties

The track is a progressbar with aria-valuenow from 0 to 100. If you wrap it in your own labelled progress bar, hide this one with aria-hidden, as the content kit’s LinearProgress does. Under reduced motion the fill eases to the new value over 0.2 s with no overshoot.

Was this page helpful?