Create two screens, register them with a provider, and render the active screen in a viewport.
Build a stack
import {
NavigationStackProvider,
NavigationStackScreen,
NavigationStackViewport,
useNavigationStack,
} from 'flow-stack';
import type { NavigationParams, NavigationScreenRenderProps } from 'flow-stack';
interface DetailsParams extends NavigationParams {
id: string;
}
function HomeScreen() {
const nav = useNavigationStack();
return <button onClick={() => nav.push('details', { id: '1' })}>Open</button>;
}
function DetailsScreen({ params }: NavigationScreenRenderProps<DetailsParams>) {
const nav = useNavigationStack();
return (
<div>
<p>ID: {params.id}</p>
<button onClick={() => nav.pop()}>Back</button>
</div>
);
}
export function App() {
return (
<div style=>
<NavigationStackProvider id="main" initialRoute=>
<NavigationStackScreen name="home" component={HomeScreen} />
<NavigationStackScreen name="details" component={DetailsScreen} />
<NavigationStackViewport />
</NavigationStackProvider>
</div>
);
}
The wrapper gives the viewport a stable size. Flow Stack fills its container; it does not size or position the surrounding UI.
What happens
- The provider creates an independent stack named
mainand activateshome. - Each
NavigationStackScreenregisters a route and its component. - The viewport renders the active route at the size of its parent.
useNavigationStackexposes typed navigation methods to descendant components.
Next steps
See it running in the Basic example, then read Core concepts for the state and rendering model.