diff --git a/packages/ra-ui-materialui/src/detail/TabbedShowLayout.js b/packages/ra-ui-materialui/src/detail/TabbedShowLayout.js index e45fe80e75..22c72cccd4 100644 --- a/packages/ra-ui-materialui/src/detail/TabbedShowLayout.js +++ b/packages/ra-ui-materialui/src/detail/TabbedShowLayout.js @@ -1,12 +1,12 @@ import React, { Component, Children, cloneElement } from 'react'; import PropTypes from 'prop-types'; -import Tabs from '@material-ui/core/Tabs'; import Divider from '@material-ui/core/Divider'; import { withRouter, Route } from 'react-router-dom'; import compose from 'recompose/compose'; import { translate } from 'ra-core'; import CardContentInner from '../layout/CardContentInner'; +import TabbedShowLayoutTabs from './TabbedShowLayoutTabs'; const sanitizeRestProps = ({ children, @@ -18,6 +18,7 @@ const sanitizeRestProps = ({ initialValues, staticContext, translate, + tabs, ...rest }) => rest; @@ -31,6 +32,7 @@ const getTabFullPath = (tab, index, baseUrl) => * * Receives the current `record` from the parent `` component, * and passes it to its childen. Children should be Tab components. + * The component passed as `tabs` props replaces the default material-ui's component. * * @example * // in src/posts.js @@ -77,36 +79,22 @@ export class TabbedShowLayout extends Component { translate, version, value, + tabs, ...rest } = this.props; return ( -
- - {Children.map(children, (tab, index) => { - if (!tab) return null; - - // Builds the full tab tab which is the concatenation of the last matched route in the - // TabbedShowLayout hierarchy (ex: '/posts/create', '/posts/12', , '/posts/12/show') - // and the tab path. - // This will be used as the Tab's value - const tabPath = getTabFullPath(tab, index, match.url); - - return cloneElement(tab, { - context: 'header', - value: tabPath, - }); - })} - +
+ {cloneElement( + tabs, + { + // The location pathname will contain the page path including the current tab path + // so we can use it as a way to determine the current tab + value: location.pathname, + match, + }, + children, + )} {Children.map( @@ -144,6 +132,11 @@ TabbedShowLayout.propTypes = { value: PropTypes.number, version: PropTypes.number, translate: PropTypes.func, + tabs: PropTypes.element.isRequired, +}; + +TabbedShowLayout.defaultProps = { + tabs: }; const enhance = compose( diff --git a/packages/ra-ui-materialui/src/detail/TabbedShowLayoutTabs.js b/packages/ra-ui-materialui/src/detail/TabbedShowLayoutTabs.js new file mode 100644 index 0000000000..27d4b62f3d --- /dev/null +++ b/packages/ra-ui-materialui/src/detail/TabbedShowLayoutTabs.js @@ -0,0 +1,34 @@ +import React, { Children, cloneElement } from 'react'; +import PropTypes from 'prop-types'; +import Tabs from '@material-ui/core/Tabs'; + +const getTabFullPath = (tab, index, baseUrl) => + `${baseUrl}${ + tab.props.path ? `/${tab.props.path}` : index > 0 ? `/${index}` : '' + }`; + +const TabbedShowLayoutTabs = ({ children, match, ...rest }) => ( + + {Children.map(children, (tab, index) => { + if (!tab) return null; + // Builds the full tab tab which is the concatenation of the last matched route in the + // TabbedShowLayout hierarchy (ex: '/posts/create', '/posts/12', , '/posts/12/show') + // and the tab path. + // This will be used as the Tab's value + const tabPath = getTabFullPath(tab, index, match.url); + + return cloneElement(tab, { + context: 'header', + value: tabPath, + }); + })} + +); + +TabbedShowLayoutTabs.propTypes = { + children: PropTypes.node, + match: PropTypes.object, + value: PropTypes.string, +}; + +export default TabbedShowLayoutTabs;