Skip to content

Instantly share code, notes, and snippets.

@MarceloPrado
Last active April 22, 2024 17:35
Show Gist options
  • Save MarceloPrado/5a123eac1d989659caacae8286b42c74 to your computer and use it in GitHub Desktop.
Save MarceloPrado/5a123eac1d989659caacae8286b42c74 to your computer and use it in GitHub Desktop.
An easy way of seeking user confirmation before proceeding with a destructive action. Demo: https://twitter.com/marceloterreiro/status/1779657639745798411
import type { ReactElement } from "react";
import { cloneElement, memo, useCallback } from "react";
import { AlertV2 } from "@/components/AlertV2/alertV2Helpers";
export interface DestructiveActionGuardProps {
children: ReactElement<{ onPress: () => void }>;
confirmationTitle?: string;
confirmationDescription?: string;
}
/**
* Guard user from destructive actions by showing a confirmation dialog before
* proceeding.
*
* **Note**: children must expose an onPress prop for this component to work.
*/
export const DestructiveActionGuard = memo(
({
children,
confirmationTitle: title = "Are you sure?",
confirmationDescription: description = "This action cannot be undone.",
}: DestructiveActionGuardProps) => {
const handlePress = useCallback(async () => {
const result = await AlertV2.show({
title,
description,
mode: "sheet",
actions: [
{
title: "Cancel",
value: "dismiss",
variant: "secondary",
},
{
title: "Delete",
value: "confirm",
variant: "danger",
},
],
actionsDirection: "horizontal",
});
if (result.value === "confirm") {
// Forward the event back to the original onPress handler
children.props.onPress();
}
}, [children.props, description, title]);
// Clone the child element and override its onPress prop
const childWithInterceptedOnPress = cloneElement(children, {
onPress: handlePress,
});
return childWithInterceptedOnPress;
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment