IslandProvider
Owns the activity stack and the clock for every Island and useIsland below it, and takes the metrics, motion and reduced-motion settings.
import { IslandProvider } from "@/lib/island";
<IslandProvider>
Wrap your app once, as high as the components that start activities. Everything below it shares one island.
import { Island, IslandProvider } from "@/lib/island";
import { App } from "./app";
export const Root = () => (
<IslandProvider>
<Island placement="viewport" />
<App />
</IslandProvider>
);
Props
import type { ReactNode } from "react";
import type { IslandClock, IslandMetricsOverrides, IslandMotionOverrides, IslandSequence } from "@/lib/island";
interface IslandProviderProps {
children: ReactNode;
clock?: IslandClock; // read once; default requestAnimationFrame
devtools?: boolean | { sequences?: Record<string, IslandSequence> }; // default false
metrics?: IslandMetricsOverrides; // deep-partial overrides of islandMetrics
motion?: IslandMotionOverrides; // deep-partial overrides of islandMotion
reducedMotion?: "user" | "always" | "never"; // default "user"
}
childrenReactNode
Your app.
ReactNodeclock?IslandClock
Where island time comes from. Read once, on mount. Pass a stepped clock for captures and tests.
IslandClocka requestAnimationFrame clockdevtools?boolean | { sequences }
Installs window.__islandcn (pause, step, seek, play) for frame-exact captures. Leave it off in production.
boolean | { sequences }falsemetrics?IslandMetricsOverrides
Deep-partial overrides of islandMetrics, the geometry table.
IslandMetricsOverridesmotion?IslandMotionOverrides
Deep-partial overrides of islandMotion, the spring and timing table.
IslandMotionOverridesreducedMotion?"user" | "always" | "never"
"user" follows prefers-reduced-motion; the others force it on or off.
"user" | "always" | "never""user"Overriding springs and sizes
Both tables merge one group at a time, so you pass only what you change:
import { Island, IslandProvider } from "@/lib/island";
import { App } from "./app";
export const Root = () => (
<IslandProvider
motion={{ shape: { expand: { response: 0.42, dampingFraction: 0.78 } }, alertHold: 4 }}
metrics={{ top: 10 }}
>
<Island placement="viewport" />
<App />
</IslandProvider>
);
motion can change while the island runs; the next transition uses the new springs. The Playground writes this prop for you. The tables and every key are listed in Motion and springs.
Notes
- It renders on the client. In the Next.js App Router, render it from a
"use client"file, see Installation. - One provider per island. Two providers draw two independent islands.