Skip to content

Repository files navigation

ActionSheet-React

SizenpmTypeScriptLicense

🌟 A lightweight, performant, and accessible action sheet component for React with modern features and best practices.

✨ Features

  • 🚀 High Performance: 60fps animations with optimized rendering
  • Accessible: WCAG compliant with keyboard navigation and screen reader support
  • 📱 Touch Friendly: Responsive gestures for mobile devices
  • 🎨 Customizable: Full control over styling and behavior
  • 🔧 TypeScript: Full TypeScript support with comprehensive type definitions
  • 📦 Lightweight: Minimal bundle size with zero dependencies
  • Modern React: Built with React 18+ features and hooks
  • 🎯 Position Flexible: Support for bottom and top positioned sheets

📺 Demo

CodeSandbox

actionsheet-demo.mp4

📦 Installation

# Using npm
npm install actionsheet-react
# Using yarn
yarn add actionsheet-react
# Using pnpm
pnpm add actionsheet-react

🚀 Quick Start

importReact,{useRef}from"react";importActionSheetfrom"actionsheet-react";functionMyComponent(){constactionSheetRef=useRef<ActionSheetRef>(null);return(<div><buttononClick={()=>actionSheetRef.current?.open()}>
Open Action Sheet
</button><ActionSheetref={actionSheetRef}onClose={()=>console.log("Closed!")}aria-label="Example action sheet"><divstyle={{padding: "20px"}}><h3>Hello World!</h3><p>This is a basic action sheet.</p><buttononClick={()=>actionSheetRef.current?.close()}>Close</button></div></ActionSheet></div>);}

📖 API Reference

Props

PropTypeDefaultDescription
onClose() => voidundefinedCallback fired when the action sheet is closed
childrenReactNodeundefinedContent to render inside the action sheet
bgStyleCSSProperties{}Custom styles for the background overlay
sheetStyleCSSProperties{}Custom styles for the sheet container
mouseEnablebooleantrueEnable mouse/pointer interactions for dragging
touchEnablebooleantrueEnable touch interactions for dragging
thresholdnumber50Threshold in pixels for triggering close when dragging
opacitynumber1Opacity of the background overlay when visible
zIndexnumber998z-index value for the action sheet
closeOnBgTapbooleantrueAllow closing when clicking on the background
bgTransitionstring"opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1)"CSS transition for background
classNamestring"action-sheet"CSS class name for the background overlay
sheetTransitionstring"transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)"CSS transition for sheet
reversebooleanfalsePosition the sheet at the top instead of bottom
aria-labelstringundefinedARIA label for accessibility
aria-labelledbystringundefinedARIA labelledby for accessibility

Ref Methods

MethodDescription
open()Open the action sheet
close()Close the action sheet
isOpen()Check if the action sheet is currently open

🎯 Usage Examples

Basic Usage

importReact,{useRef}from"react";importActionSheet,{ActionSheetRef}from"actionsheet-react";functionBasicExample(){constactionSheetRef=useRef<ActionSheetRef>(null);return(<><buttononClick={()=>actionSheetRef.current?.open()}>
Open Basic Sheet
</button><ActionSheetref={actionSheetRef}><divstyle={{padding: "20px"}}><h3>Basic Action Sheet</h3><p>Drag down, click background, or press Escape to close.</p></div></ActionSheet></>);}

Top Position Sheet

functionTopSheetExample(){constactionSheetRef=useRef<ActionSheetRef>(null);return(<><buttononClick={()=>actionSheetRef.current?.open()}>
Open Top Sheet
</button><ActionSheetref={actionSheetRef}reverse={true}aria-label="Top positioned action sheet"><divstyle={{padding: "20px"}}><h3>Top Action Sheet</h3><p>This sheet slides down from the top!</p></div></ActionSheet></>);}

Custom Styled Sheet

functionCustomStyledExample(){constactionSheetRef=useRef<ActionSheetRef>(null);return(<><buttononClick={()=>actionSheetRef.current?.open()}>
Open Custom Sheet
</button><ActionSheetref={actionSheetRef}bgStyle={{backgroundColor: "rgba(139, 69, 19, 0.8)"}}sheetStyle={{backgroundColor: "#1a1a1a",color: "#ffffff",borderRadius: "20px 20px 0 0",}}aria-label="Custom styled action sheet"><divstyle={{padding: "20px"}}><h3>Custom Styled Sheet</h3><p>This sheet has custom background and styling.</p></div></ActionSheet></>);}

Action List Example

functionActionListExample(){constactionSheetRef=useRef<ActionSheetRef>(null);const[selectedAction,setSelectedAction]=useState("");consthandleAction=(action: string)=>{setSelectedAction(action);actionSheetRef.current?.close();};return(<><buttononClick={()=>actionSheetRef.current?.open()}>
Open Action List
</button><ActionSheetref={actionSheetRef}threshold={80}><div><divstyle={{padding: "20px",borderBottom: "1px solid #eee"}}><h3>Choose an Action</h3></div><div>{["Share","Edit","Copy Link","Download","Delete"].map(action=>(<buttonkey={action}onClick={()=>handleAction(action)}style={{width: "100%",padding: "15px 20px",border: "none",background: "white",borderBottom: "1px solid #f0f0f0",textAlign: "left",cursor: "pointer",}}>{action}</button>))}</div></div></ActionSheet>{selectedAction&&<p>Selected: {selectedAction}</p>}</>);}

