61 lines
1.3 KiB
TypeScript
Executable File
61 lines
1.3 KiB
TypeScript
Executable File
import React from "react";
|
|
import { NavLink, NavLinkProps, To } from "react-router-dom";
|
|
import classNames from "classnames";
|
|
|
|
type Props = {
|
|
to?: To;
|
|
children: React.ReactNode;
|
|
disabled?: boolean;
|
|
className?: string;
|
|
} & Omit<NavLinkProps, "to">;
|
|
|
|
function getURL(to: To): URL {
|
|
if (typeof to !== "string") {
|
|
return getURL(to.pathname ?? "");
|
|
}
|
|
try {
|
|
return new URL(to as string);
|
|
} catch {
|
|
let outurl = `${window.location.origin}${
|
|
to.startsWith("/") ? to : "/" + to
|
|
}`;
|
|
return new URL(outurl);
|
|
}
|
|
}
|
|
|
|
export default function Link({
|
|
to,
|
|
children,
|
|
disabled,
|
|
className,
|
|
style,
|
|
...props
|
|
}: Props) {
|
|
const link =
|
|
to && getURL(to).hostname === window.location.hostname ? (
|
|
<NavLink
|
|
to={getURL(to).pathname}
|
|
style={style}
|
|
className={classNames({ "pointer-events-none": disabled }, className)}
|
|
>
|
|
{children}
|
|
</NavLink>
|
|
) : (
|
|
<a
|
|
href={disabled ? undefined : (to && getURL(to).origin) || undefined}
|
|
style={
|
|
typeof style === "function"
|
|
? style({
|
|
isActive: true,
|
|
})
|
|
: style
|
|
}
|
|
aria-disabled={disabled}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</a>
|
|
);
|
|
return <div>{link}</div>;
|
|
}
|