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

| Live Demo | CodeSandbox |
# Using npm
npm install actionsheet-react
# Using yarn
yarn add actionsheet-react
# Using pnpm
pnpm add actionsheet-react
import React, { useRef } from "react";
import ActionSheet from "actionsheet-react";
function MyComponent() {
const actionSheetRef = useRef<ActionSheetRef>(null);
return (
<div>
<button onClick={() => actionSheetRef.current?.open()}>
Open Action Sheet
</button>
<ActionSheet
ref={actionSheetRef}
onClose={() => console.log("Closed!")}
aria-label="Example action sheet"
>
<div style=>
<h3>Hello World!</h3>
<p>This is a basic action sheet.</p>
<button onClick={() => actionSheetRef.current?.close()}>Close</button>
</div>
</ActionSheet>
</div>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
onClose |
() => void |
undefined |
Callback fired when the action sheet is closed |
children |
ReactNode |
undefined |
Content to render inside the action sheet |
bgStyle |
CSSProperties |
{} |
Custom styles for the background overlay |
sheetStyle |
CSSProperties |
{} |
Custom styles for the sheet container |
mouseEnable |
boolean |
true |
Enable mouse/pointer interactions for dragging |
touchEnable |
boolean |
true |
Enable touch interactions for dragging |
threshold |
number |
50 |
Threshold in pixels for triggering close when dragging |
opacity |
number |
1 |
Opacity of the background overlay when visible |
zIndex |
number |
998 |
z-index value for the action sheet |
closeOnBgTap |
boolean |
true |
Allow closing when clicking on the background |
bgTransition |
string |
"opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1)" |
CSS transition for background |
className |
string |
"action-sheet" |
CSS class name for the background overlay |
sheetTransition |
string |
"transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)" |
CSS transition for sheet |
reverse |
boolean |
false |
Position the sheet at the top instead of bottom |
aria-label |
string |
undefined |
ARIA label for accessibility |
aria-labelledby |
string |
undefined |
ARIA labelledby for accessibility |
| Method | Description |
|---|---|
open() |
Open the action sheet |
close() |
Close the action sheet |
isOpen() |
Check if the action sheet is currently open |
import React, { useRef } from "react";
import ActionSheet, { ActionSheetRef } from "actionsheet-react";
function BasicExample() {
const actionSheetRef = useRef<ActionSheetRef>(null);
return (
<>
<button onClick={() => actionSheetRef.current?.open()}>
Open Basic Sheet
</button>
<ActionSheet ref={actionSheetRef}>
<div style=>
<h3>Basic Action Sheet</h3>
<p>Drag down, click background, or press Escape to close.</p>
</div>
</ActionSheet>
</>
);
}
function TopSheetExample() {
const actionSheetRef = useRef<ActionSheetRef>(null);
return (
<>
<button onClick={() => actionSheetRef.current?.open()}>
Open Top Sheet
</button>
<ActionSheet
ref={actionSheetRef}
reverse={true}
aria-label="Top positioned action sheet"
>
<div style=>
<h3>Top Action Sheet</h3>
<p>This sheet slides down from the top!</p>
</div>
</ActionSheet>
</>
);
}
function CustomStyledExample() {
const actionSheetRef = useRef<ActionSheetRef>(null);
return (
<>
<button onClick={() => actionSheetRef.current?.open()}>
Open Custom Sheet
</button>
<ActionSheet
ref={actionSheetRef}
bgStyle=
sheetStyle=
aria-label="Custom styled action sheet"
>
<div style=>
<h3>Custom Styled Sheet</h3>
<p>This sheet has custom background and styling.</p>
</div>
</ActionSheet>
</>
);
}
function ActionListExample() {
const actionSheetRef = useRef<ActionSheetRef>(null);
const [selectedAction, setSelectedAction] = useState("");
const handleAction = (action: string) => {
setSelectedAction(action);
actionSheetRef.current?.close();
};
return (
<>
<button onClick={() => actionSheetRef.current?.open()}>
Open Action List
</button>
<ActionSheet ref={actionSheetRef} threshold={80}>
<div>
<div style=>
<h3>Choose an Action</h3>
</div>
<div>
{["Share", "Edit", "Copy Link", "Download", "Delete"].map(
action => (
<button
key={action}
onClick={() => handleAction(action)}
style=
>
{action}
</button>
)
)}
</div>
</div>
</ActionSheet>
{selectedAction && <p>Selected: {selectedAction}</p>}
</>
);
}
ActionSheet-React is built with accessibility in mind:
Escape to close the sheet<ActionSheet
ref={actionSheetRef}
aria-label="User settings"
// or
aria-labelledby="settings-title"
>
<div>
<h3 id="settings-title">User Settings</h3>
{/* Content */}
</div>
</ActionSheet>
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.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.action-sheet {
background-color: var(--actionsheet-bg-color);
}
<ActionSheet
bgTransition="opacity 0.5s ease-in-out"
sheetTransition="transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)"
>
{/* Content */}
</ActionSheet>
React.memo for complex sheet contentconst OptimizedSheetContent = memo(({ data }) => (
<div>{/* Heavy content here */}</div>
));
<ActionSheet ref={ref}>
<OptimizedSheetContent data={data} />
</ActionSheet>;
// v1.x
<ActionSheet
ref={ref}
onClose={handleClose}
bgTransition="opacity 0.5s ease-in-out, z-index 0.5s ease-in-out"
/>
// v2.x
<ActionSheet
ref={ref}
onClose={handleClose}
bgTransition="opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
aria-label="Action sheet"
/>
Contributions are welcome! Please read our Contributing Guide for details.
ISC © mohit23x
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",
},
};
import ActionSheet, {ActionSheetRef} from 'actionsheet-react';
const MyComponent = () => {
const ref = useRef<ActionSheetRef>();
// ...rest same as above code
| property name | type | more info |
|---|---|---|
| onClose | callback function | called when the actionsheet is closed |
| children | React Children | all the fancy HTML elements that you want to show in the menu |
| bgStyle | css styles object | these styles are applied to the background black overlay |
| sheetStyle | css styles object | these styles are applied to the sheet component |
| mouseEnable | boolean | if true, the sheet can be dragged down using mouse |
| touchEnable | boolean | if true, the sheet can be swiped down on touch devices |
| threshold | number | the minimum distance dragged, so that sheet will slide down. Threshold is measured in px , default value is 50 |
| zIndex | number | the default value is 999 |
| closeOnBgTap | boolean | if true, the sheet is closed when the background overlay is tapped |
| reverse | boolean | open the sheet in reverse direction |
| sheetTransition | string | css transition shorthand, default value transform 0.3s ease-in-out |
| bgTransition | string | css transition shorthand, default value opacity 0.5s ease-in-out, z-index 0.5s ease-in-out |
document.body.style.overflow = "hidden";
document.body.style.overflow = "auto";
touchEnable={false} or you can disable pull-to-refresh.body {
overscroll-behavior: contain;
}
The github repo is always there for you.