mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
add Link component
This commit is contained in:
parent
66b224ad26
commit
cb11c7cbc6
|
@ -1,11 +1,13 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import App from '../lib/app'
|
import App from '../lib/app'
|
||||||
|
import Link from '../lib/link'
|
||||||
|
|
||||||
const modules = new Map([
|
const modules = new Map([
|
||||||
['react', React],
|
['react', React],
|
||||||
['react-dom', ReactDOM],
|
['react-dom', ReactDOM],
|
||||||
['next/app', App]
|
['next/app', App],
|
||||||
|
['next/link', Link]
|
||||||
])
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
71
lib/link.js
Normal file
71
lib/link.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import React, { Component, PropTypes, Children } from 'react'
|
||||||
|
|
||||||
|
export default class Link extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
router: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
this.linkClicked = this.linkClicked.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
linkClicked (e) {
|
||||||
|
if ('A' === e.target.nodeName &&
|
||||||
|
(e.metaKey || e.ctrlKey || e.shiftKey || 2 === e.nativeEvent.which)) {
|
||||||
|
// ignore click for new tab / new window behavior
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { href, scroll } = this.props
|
||||||
|
|
||||||
|
if (!isLocal(href)) {
|
||||||
|
// ignore click if it's outside our scope
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
// straight up redirect
|
||||||
|
this.context.router.goTo(href, (err) => {
|
||||||
|
if (err) {
|
||||||
|
if (this.props.onError) this.props.onError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false !== scroll) {
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const children = Children.map(this.props.children, (child) => {
|
||||||
|
const props = {
|
||||||
|
onClick: this.linkClicked
|
||||||
|
}
|
||||||
|
|
||||||
|
const isChildAnchor = child && 'a' === child.type
|
||||||
|
|
||||||
|
// if child does not specify a href, specify it
|
||||||
|
// so that repetition is not needed by the user
|
||||||
|
if (!isChildAnchor || !('href' in child.props)) {
|
||||||
|
props.href = this.props.href
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChildAnchor) {
|
||||||
|
return React.cloneElement(child, props)
|
||||||
|
} else {
|
||||||
|
return <a {...props}>{child}</a>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return children[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLocal (href) {
|
||||||
|
const origin = location.origin
|
||||||
|
return !/^https?:\/\//.test(href) ||
|
||||||
|
origin === href.substr(0, origin.length)
|
||||||
|
}
|
|
@ -26,7 +26,8 @@ export function transpile (path) {
|
||||||
moduleAlias,
|
moduleAlias,
|
||||||
[
|
[
|
||||||
{ src: `npm:${babelRuntimePath}`, expose: 'babel-runtime' },
|
{ src: `npm:${babelRuntimePath}`, expose: 'babel-runtime' },
|
||||||
{ src: `npm:${require.resolve('react')}`, expose: 'react' }
|
{ src: `npm:${require.resolve('react')}`, expose: 'react' },
|
||||||
|
{ src: `npm:${require.resolve('../lib/link')}`, expose: 'next/link' }
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
@ -51,13 +52,9 @@ export function bundle (path) {
|
||||||
externals: [
|
externals: [
|
||||||
'react',
|
'react',
|
||||||
'react-dom',
|
'react-dom',
|
||||||
'next',
|
|
||||||
'next/head',
|
|
||||||
'next/link',
|
|
||||||
'next/component',
|
|
||||||
'next/app',
|
|
||||||
{
|
{
|
||||||
[require.resolve('react')]: 'react'
|
[require.resolve('react')]: 'react',
|
||||||
|
[require.resolve('../lib/link')]: 'next/link'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
resolveLoader: {
|
resolveLoader: {
|
||||||
|
|
Loading…
Reference in a new issue