♿ Accessibility

ActionSheet-React is built with accessibility in mind:

  • ARIA Support: Proper ARIA attributes for screen readers
  • Keyboard Navigation: Press Escape to close the sheet
  • Focus Management: Automatic focus handling when opening/closing
  • Screen Reader Support: Compatible with popular screen readers

Accessibility Best Practices

<ActionSheetref={actionSheetRef}aria-label="User settings"// oraria-labelledby="settings-title"><div><h3id="settings-title">User Settings</h3>{/* Content */}</div></ActionSheet>

🎨 Styling

CSS Custom Properties

You can use CSS custom properties for consistent theming:

:root {
--actionsheet-bg-color:rgba(0,0,0,0.5);
--actionsheet-sheet-bg:#ffffff;
--actionsheet-border-radius:16px;
--actionsheet-transition:0.3scubic-bezier(0.4,0,0.2,1);
}
.action-sheet {
background-color:var(--actionsheet-bg-color);
}

Custom Animations

<ActionSheetbgTransition="opacity 0.5s ease-in-out"sheetTransition="transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)">{/* Content */}</ActionSheet>

🚀 Performance Tips

  1. Memoize Content: Use React.memo for complex sheet content
  2. Optimize Images: Use appropriate image formats and sizes
  3. Avoid Heavy Computations: Keep sheet content lightweight
  4. Use CSS Transforms: Prefer CSS transforms over changing layout properties
constOptimizedSheetContent=memo(({ data })=>(<div>{/* Heavy content here */}</div>));<ActionSheetref={ref}><OptimizedSheetContentdata={data}/></ActionSheet>;

🔄 Migration from v1.x

Breaking Changes

  1. React Version: Now requires React 16.8+
  2. TypeScript: Better type definitions
  3. Props: Some prop names have changed for clarity
  4. Accessibility: New ARIA props added

Migration Guide

// v1.x<ActionSheetref={ref}onClose={handleClose}bgTransition="opacity 0.5s ease-in-out, z-index 0.5s ease-in-out"/>// v2.x<ActionSheetref={ref}onClose={handleClose}bgTransition="opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1)"aria-label="Action sheet"/>

🤝 Contributing

Contributions are welcome! Please read our Contributing Guide for details.

📄 License

ISC © mohit23x

🙏 Credits

Built with ❤️ by mohit23x


### 👨‍💻 Usage
##### Sample code using Javascript
```javascript
import React, { useRef, Fragment } from "react";
import ActionSheet from "actionsheet-react";
const MyComponent = () => {
const ref = useRef();
const handleOpen = () => {
ref.current.open();
};
const handleClose = () => {
ref.current.close();
};
return (
<Fragment>
<button onClick={handleOpen}>Open</button>
<button onClick={handleClose}>Close</button>
<ActionSheet ref={ref}>
<div style={style.content}>🙂 Hi React Devs!</div>
</ActionSheet>
</Fragment>
);
};
const style = {
content: {
height: 300,
display: "flex",
justifyContent: "center",
alignItems: "center",
},
};
Sample code using Typescript
importActionSheet,{ActionSheetRef}from'actionsheet-react';constMyComponent=()=>{constref=useRef<ActionSheetRef>();// ...rest same as above code

🌮 Props

all props are optional
property nametypemore info
onClosecallback functioncalled when the actionsheet is closed
childrenReact Childrenall the fancy HTML elements that you want to show in the menu
bgStylecss styles objectthese styles are applied to the background black overlay
sheetStylecss styles objectthese styles are applied to the sheet component
mouseEnablebooleanif true, the sheet can be dragged down using mouse
touchEnablebooleanif true, the sheet can be swiped down on touch devices
thresholdnumberthe minimum distance dragged, so that sheet will slide down. Threshold is measured in px , default value is 50
zIndexnumberthe default value is 999
closeOnBgTapbooleanif true, the sheet is closed when the background overlay is tapped
reversebooleanopen the sheet in reverse direction
sheetTransitionstringcss transition shorthand, default value transform 0.3s ease-in-out
bgTransitionstringcss transition shorthand, default value opacity 0.5s ease-in-out, z-index 0.5s ease-in-out

👾 Misc

  1. The logic to stop the backgroud from scrolling is not implemented in this package just to keep it simple. To avoid the background from scrolling you can toggle the overflow property of the body tag, or you can also use some other way of your choice
document.body.style.overflow="hidden";document.body.style.overflow="auto";
  1. Mobile browsers generally have pull-to-refresh and when action sheet is open and when user drags the sheet down the pull-to-refresh is triggered. To control this behavior either you can disable swipe in action sheet touchEnable={false} or you can disable pull-to-refresh.
body {
overscroll-behavior: contain;
}

⛳ Issues/Feature Request/Pull Request

The github repo is always there for you.

About

React action sheet component

Topics

Resources

Stars

13 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages