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 ReactDOM from 'react-dom'
|
||||
import App from '../lib/app'
|
||||
import Link from '../lib/link'
|
||||
|
||||
const modules = new Map([
|
||||
['react', React],
|
||||
['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,
|
||||
[
|
||||
{ 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: [
|
||||
'react',
|
||||
'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: {
|
||||
|
|
Loading…
Reference in a new issue