Skip to content

Commit

Permalink
accept object and function for to (#26)
Browse files Browse the repository at this point in the history
In the `<Link>`, `<NavLink>`, and `<Redirect>` components, accept a
string, object, or function for `to`. Previously, only a string was
accepted.
  • Loading branch information
zfletch committed Apr 23, 2021
1 parent dc6816f commit 39e43ba
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/demo/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ const Header = ({
</NavLink>
</li>
<li>
<NavLink to="/about">
<NavLink to={{ pathname: '/about' }}>
<I18n t="about" />
</NavLink>
</li>
<li>
<NavLink to="/topics">
<NavLink to={(location) => ({ ...location, pathname: '/topics' })}>
<I18n t="topics" />
</NavLink>
</li>
Expand Down
58 changes: 48 additions & 10 deletions src/lib/components/I18n/withLocale.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,47 @@ import PropTypes from 'prop-types';

import { withRouter } from 'react-router-dom';

const newToPath = (to, locale) => (
to[0] === '/'
? `/${locale}${to}`
: `${locale}/${to}`
);

const newToObject = (to, locale) => {
const { pathname } = to;

if (typeof pathname !== 'string') { return to; }

const toObj = { ...to, pathname: newToPath(pathname, locale) };

return toObj;
};

const newToFunction = (to, locale) => (
(location) => {
const result = to(location);

return typeof result === 'string'
? newToPath(result, locale)
: newToObject(result, locale);
}
);

const newTo = (to, params) => {
if (!params) { return to; }

const { locale } = params;

if (!locale) { return to; }

const type = typeof to;

if (type === 'string') { return newToPath(to, locale); }
if (type === 'function') { return newToFunction(to, locale); }

return newToObject(to, locale);
};

const withLocale = (WrappedComponent) => {
const NewComponent = ({
to,
Expand All @@ -24,24 +65,21 @@ const withLocale = (WrappedComponent) => {
);
}

let path = to;

if (params && params.locale) {
path = path[0] === '/'
? `/${params.locale}${path}`
: `${params.locale}/${path}`;
}

return (
<WrappedComponent
to={path}
to={newTo(to, params)}
{...rest}
/>
);
};

NewComponent.propTypes = {
to: PropTypes.string.isRequired,
to: PropTypes.oneOfType([
PropTypes.string,
// eslint-disable-next-line react/forbid-prop-types
PropTypes.object,
PropTypes.func,
]).isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
locale: PropTypes.string,
Expand Down

0 comments on commit 39e43ba

Please sign in to comment.