39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
"use client";
|
|
|
|
import { Check } from "lucide-react";
|
|
|
|
export type ActionState = "normal" | "loading" | "success" | "error";
|
|
|
|
export function ActionButton({
|
|
children,
|
|
icon,
|
|
state = "normal",
|
|
loadingText,
|
|
successText = "Gespeichert",
|
|
disabled,
|
|
disabledReason,
|
|
variant = "secondary",
|
|
className = "",
|
|
...props
|
|
}: React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
icon?: React.ReactNode;
|
|
state?: ActionState;
|
|
loadingText?: string;
|
|
successText?: string;
|
|
disabledReason?: string;
|
|
variant?: "primary" | "secondary" | "danger" | "success";
|
|
}) {
|
|
const isDisabled = disabled || state === "loading";
|
|
const variantClass = state === "success" ? "btn-success" : state === "error" ? "btn-danger" : `btn-${variant}`;
|
|
return (
|
|
<button
|
|
{...props}
|
|
disabled={isDisabled}
|
|
title={isDisabled ? disabledReason : props.title}
|
|
className={`btn ${variantClass} ${className}`}
|
|
>
|
|
{state === "loading" ? <span className="spinner" /> : state === "success" ? <Check className="h-4 w-4" /> : icon}
|
|
<span>{state === "loading" ? loadingText ?? "Laedt..." : state === "success" ? successText : children}</span>
|
|
</button>
|
|
);
|
|
}
|