The Problem
You open a sidebar and need to pass data along with it: which screen to show, which filter is active, which item was tapped. Without metadata, you end up managing a parallel state object that drifts out of sync with the sidebar's open/close state. swipe-bar solves this by letting you attach typed metadata directly to sidebar operations.
Defining Your Type Map
Pass a generic to useSwipeBarContext and
every sidebar gets its own typed metadata. The generic maps each
direction to a shape:
typed-meta.tsx
type MyMeta = {
left: {
primary: { screen: "settings" | "profile" };
secondary: { panel: string };
};
right: {
primary: { tab: number };
};
bottom: {
primary: { filter: string };
secondary: { step: number };
};
};
const {
openSidebar,
closeSidebar,
openSidebarFully,
openSidebarToMidAnchor,
setMeta,
leftSidebars, // primary.meta: { screen: "settings" | "profile" } | null
rightSidebars, // primary.meta: { tab: number } | null
bottomSidebars, // primary.meta: { filter: string } | null
} = useSwipeBarContext<MyMeta>();Setting Meta on Open/Close
meta-on-action.ts
// Pass meta when opening (all directions support id for multi-instance)
openSidebar("left", { id: "primary", meta: { screen: "settings" } });
openSidebar("left", { id: "secondary", meta: { panel: "nav" } });
closeSidebar("right", { meta: { tab: 2 } });
openSidebarFully("bottom", { id: "primary", meta: { filter: "active" } });
openSidebarToMidAnchor("bottom", { id: "secondary", meta: { step: 1 } });Standalone setMeta
Update metadata without triggering an open or close. The sidebar stays wherever it is:
set-meta.ts
// Update meta independently (all directions accept id for multi-instance)
setMeta("left", { id: "primary", meta: { screen: "profile" } });
setMeta("right", { id: "primary", meta: { tab: 3 } });
setMeta("bottom", { id: "primary", meta: { filter: "completed" } });
// Clear meta to null
setMeta("left", { id: "primary", meta: null });
setMeta("bottom", { id: "primary", meta: null });Resetting Meta
reset-meta.ts
// Clear meta on close
closeSidebar("left", { resetMeta: true });
// resetMeta takes precedence when both are provided
openSidebar("right", { meta: { tab: 3 }, resetMeta: true }); // meta stays null
// Auto-reset on every close (gesture, overlay, toggle, programmatic)
<SwipeBarLeft resetMetaOnClose>
<nav>...</nav>
</SwipeBarLeft>
// Explicit meta or resetMeta in closeSidebar opts still takes precedence
closeSidebar("left", { meta: { screen: "profile" } }); // keeps this metaBehaviours
- Generic on the hook — strict per-sidebar typing; without the generic, meta is absent from the API
- Set on open/close — works on all four functions: openSidebar, closeSidebar, openSidebarFully, openSidebarToMidAnchor
- Preserved by default — calling without meta/resetMeta leaves existing meta untouched
- resetMeta: true — clears meta to null; takes precedence over meta if both are provided
- Drag gestures do not touch meta — swipe and toggle interactions never modify meta. Only explicit API calls change it
- Per-instance on all directions — meta is per-instance via leftSidebars[id].meta, rightSidebars[id].meta, and bottomSidebars[id].meta; cleaned up on unregister