Skip to content

Commit a53fd31

Browse files
committed
chore: combine link usage
1 parent 37d0080 commit a53fd31

File tree

18 files changed

+114
-73
lines changed

18 files changed

+114
-73
lines changed

app/components/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CircleX } from "lucide-react";
22

3-
import Link from "~/components/Link";
3+
import Link from "~/components/link";
44
import cn from "~/utils/cn";
55

66
interface FooterProps {
@@ -28,7 +28,7 @@ export default function Footer({ url, debug, healthy }: FooterProps) {
2828
<div className={cn("text-xs leading-none", !healthy && "hidden md:block")}>
2929
<p>
3030
Headplane is free. Please consider{" "}
31-
<Link to="https://github.com/sponsors/tale" name="Aarnav's GitHub Sponsors">
31+
<Link isExternal to="https://github.com/sponsors/tale" name="Aarnav's GitHub Sponsors">
3232
donating
3333
</Link>{" "}
3434
to support development.{" "}

app/components/Link.tsx

Lines changed: 0 additions & 32 deletions
This file was deleted.

app/components/error-banner.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import cn from "~/utils/cn";
66

77
import Card from "./Card";
88
import Code from "./Code";
9-
import Link from "./Link";
9+
import Link from "./link";
1010

1111
export function getErrorMessage(error: Error | unknown): {
1212
title: string;
@@ -137,7 +137,7 @@ export function getErrorMessage(error: Error | unknown): {
137137
<Card.Text>
138138
An unexpected error occurred which is most likely a bug. Please consider reporting
139139
filing an issue on the{" "}
140-
<Link name="Headplane GitHub" to="https://github.com/tale/headplane/issues">
140+
<Link isExternal name="Headplane GitHub" to="https://github.com/tale/headplane/issues">
141141
Headplane GitHub
142142
</Link>{" "}
143143
repository with the details below.

app/components/link.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { ExternalLink } from "lucide-react";
2+
import type { JSX } from "react";
3+
import { Link as RouterLink } from "react-router";
4+
5+
import cn from "~/utils/cn";
6+
7+
const linkStyles = cn(
8+
"inline-flex items-center gap-x-0.5",
9+
"text-blue-500 hover:text-blue-700",
10+
"dark:text-blue-400 dark:hover:text-blue-300",
11+
"focus:ring-offset-1 rounded-md",
12+
"focus:outline-hidden focus:ring-2 focus:ring-indigo-500/40",
13+
"dark:focus:ring-indigo-400/40 dark:focus:ring-offset-mist-900",
14+
);
15+
16+
export type LinkProps =
17+
| {
18+
isExternal: true;
19+
to: string;
20+
name: string;
21+
children: string;
22+
className?: string;
23+
}
24+
| {
25+
isExternal?: false;
26+
to: string;
27+
children?: string;
28+
className?: string;
29+
};
30+
31+
export default function Link(props: LinkProps): JSX.Element {
32+
if (props.isExternal) {
33+
return (
34+
<a
35+
href={props.to}
36+
aria-label={props.name}
37+
target="_blank"
38+
rel="noreferrer"
39+
className={cn(linkStyles, props.className)}
40+
>
41+
{props.children}
42+
<ExternalLink className="w-3.5" />
43+
</a>
44+
);
45+
}
46+
47+
return (
48+
<RouterLink to={props.to} className={cn(linkStyles, props.className)}>
49+
{props.children}
50+
</RouterLink>
51+
);
52+
}

app/layouts/no-access.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Form } from "react-router";
33

44
import Button from "~/components/Button";
55
import Card from "~/components/Card";
6-
import Link from "~/components/Link";
6+
import Link from "~/components/link";
77
import Options from "~/components/Options";
88
import toast from "~/utils/toast";
99

@@ -58,6 +58,7 @@ export default function NoAccess({ linkedUserName, osValue }: NoAccessProps) {
5858
<p className="mt-1 text-center text-xs text-mist-600 dark:text-mist-300">
5959
Click this button to copy the command.{" "}
6060
<Link
61+
isExternal
6162
name="Linux installation script"
6263
to="https://github.com/tailscale/tailscale/blob/main/scripts/installer.sh"
6364
>
@@ -112,6 +113,7 @@ export default function NoAccess({ linkedUserName, osValue }: NoAccessProps) {
112113
<br />
113114
You can also download Tailscale on the{" "}
114115
<Link
116+
isExternal
115117
name="macOS App Store"
116118
to="https://apps.apple.com/ca/app/tailscale/id1475387142"
117119
>

app/routes/auth/login/config-error.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AlertCircle, CloudOff } from "lucide-react";
22

33
import Card from "~/components/Card";
44
import Code from "~/components/Code";
5-
import Link from "~/components/Link";
5+
import Link from "~/components/link";
66
import { OidcConnectorError } from "~/server/web/oidc-connector";
77

88
export function OidcDiscoveryFailedNotice() {
@@ -35,6 +35,7 @@ export function OidcConfigErrorNotice({ errors }: { errors: OidcConnectorError[]
3535
))}
3636
</ul>{" "}
3737
<Link
38+
isExternal
3839
name="Headplane OIDC Issues"
3940
to="https://headplane.net/configuration/sso#troubleshooting"
4041
>

app/routes/auth/login/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { AlertCircle } from "lucide-react";
22
import { useEffect, useState } from "react";
3-
import { Form, Link as RemixLink, redirect, useSearchParams } from "react-router";
3+
import { Form, redirect, useSearchParams } from "react-router";
44

55
import Button from "~/components/Button";
66
import Card from "~/components/Card";
77
import Code from "~/components/Code";
88
import Input from "~/components/Input";
9-
import Link from "~/components/Link";
9+
import Link from "~/components/link";
1010
import { useLiveData } from "~/utils/live-data";
1111

1212
import type { Route } from "./+types/page";
@@ -103,6 +103,7 @@ export default function Page({ loaderData, actionData }: Route.ComponentProps) {
103103
Headplane is configured to use secure cookies, but this site is being served over an
104104
insecure connection and login will not work correctly.{" "}
105105
<Link
106+
isExternal
106107
name="Headplane Common Issues"
107108
to="https://headplane.net/configuration/common-issues#issue-logging-in-does-not-do-anything"
108109
>
@@ -138,15 +139,15 @@ export default function Page({ loaderData, actionData }: Route.ComponentProps) {
138139
</Button>
139140
</Form>
140141
{isOidcConnectorEnabled ? (
141-
<RemixLink to="/oidc/start">
142+
<Link to="/oidc/start">
142143
<Button
143144
className="mt-2 w-full"
144145
isDisabled={oidcErrorCodes.length > 0}
145146
variant="light"
146147
>
147148
Single Sign-On
148149
</Button>
149-
</RemixLink>
150+
</Link>
150151
) : undefined}
151152
</Card>
152153
</div>

app/routes/dns/components/manage-records.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Form } from "react-router";
22

33
import Button from "~/components/Button";
44
import Code from "~/components/Code";
5-
import Link from "~/components/Link";
5+
import Link from "~/components/link";
66
import TableList from "~/components/TableList";
77
import cn from "~/utils/cn";
88

@@ -20,7 +20,11 @@ export default function ManageRecords({ records, isDisabled }: Props) {
2020
<p>
2121
Headscale supports adding custom DNS records to your Tailnet. As of now, only <Code>A</Code>{" "}
2222
and <Code>AAAA</Code> records are supported.{" "}
23-
<Link name="Headscale DNS Records documentation" to="https://headscale.net/stable/ref/dns">
23+
<Link
24+
isExternal
25+
name="Headscale DNS Records documentation"
26+
to="https://headscale.net/stable/ref/dns"
27+
>
2428
Learn More
2529
</Link>
2630
</p>

app/routes/machines/components/machine-row.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ChevronDown, Copy } from "lucide-react";
22
import { useMemo } from "react";
3-
import { Link } from "react-router";
43

54
import Chip from "~/components/Chip";
5+
import Link from "~/components/link";
66
import Menu from "~/components/Menu";
77
import StatusCircle from "~/components/StatusCircle";
88
import { ExitNodeTag } from "~/components/tags/ExitNode";

app/routes/machines/dialogs/tags.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import { Plus, TagsIcon, X } from "lucide-react";
22
import { useEffect, useMemo, useRef, useState } from "react";
33
import { useFetcher } from "react-router";
44

5-
import type { Machine } from "~/types";
6-
75
import Button from "~/components/Button";
86
import Dialog from "~/components/Dialog";
9-
import Link from "~/components/Link";
7+
import Link from "~/components/link";
108
import Select from "~/components/Select";
119
import TableList from "~/components/TableList";
10+
import type { Machine } from "~/types";
1211
import cn from "~/utils/cn";
1312

1413
interface TagsProps {
@@ -73,7 +72,11 @@ export default function Tags({ machine, isOpen, setIsOpen, existingTags }: TagsP
7372
<Dialog.Title>Edit ACL tags for {machine.givenName}</Dialog.Title>
7473
<Dialog.Text>
7574
ACL tags can be used to reference machines in your ACL policies. See the{" "}
76-
<Link name="Tailscale documentation" to="https://tailscale.com/kb/1068/acl-tags">
75+
<Link
76+
isExternal
77+
name="Tailscale documentation"
78+
to="https://tailscale.com/kb/1068/acl-tags"
79+
>
7780
Tailscale documentation
7881
</Link>{" "}
7982
for more information.

0 commit comments

Comments
 (0)