77ace510 |
import * as R from 'ramda';
|
5c5f8ac3 |
import React, {useReducer, useEffect} from 'react';
import PropTypes from 'prop-types';
|
77ace510 |
const RouteContext = React.createContext(null);
const ActionDispatcherContext = React.createContext(null);
function RouteProvider({children, actionDispatcher, _window}) {
const [route, updateRoute] = useReducer((state, action) =>
R.omit(['type'], R.assoc('routeName', action.type, action))
, {});
useEffect(() => {
return actionDispatcher.addActionListener(action => updateRoute(action));
});
useEffect(() => {
actionDispatcher.receiveLocation(_window.location);
});
return (<ActionDispatcherContext.Provider value={actionDispatcher}>
<RouteContext.Provider value={route}>
{children}
</RouteContext.Provider>
</ActionDispatcherContext.Provider>);
}
RouteProvider.defaultProps = {
_window: window ? window : null
};
|
5c5f8ac3 |
RouteProvider.propTypes = {
_window: PropTypes.object,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]),
actionDispatcher: PropTypes.object
};
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
|
77ace510 |
function withRoute(Component) {
|
5c5f8ac3 |
const routeAdded = ({children, ...restProps}) => {
|
77ace510 |
return (<RouteContext.Consumer>
{route =>
<Component {...{...restProps, route}}>{children}</Component>
}
</RouteContext.Consumer>
)
|
5c5f8ac3 |
};
routeAdded.displayName = `withRoute(${getDisplayName(Component)})`
routeAdded.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
])
};
return routeAdded;
|
77ace510 |
}
function RouteLink({route, params, children, ...props}) {
const action = {
type: route, ...params
};
return <ActionDispatcherContext.Consumer>{
dispatcher => {
const url = dispatcher.pathForAction(action);
return <a
onClick={(ev) => {
ev.preventDefault();
|
df6a63f6 |
dispatcher.receiveAction(action, true);
|
77ace510 |
}}
href={url} {...props}>{children}</a>
}
}
</ActionDispatcherContext.Consumer>;
}
|
5c5f8ac3 |
RouteLink.propTypes = {
route: PropTypes.string,
params: PropTypes.object,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]),
};
|
77ace510 |
export {RouteProvider, withRoute, RouteLink};
|