an app to share curated trails
sidetrail.app
atproto
nextjs
react
rsc
1"use client";
2
3import { useTransition, type ReactNode } from "react";
4
5type Props = {
6 action: () => Promise<void>;
7 children: ReactNode;
8 pendingChildren?: ReactNode;
9 className?: string;
10 pendingClassName?: string;
11 disabled?: boolean;
12 type?: "button" | "submit";
13};
14
15export function ActionButton({
16 action,
17 children,
18 pendingChildren,
19 className,
20 pendingClassName,
21 disabled = false,
22 type = "button",
23}: Props) {
24 const [isPending, startTransition] = useTransition();
25
26 const handleClick = (e: React.MouseEvent) => {
27 if (isPending) return;
28 e.stopPropagation();
29 startTransition(async () => {
30 await action();
31 });
32 };
33
34 const classNames = [className, isPending && pendingClassName].filter(Boolean).join(" ");
35
36 return (
37 <button
38 type={type}
39 onClick={handleClick}
40 disabled={disabled || isPending}
41 className={classNames}
42 >
43 {isPending && pendingChildren ? pendingChildren : children}
44 </button>
45 );
46}