Files
MiragenFlow/packages/ui/src/button.tsx
T

51 lines
2.1 KiB
TypeScript

import { Children, forwardRef, isValidElement, type ReactElement, type ReactNode } from "react";
import { Button as TDesignButton } from "tdesign-react/es/button";
import type { ButtonProps as TDesignButtonProps } from "tdesign-react/es/button";
import "./button.css";
export type MiragenFlowButtonType = "default" | "primary" | "outline" | "dashed" | "link" | "text" | "danger" | "danger-outline";
export interface MiragenFlowButtonProps extends Omit<TDesignButtonProps, "children" | "content" | "icon" | "theme" | "type" | "variant"> {
children?: ReactNode;
htmlType?: "button" | "submit" | "reset";
icon?: ReactElement;
type?: MiragenFlowButtonType;
}
const buttonTypeMap: Record<MiragenFlowButtonType, { theme: "default" | "primary" | "danger"; variant: "base" | "outline" | "dashed" | "text" }> = {
default: { theme: "default", variant: "base" },
primary: { theme: "primary", variant: "base" },
outline: { theme: "default", variant: "outline" },
dashed: { theme: "default", variant: "dashed" },
link: { theme: "primary", variant: "text" },
text: { theme: "default", variant: "text" },
danger: { theme: "danger", variant: "base" },
"danger-outline": { theme: "danger", variant: "outline" },
};
export const MiragenFlowButton = forwardRef<HTMLElement, MiragenFlowButtonProps>(function MiragenFlowButton(
{ children, className, htmlType = "button", icon, loading, onClick, tag, type = "default", ...rest },
ref,
) {
const mapped = buttonTypeMap[type];
const hasRichChildren = Children.count(children) > 1 || Children.toArray(children).some(isValidElement);
const resolvedClassName = ["mf-button", hasRichChildren && "mf-button--rich", className].filter(Boolean).join(" ");
return (
<TDesignButton
{...rest}
ref={ref}
className={resolvedClassName}
icon={icon}
loading={loading}
onClick={onClick}
tag={tag ?? (rest.href ? undefined : "button")}
theme={mapped.theme}
type={htmlType}
variant={mapped.variant}
>
{children}
</TDesignButton>
);
});