You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.0 KiB
67 lines
2.0 KiB
import PropTypes from 'prop-types'; |
|
|
|
import { __RouterContext } from 'react-router'; |
|
|
|
import hoistStatics from 'hoist-non-react-statics'; |
|
|
|
export const WithRouterPropTypes = { |
|
match: PropTypes.object.isRequired, |
|
location: PropTypes.object.isRequired, |
|
history: PropTypes.object.isRequired, |
|
}; |
|
|
|
export const WithOptionalRouterPropTypes = { |
|
match: PropTypes.object, |
|
location: PropTypes.object, |
|
history: PropTypes.object, |
|
}; |
|
|
|
export interface OptionalRouterProps { |
|
ref: unknown; |
|
wrappedComponentRef: unknown; |
|
} |
|
|
|
// This is copied from https://github.com/remix-run/react-router/blob/v5.3.4/packages/react-router/modules/withRouter.js |
|
// but does not fail if called outside of a React Router context |
|
export function withOptionalRouter< |
|
ComponentType extends React.ComponentType<OptionalRouterProps>, |
|
>(Component: ComponentType) { |
|
const displayName = `withRouter(${Component.displayName ?? Component.name})`; |
|
const C = (props: React.ComponentProps<ComponentType>) => { |
|
const { wrappedComponentRef, ...remainingProps } = props; |
|
|
|
return ( |
|
<__RouterContext.Consumer> |
|
{(context) => { |
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition |
|
if (context) { |
|
return ( |
|
// @ts-expect-error - Dynamic covariant generic components are tough to type. |
|
<Component |
|
{...remainingProps} |
|
{...context} |
|
ref={wrappedComponentRef} |
|
/> |
|
); |
|
} else { |
|
// @ts-expect-error - Dynamic covariant generic components are tough to type. |
|
return <Component {...remainingProps} ref={wrappedComponentRef} />; |
|
} |
|
}} |
|
</__RouterContext.Consumer> |
|
); |
|
}; |
|
|
|
C.displayName = displayName; |
|
C.WrappedComponent = Component; |
|
C.propTypes = { |
|
...Component.propTypes, |
|
wrappedComponentRef: PropTypes.oneOfType([ |
|
PropTypes.string, |
|
PropTypes.func, |
|
PropTypes.object, |
|
]), |
|
}; |
|
|
|
return hoistStatics(C, Component); |
|
}
|
|
|