/
SubmitButton.tsx
53 lines (47 loc) · 1.46 KB
/
SubmitButton.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
'use client';
import { useFormStatus } from 'react-dom';
import { twMerge } from 'tailwind-merge';
import { ClassNamePropsOptional } from '@/features/shared/ui/ClassNameProps';
import { ChildrenProps } from '@/features/shared/ui/ChildrenProps';
export interface SubmitButtonProps extends ChildrenProps, ClassNamePropsOptional {
readonly labelClassName?: string;
readonly spinnerClassName?: string;
readonly submitting?: React.ReactNode;
readonly submittingContainerClassName?: string;
}
export const SubmitButton = ({
children,
className,
labelClassName,
spinnerClassName,
submitting,
submittingContainerClassName,
}: SubmitButtonProps) => {
const { pending } = useFormStatus();
const spinner = (
<div className="absolute w-4 h-4 left-1/2 right-1/2 -translate-x-1/2 -translate-y-1/2">
<div className={twMerge('spinner w-4 h-4', spinnerClassName)} />
</div>
);
const pendingComponent = submitting ? submitting : spinner;
return (
<button
type="submit"
className={twMerge('group relative', className)}
aria-disabled={pending}
disabled={pending}
>
<div
className={twMerge(
'flex items-center justify-center group-disabled:opacity-0',
labelClassName,
)}
>
{(!submitting || !pending) && children}
</div>
<div className={twMerge('flex group-enabled:hidden', submittingContainerClassName)}>
{pendingComponent}
</div>
</button>
);
};