diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 15:08:52 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 15:08:52 -0500 |
| commit | 570aa713b1b2becf7c06c89610c75d2cb119b532 (patch) | |
| tree | b6e3ae339bd55a7a00d77ee64532ece9fc43c13f /src/components/async-button.tsx | |
| parent | fee1963284eafa6db7887103a156799b7610e13d (diff) | |
Delete expense
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> + ) +} |
