71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import React, { DetailedHTMLProps, HTMLAttributes } from "react";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
/**
|
|
* # General Card
|
|
* @className twui-card
|
|
* @className twui-card-link
|
|
*
|
|
* @info use the classname `nested-link` to prevent the card from being clickable when
|
|
* a link (or the target element with this calss) inside the card is clicked.
|
|
*/
|
|
export default function Card({
|
|
href,
|
|
variant,
|
|
linkProps,
|
|
...props
|
|
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
|
variant?: "normal";
|
|
href?: string;
|
|
linkProps?: DetailedHTMLProps<
|
|
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
HTMLAnchorElement
|
|
>;
|
|
}) {
|
|
const component = (
|
|
<div
|
|
{...props}
|
|
className={twMerge(
|
|
"flex flex-row items-center p-4 rounded bg-white dark:bg-white/10",
|
|
"border border-slate-200 dark:border-white/10 border-solid",
|
|
href
|
|
? "hover:bg-slate-100 dark:hover:bg-white/30 hover:border-slate-400 dark:hover:border-white/20"
|
|
: "",
|
|
"twui-card",
|
|
props.className
|
|
)}
|
|
>
|
|
{props.children}
|
|
</div>
|
|
);
|
|
|
|
if (href) {
|
|
return (
|
|
<a
|
|
href={href}
|
|
{...linkProps}
|
|
onClick={(e) => {
|
|
const targetEl = e.target as HTMLElement;
|
|
if (targetEl.closest(".nested-link")) {
|
|
e.preventDefault();
|
|
} else if (e.ctrlKey) {
|
|
window.open(href, "_blank");
|
|
} else {
|
|
window.location.href = href;
|
|
}
|
|
linkProps?.onClick?.(e);
|
|
}}
|
|
className={twMerge(
|
|
"cursor-pointer",
|
|
"twui-card-link",
|
|
linkProps?.className
|
|
)}
|
|
>
|
|
{component}
|
|
</a>
|
|
);
|
|
}
|
|
|
|
return component;
|
|
}
|