diff options
Diffstat (limited to 'src/components/async-button.tsx')
| -rw-r--r-- | src/components/async-button.tsx | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/components/async-button.tsx b/src/components/async-button.tsx new file mode 100644 index 0000000..7d2bf93 --- /dev/null +++ b/src/components/async-button.tsx @@ -0,0 +1,42 @@ +'use client' +import { Button, ButtonProps } from '@/components/ui/button' +import { Loader2 } from 'lucide-react' +import { ReactNode, useState } from 'react' + +type Props = ButtonProps & { + action?: () => Promise<void> + loadingContent?: ReactNode +} + +export function AsyncButton({ + action, + children, + loadingContent, + ...props +}: Props) { + const [loading, setLoading] = useState(false) + return ( + <Button + onClick={async () => { + try { + setLoading(true) + await action?.() + } catch (err) { + console.error(err) + } finally { + setLoading(false) + } + }} + {...props} + > + {loading ? ( + <> + <Loader2 className="w-4 h-4 mr-2 animate-spin" />{' '} + {loadingContent ?? children} + </> + ) : ( + children + )} + </Button> + ) +} |
