From cdb8c67b126d1e0d4a5bee9487e42d8116af0e60 Mon Sep 17 00:00:00 2001 From: dpwrussell Date: Mon, 19 Sep 2016 13:49:36 -0400 Subject: [PATCH 1/2] Placeholder fragment --- src/index.js | 2 ++ src/placeholder-fragment.js | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/placeholder-fragment.js diff --git a/src/index.js b/src/index.js index 967ec6af..9cf43ffe 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import createStoreWithRouter, { import provideRouter, { RouterProvider } from './provider'; import { Link, PersistentQueryLink } from './link'; import { AbsoluteFragment, RelativeFragment } from './fragment'; +import PlaceholderFragment from './placeholder-fragment'; import routerReducer from './reducer'; import createMatcher from './create-matcher'; @@ -35,6 +36,7 @@ export { Fragment, AbsoluteFragment, RelativeFragment, + PlaceholderFragment, // Public action types LOCATION_CHANGED, diff --git a/src/placeholder-fragment.js b/src/placeholder-fragment.js new file mode 100644 index 00000000..ace6cd67 --- /dev/null +++ b/src/placeholder-fragment.js @@ -0,0 +1,71 @@ +// @flow +import type { Location } from 'history'; +import type { RouterContext } from './provider'; +import React, { PropTypes } from 'react'; + +type Props = { + forRoute?: string, + forRoutes?: Array, + withConditions?: (location: Location) => bool, + children: React.Element<*> +}; + +type Context = { + router?: RouterContext +}; + +const PlaceholderFragment = (props: Props, context: Context ) => { + const { + forRoute, + forRoutes, + withConditions, + children + } = props; + + const { store } = context.router; + const { matchRoute } = store; + const { router: location } = store.getState(); + + const matchResult = matchRoute(location.pathname); + + if (!matchResult) { + return null; + } + + if ( + forRoute && + matchResult.route !== forRoute + ) { + return null; + } + + if (Array.isArray(forRoutes)) { + const anyMatch = forRoutes.some(route => + matchResult.route === route + ); + + if (!anyMatch) { + return null; + } + } + + if (withConditions && !withConditions(location)) { + return null; + } + + if (matchResult && matchResult.result && matchResult.result.component) { + return React.createElement( + matchResult.result.component, + matchResult.result.componentProps ? matchResult.result.componentProps : {}, + children + ); + } + + return null; +}; + +PlaceholderFragment.contextTypes = { + router: PropTypes.object +}; + +export default PlaceholderFragment; From a007b722ff013d60e877e217066e83740fd99807 Mon Sep 17 00:00:00 2001 From: dpwrussell Date: Mon, 19 Sep 2016 14:05:06 -0400 Subject: [PATCH 2/2] PlaceholderFragment can have the key of the component and component props configured --- src/placeholder-fragment.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/placeholder-fragment.js b/src/placeholder-fragment.js index ace6cd67..1836700d 100644 --- a/src/placeholder-fragment.js +++ b/src/placeholder-fragment.js @@ -7,7 +7,9 @@ type Props = { forRoute?: string, forRoutes?: Array, withConditions?: (location: Location) => bool, - children: React.Element<*> + children: React.Element<*>, + componentKey: string, + componentPropsKey?: string }; type Context = { @@ -19,7 +21,9 @@ const PlaceholderFragment = (props: Props, context: Context ) => { forRoute, forRoutes, withConditions, - children + children, + componentKey = 'component', + componentPropsKey = 'componentProps' } = props; const { store } = context.router; @@ -53,10 +57,12 @@ const PlaceholderFragment = (props: Props, context: Context ) => { return null; } - if (matchResult && matchResult.result && matchResult.result.component) { + if (matchResult && matchResult.result && matchResult.result.hasOwnProperty(componentKey)) { return React.createElement( - matchResult.result.component, - matchResult.result.componentProps ? matchResult.result.componentProps : {}, + matchResult.result[componentKey], + matchResult.result.hasOwnProperty(componentPropsKey) ? + matchResult.result[componentPropsKey] : + {}, children ); }