Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 45ae2cd

Browse files
committedApr 16, 2021
Anchor tag respects modifiers
Holding ctrl / alt when clicking link defers to default browser behavior. Also adds a test case to examples dir. Taken from next.js: https://github.com/vercel/next.js/blob/canary/packages/next/client/link.tsx#L89
1 parent 1d58b17 commit 45ae2cd

File tree

8 files changed

+162
-1
lines changed

8 files changed

+162
-1
lines changed
 

‎examples/anchor-links/app.tsx

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { ComponentType } from 'react'
2+
3+
const links = {
4+
'Home': '/',
5+
'About': '/about',
6+
'Query 0': '/query',
7+
'Query 1': '/query?q=hello&limit=10&offset=20',
8+
'Pink': '/colors/pink',
9+
'Orange': '/colors/orange',
10+
'Teal': '/colors/teal',
11+
'Dark Blue': '/colors/darkblue?text=yellow',
12+
'Dark Green': '/colors/darkgreen?text=orange',
13+
}
14+
15+
export default function App({ Page, pageProps }: { Page: ComponentType<any>, pageProps: any }) {
16+
return (
17+
<main>
18+
<head>
19+
<meta name="viewport" content="width=device-width" />
20+
<style>{`
21+
body {
22+
font-family: sans-serif;
23+
}
24+
nav a {
25+
margin: 10px;
26+
}
27+
`}</style>
28+
</head>
29+
<nav>
30+
{Object.entries(links).map(([name, link]) => <a key={name} href={link}>{name}</a>)}
31+
</nav>
32+
<Page {...pageProps} />
33+
</main>
34+
)
35+
}

‎examples/anchor-links/pages/about.tsx

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useDeno } from "framework/react"
2+
import React from "react"
3+
4+
export default function About() {
5+
const version = useDeno(() => Deno.version.deno)
6+
return (
7+
<div>
8+
<head>
9+
<title>About</title>
10+
<style>{`
11+
body {
12+
background: pink;
13+
}
14+
`}</style>
15+
</head>
16+
<div>
17+
<h1>About page</h1>
18+
<p>Deno version: {version}</p>
19+
</div>
20+
</div>
21+
)
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useRouter } from "framework/react"
2+
import React from "react"
3+
4+
export default function Query() {
5+
const router = useRouter()
6+
const color = router.params.name || 'white'
7+
const textColor = router.query.get('text') || 'black'
8+
return (
9+
<div>
10+
<head>
11+
<title>Color: {color}</title>
12+
<style>{`
13+
body {
14+
background: ${color};
15+
color: ${textColor};
16+
}
17+
nav a {
18+
color: ${textColor};
19+
}
20+
`}</style>
21+
</head>
22+
<div>
23+
<h1>{color}</h1>
24+
</div>
25+
</div>
26+
)
27+
}

‎examples/anchor-links/pages/index.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useDeno } from 'framework/react'
2+
import React from 'react'
3+
4+
export default function Home() {
5+
return (
6+
<div>
7+
<head>
8+
<title>Home</title>
9+
</head>
10+
<div>
11+
<h1>Home page</h1>
12+
</div>
13+
</div>
14+
)
15+
}

‎examples/anchor-links/pages/query.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useDeno, useRouter } from "framework/react"
2+
import React from "react"
3+
4+
export default function Query() {
5+
const router = useRouter()
6+
const debug = useDeno(() => {
7+
const q = Object.fromEntries(router.query.entries())
8+
return JSON.stringify(q, undefined, 2)
9+
})
10+
return (
11+
<div>
12+
<head>
13+
<title>Query</title>
14+
<style>{`
15+
body {
16+
background: #333;
17+
color: lightgreen;
18+
}
19+
nav a {
20+
color: teal;
21+
}
22+
`}</style>
23+
</head>
24+
<div>
25+
<h1>Query:</h1>
26+
<pre>{debug}</pre>
27+
</div>
28+
</div>
29+
)
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react'
2+
3+
4+
export default function Home() {
5+
6+
return (
7+
<div className="page">
8+
<head>
9+
<title>About Page - Aleph.js</title>
10+
<link rel="stylesheet" href="../style/about.css" />
11+
</head>
12+
<h1>About Page</h1>
13+
<a href="/">Back home</a>
14+
</div>
15+
)
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background: pink;
3+
}

‎framework/react/components/Anchor.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export default function Anchor(props: AnchorProps) {
113113
if (util.isFunction(props.onMouseEnter)) {
114114
props.onMouseEnter(e)
115115
}
116-
if (e.defaultPrevented) {
116+
if (e.defaultPrevented || isModifiedEvent(e)) {
117117
return
118118
}
119119
e.preventDefault()
@@ -142,3 +142,16 @@ export default function Anchor(props: AnchorProps) {
142142
children
143143
)
144144
}
145+
146+
function isModifiedEvent(event: React.MouseEvent): boolean {
147+
const { target } = event.currentTarget as any
148+
const nativeEvent = event.nativeEvent as any
149+
return (
150+
(target && target !== '_self') ||
151+
event.metaKey ||
152+
event.ctrlKey ||
153+
event.shiftKey ||
154+
event.altKey || // triggers resource download
155+
(nativeEvent && nativeEvent.which === 2)
156+
)
157+
}

0 commit comments

Comments
 (0)
Please sign in to comment.