Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Merge 2d89c51 into 2e4ebde
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Quach committed Apr 16, 2019
2 parents 2e4ebde + 2d89c51 commit 1af565f
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 28 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
'!src/components/Dropdown/V2/Dropdown.Renderer.tsx',
'!src/components/Dropdown/V2/Dropdown.renderUtils.ts',
'!src/components/Popper/**/*.{js,jsx}',
'!src/components/Route/**/*.{js,jsx,ts}',
'!src/tests/helpers/**/*.{js,jsx}',
'!src/utilities/browser.{js,jsx,ts}',
'!src/utilities/env.{js,jsx,ts}',
Expand Down
35 changes: 28 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@
},
"peerDependencies": {
"react": "^16 || ^15",
"react-dom": "^16 || ^15",
"react-router-dom": "4.0.0 - 4.3.1"
"react-dom": "^16 || ^15"
},
"dependencies": {
"@helpscout/fancy": "2.2.6",
Expand All @@ -98,11 +97,13 @@
"compute-scroll-into-view": "1.0.11",
"dash-get": "1.0.2",
"highlight.js": "9.12.0",
"invariant": "2.2.4",
"path-to-regexp": "2.4.0",
"popper.js": "1.14.3",
"prop-types": "^15",
"react-sortable-hoc": "0.6.7",
"react-transition-group": "2.5.3"
"react-transition-group": "2.5.3",
"warning": "4.0.3"
},
"devDependencies": {
"@babel/cli": "^7.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/NavLink/NavLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/NavLink.js

import * as React from 'react'
import { Route } from 'react-router-dom'
import Route from '../Route'
import propConnect from '../PropProvider/propConnect'
import Link from '../Link'
import { classNames } from '../../utilities/classNames'
Expand Down
2 changes: 1 addition & 1 deletion src/components/Popper/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Popper

A fork of[react-popper](https://github.com/FezVrasta/react-popper) adapted for React 15 / Blue.
A fork of [react-popper](https://github.com/FezVrasta/react-popper) adapted for React 15 / Blue.
3 changes: 3 additions & 0 deletions src/components/Route/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Route

A fork of [Route](https://github.com/ReactTraining/react-router/blob/3d233bf0b6dd5bf68d9bac9c94273ae25646b207/packages/react-router/modules/Route.js) from [React Router @ 4.3.1](https://github.com/ReactTraining/react-router/tree/3d233bf0b6dd5bf68d9bac9c94273ae25646b207).
132 changes: 132 additions & 0 deletions src/components/Route/Route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import warning from 'warning'
import invariant from 'invariant'
import React from 'react'
import PropTypes from 'prop-types'
import matchPath from '../../utilities/react-router/matchPath'

const isEmptyChildren = children => React.Children.count(children) === 0

/**
* Forked from React Router @ 4.3.1
* https://github.com/ReactTraining/react-router/blob/3d233bf0b6dd5bf68d9bac9c94273ae25646b207/packages/react-router/modules/Route.js
*/
class Route extends React.Component {
static propTypes = {
computedMatch: PropTypes.object, // private, from <Switch>
path: PropTypes.string,
exact: PropTypes.bool,
strict: PropTypes.bool,
sensitive: PropTypes.bool,
component: PropTypes.func,
render: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
location: PropTypes.object,
}

static contextTypes = {
router: PropTypes.shape({
history: PropTypes.object.isRequired,
route: PropTypes.object.isRequired,
staticContext: PropTypes.object,
}),
}

static childContextTypes = {
router: PropTypes.object.isRequired,
}

getChildContext() {
return {
router: {
...this.context.router,
route: {
location: this.props.location || this.context.router.route.location,
match: this.state.match,
},
},
}
}

state = {
match: this.computeMatch(this.props, this.context.router),
}

computeMatch(
{ computedMatch, location, path, strict, exact, sensitive },
router
) {
if (computedMatch) return computedMatch // <Switch> already computed the match for us

invariant(
router,
'You should not use <Route> or withRouter() outside a <Router>'
)

const { route } = router
const pathname = (location || route.location).pathname

return matchPath(pathname, { path, strict, exact, sensitive }, route.match)
}

componentWillMount() {
warning(
!(this.props.component && this.props.render),
'You should not use <Route component> and <Route render> in the same route; <Route render> will be ignored'
)

warning(
!(
this.props.component &&
this.props.children &&
!isEmptyChildren(this.props.children)
),
'You should not use <Route component> and <Route children> in the same route; <Route children> will be ignored'
)

warning(
!(
this.props.render &&
this.props.children &&
!isEmptyChildren(this.props.children)
),
'You should not use <Route render> and <Route children> in the same route; <Route children> will be ignored'
)
}

componentWillReceiveProps(nextProps, nextContext) {
warning(
!(nextProps.location && !this.props.location),
'<Route> elements should not change from uncontrolled to controlled (or vice versa). You initially used no "location" prop and then provided one on a subsequent render.'
)

warning(
!(!nextProps.location && this.props.location),
'<Route> elements should not change from controlled to uncontrolled (or vice versa). You provided a "location" prop initially but omitted it on a subsequent render.'
)

this.setState({
match: this.computeMatch(nextProps, nextContext.router),
})
}

render() {
const { match } = this.state
const { children, component, render } = this.props
const { history, route, staticContext } = this.context.router
const location = this.props.location || route.location
const props = { match, location, history, staticContext }

if (component) return match ? React.createElement(component, props) : null

if (render) return match ? render(props) : null

if (typeof children === 'function') return children(props)

if (children && !isEmptyChildren(children))
return React.Children.only(children)

return null
}
}

export default Route
3 changes: 3 additions & 0 deletions src/components/Route/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Route from './Route'

export default Route
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export { default as PreviewCard } from './PreviewCard'
export { default as ProgressBar } from './ProgressBar'
export { default as PromoCard } from './PromoCard'
export { default as PropProvider } from './PropProvider'
export { default as Route } from './Route'
export { default as RouteWrapper } from './RouteWrapper'
export { default as Radio } from './Radio'
export { default as RadioCard } from './RadioCard'
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export const renderChildrenSafely = (

export const renderAsSingleChild = (
children: any,
baseTag: 'div',
baseTag?: 'div',
props: any = {}
) => {
const _isArray = isArray(children)
Expand Down
31 changes: 16 additions & 15 deletions src/utilities/react-router/matchPath.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
// Source
// https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/matchPath.js

// https://github.com/ReactTraining/react-router/blob/3d233bf0b6dd5bf68d9bac9c94273ae25646b207/packages/react-router/modules/matchPath.js
import pathToRegexp from 'path-to-regexp'

const cache = {}
const patternCache = {}
const cacheLimit = 10000
let cacheCount = 0

function compilePath(path, options) {
const compilePath = (pattern, options) => {
const cacheKey = `${options.end}${options.strict}${options.sensitive}`
const pathCache = cache[cacheKey] || (cache[cacheKey] = {})
const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {})

if (pathCache[path]) return pathCache[path]
if (cache[pattern]) return cache[pattern]

const keys = []
const regexp = pathToRegexp(path, keys, options)
const result = { regexp, keys }
const re = pathToRegexp(pattern, keys, options)
const compiledPattern = { re, keys }

if (cacheCount < cacheLimit) {
pathCache[path] = result
cache[pattern] = compiledPattern
cacheCount++
}

return result
return compiledPattern
}

/**
* Public API for matching a URL pathname to a path.
* Public API for matching a URL pathname to a path pattern.
*/
function matchPath(pathname, options = {}) {
const matchPath = (pathname, options = {}, parent) => {
if (typeof options === 'string') options = { path: options }

const { path, exact = false, strict = false, sensitive = false } = options

const { regexp, keys } = compilePath(path, { end: exact, strict, sensitive })
const match = regexp.exec(pathname)
if (path == null) return parent

const { re, keys } = compilePath(path, { end: exact, strict, sensitive })
const match = re.exec(pathname)

if (!match) return null

Expand All @@ -44,7 +45,7 @@ function matchPath(pathname, options = {}) {
if (exact && !isExact) return null

return {
path, // the path used to match
path, // the path pattern used to match
url: path === '/' && url === '' ? '/' : url, // the matched portion of the URL
isExact, // whether or not we matched exactly
params: keys.reduce((memo, key, index) => {
Expand Down

0 comments on commit 1af565f

Please sign in to comment.