150 lines
4.7 KiB
TypeScript
150 lines
4.7 KiB
TypeScript
import { MouseEventHandler, ReactNode, Ref, useEffect, useRef } from "react";
|
|
import LinkOrAhref from "./LinkOrAhref";
|
|
import { Button } from "../button";
|
|
import { useLocation, useMatches } from "react-router";
|
|
import { useRootData } from "~/utils/data/useRootData";
|
|
import AnalyticsHelper from "~/utils/helpers/AnalyticsHelper";
|
|
import clsx from "clsx";
|
|
|
|
interface Props {
|
|
className?: string;
|
|
type?: "button" | "submit" | "reset" | undefined;
|
|
to?: string;
|
|
target?: undefined | "_blank";
|
|
rel?: string;
|
|
disabled?: boolean;
|
|
destructive?: boolean;
|
|
isExternal?: boolean;
|
|
onClick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
|
|
autoFocus?: boolean;
|
|
children: ReactNode;
|
|
prefetch?: "intent" | "render" | "none";
|
|
event?: { action: string; category: string; label: string; value: string };
|
|
sendEvent?: boolean;
|
|
dataUiId?: string;
|
|
}
|
|
|
|
export default function ButtonPrimary({
|
|
className = "",
|
|
type = "button",
|
|
onClick,
|
|
disabled,
|
|
destructive,
|
|
to,
|
|
target,
|
|
rel,
|
|
isExternal = false,
|
|
autoFocus,
|
|
prefetch,
|
|
children,
|
|
event,
|
|
sendEvent = true,
|
|
dataUiId,
|
|
}: Props) {
|
|
// const combinedClassName = clsx(
|
|
// className,
|
|
// "inline-flex items-center space-x-2 px-4 py-2 border border-transparent shadow-2xs text-sm font-medium rounded-md text-white focus:outline-hidden focus:ring-2 focus:ring-accent-300",
|
|
// disabled && "cursor-not-allowed opacity-75",
|
|
// !destructive && "bg-primary",
|
|
// destructive && "bg-red-600",
|
|
// !disabled && !destructive && !className && "hover:bg-accent-900 focus:ring-ring hover:text-accent-100",
|
|
// !disabled && destructive && "hover:bg-red-700 focus:ring-red-500"
|
|
// );
|
|
|
|
let location = useLocation();
|
|
const rootData = useRootData();
|
|
const matches = useMatches();
|
|
const focusRef = useRef<HTMLButtonElement | HTMLAnchorElement | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!autoFocus) {
|
|
return;
|
|
}
|
|
const timeout = window.setTimeout(() => focusRef.current?.focus(), 0);
|
|
return () => window.clearTimeout(timeout);
|
|
}, [autoFocus]);
|
|
|
|
function onClicked(e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) {
|
|
if (onClick) {
|
|
onClick(e);
|
|
}
|
|
if (!event || !sendEvent) {
|
|
return;
|
|
}
|
|
const routeMatch = matches.find((m) => m.pathname == location.pathname);
|
|
AnalyticsHelper.addEvent({
|
|
url: location.pathname,
|
|
route: routeMatch?.id,
|
|
rootData,
|
|
action: event.action,
|
|
category: event.category,
|
|
label: event.label,
|
|
value: event.value,
|
|
});
|
|
}
|
|
|
|
return (
|
|
<span>
|
|
{(() => {
|
|
if (!to || disabled) {
|
|
return (
|
|
<Button
|
|
variant={destructive ? "destructive" : undefined}
|
|
className={clsx("inline-flex items-center space-x-2", className)}
|
|
onClick={onClicked}
|
|
type={type}
|
|
disabled={disabled}
|
|
ref={focusRef as Ref<HTMLButtonElement>}
|
|
data-ui-id={dataUiId}
|
|
>
|
|
{children}
|
|
</Button>
|
|
);
|
|
} else if (to && isExternal) {
|
|
return (
|
|
<Button asChild>
|
|
<a
|
|
href={to}
|
|
target={target}
|
|
rel={rel}
|
|
ref={focusRef as Ref<HTMLAnchorElement>}
|
|
onClick={onClicked}
|
|
data-ui-id={dataUiId}
|
|
className={clsx("inline-flex items-center space-x-2", className)}
|
|
>
|
|
{children}
|
|
</a>
|
|
</Button>
|
|
);
|
|
} else {
|
|
return (
|
|
<Button asChild>
|
|
<LinkOrAhref
|
|
to={disabled ? "" : to}
|
|
target={target}
|
|
rel={rel}
|
|
prefetch={prefetch}
|
|
className={clsx("inline-flex items-center space-x-2", className)}
|
|
// className={clsx(
|
|
// className,
|
|
// "borde1-transparent focus:ring-accent-300 inline-flex items-center space-x-2 rounded-md border px-4 py-2 text-sm font-medium text-white shadow-2xs focus:outline-hidden focus:ring-2",
|
|
// disabled && "cursor-not-allowed opacity-75",
|
|
// !destructive && "bg-primary",
|
|
// destructive && "bg-red-600",
|
|
// !disabled && !destructive && !className && "hover:bg-accent-900 hover:text-accent-100 focus:ring-ring",
|
|
// !disabled && destructive && "hover:bg-red-700 focus:ring-red-500"
|
|
// )}
|
|
autoFocus={autoFocus}
|
|
onClick={onClicked}
|
|
data-ui-id={dataUiId}
|
|
>
|
|
{children}
|
|
</LinkOrAhref>
|
|
</Button>
|
|
);
|
|
}
|
|
})()}
|
|
</span>
|
|
);
|
|
}
|