Toggling and swiping sidebars like in a native app, built with React. Inspired by the native iOS swipe gestures.
npm install @luciodale/swipe-barSwipeBar provides an intuitive, native-app-like experience for mobile and desktop sidebars. Swipe from the edge to open, drag to close, and enjoy smooth animations with full customization control.
- 📦 Lightweight - zero dependencies
- 📱 Native Mobile Gestures - Swipe from screen edges just like native apps
- 🖱️ Desktop Support - Works seamlessly with mouse interactions
- 🎨 Fully Customizable - Complete control over styling, animations, and behavior
- 🎯 Smart Positioning - Automatically adapts between absolute and relative positioning
- 🎭 Custom Toggles - Use built-in toggle icons or provide your own components
- ⚡ Performant - Relies on transform and opacity properties
- 🎚️ Configurable Thresholds - Fine-tune edge activation and drag sensitivity
- 🌓 Overlay Support - Optional backdrop overlay with customizable colors
- 📏 Responsive - Media query support for different screen sizes
- 🔧 Programmatic Control - Open and close sidebars from anywhere in your app
``bash`
npm install @luciodale/swipe-baror
yarn add @luciodale/swipe-baror
bun add @luciodale/swipe-bar
`bash`
npm install @luciodale/swipe-bar
Wrap your app with SwipeBarProvider:
`tsx
import { SwipeBarProvider } from "@luciodale/swipe-bar";
function App() {
return (
{/ Your app content /}
);
}
`
`tsx
import { SwipeBarLeft } from "@luciodale/swipe-bar";
`
`tsx
import { SwipeBarRight } from "@luciodale/swipe-bar";
Settings panel
`
Use the context hook to control sidebars from anywhere:
`tsx
import { useSwipeBarContext } from "@luciodale/swipe-bar";
function MyComponent() {
const { openSidebar, closeSidebar, isLeftOpen, isRightOpen } = useSwipeBarContext();
return (
);
}
`
Configure global defaults for all sidebars:
`tsx`
transitionMs={300}
edgeActivationWidthPx={40}
dragActivationDeltaPx={20}
showOverlay={true}
isAbsolute={false}
overlayBackgroundColor="rgba(0, 0, 0, 0.5)"
toggleIconColor="white"
toggleIconSizePx={40}
toggleIconEdgeDistancePx={40}
showToggle={true}
mediaQueryWidth={640}
swipeBarZIndex={30}
toggleZIndex={15}
overlayZIndex={20}
>
{children}
Both SwipeBarLeft and SwipeBarRight accept the same props, which override provider defaults:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| className | string | - | CSS classes for the sidebar container |ToggleComponent
| | ReactNode | - | Custom toggle button component |sidebarWidthPx
| | number | 320 | Width of the sidebar in pixels |transitionMs
| | number | 200 | Animation duration in milliseconds |edgeActivationWidthPx
| | number | 40 | Touch zone width from screen edge to activate swipe |dragActivationDeltaPx
| | number | 20 | Minimum drag distance to activate sidebar |showOverlay
| | boolean | true | Show backdrop overlay when sidebar is open |isAbsolute
| | boolean | false | Use absolute positioning (overlay mode) |overlayBackgroundColor
| | string | "rgba(0, 0, 0, 0.5)" | Overlay background color |toggleIconColor
| | string | "white" | Color of the built-in toggle icon |toggleIconSizePx
| | number | 40 | Size of the toggle icon |toggleIconEdgeDistancePx
| | number | 40 | Distance of toggle from screen edge |showToggle
| | boolean | true | Show the toggle button |mediaQueryWidth
| | number | 640 | Max screen width for swipe gestures (in pixels) |swipeBarZIndex
| | number | 30 | Z-index for left and right swipe bars |toggleZIndex
| | number | 15 | Z-index for left and right toggle buttons |overlayZIndex
| | number | 20 | Z-index for the overlay backdrop |
`tsx`
const {
isLeftOpen, // boolean - is left sidebar open
isRightOpen, // boolean - is right sidebar open
openSidebar, // (side: "left" | "right") => void
closeSidebar, // (side: "left" | "right") => void
globalOptions, // current global options
setGlobalOptions, // update global options
} = useSwipeBarContext();
By default, sidebars push content to the side. Set isAbsolute={true} to make sidebars overlay on top of content instead:
`tsx`
{/ This sidebar will overlay content /}
Note: On mobile (below mediaQueryWidth), sidebars automatically switch to absolute positioning for a better mobile experience.
Control when swipe gestures are enabled based on screen size:
`tsx`
{/ Swipe gestures only work on screens ≤640px wide /}
This is useful if you want swipe interactions only on mobile/tablet devices.
The built-in toggle button automatically hides when:
- The overlay is visible to handle closing instead
Replace the default toggle with your own component:
`tsx`
}
>
{/ content /}
`tsx
import { SwipeBarProvider, SwipeBarLeft } from "@luciodale/swipe-bar";
function App() {
return (
Navigation
{/ Your main content /}
);
}
`
`tsx`
overlayBackgroundColor="rgba(0, 0, 0, 0.3)"
>
{/ Glass effect sidebar content /}
`tsx`
isAbsolute={true}
>
{/ Full screen mobile menu /}
`tsx``
function Header() {
const { openSidebar } = useSwipeBarContext();
return (
My App
);
}
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile Safari (iOS 12+)
- Chrome Android (latest)
Touch events and smooth animations are supported across all modern browsers.
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
MIT