Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFR] Add options prop to TabbedShowLayout #2740

Merged
merged 10 commits into from
Jan 15, 2019
47 changes: 20 additions & 27 deletions packages/ra-ui-materialui/src/detail/TabbedShowLayout.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -18,6 +18,7 @@ const sanitizeRestProps = ({
initialValues,
staticContext,
translate,
tabs,
...rest
}) => rest;

Expand All @@ -31,6 +32,7 @@ const getTabFullPath = (tab, index, baseUrl) =>
*
* Receives the current `record` from the parent `<Show>` component,
* and passes it to its childen. Children should be Tab components.
* The component passed as `tabs` props replaces the default material-ui's <Tabs> component.
*
* @example
* // in src/posts.js
Expand Down Expand Up @@ -77,36 +79,22 @@ export class TabbedShowLayout extends Component {
translate,
version,
value,
tabs,
...rest
} = this.props;

return (
<div
className={className}
key={version}
{...sanitizeRestProps(rest)}
>
<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}
indicatorColor="primary"
>
{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,
});
})}
</Tabs>
<div className={className} key={version} {...sanitizeRestProps(rest)}>
{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,
)}
<Divider />
<CardContentInner>
{Children.map(
Expand Down Expand Up @@ -144,6 +132,11 @@ TabbedShowLayout.propTypes = {
value: PropTypes.number,
version: PropTypes.number,
translate: PropTypes.func,
tabs: PropTypes.element.isRequired,
};

TabbedShowLayout.defaultProps = {
tabs: <TabbedShowLayoutTabs />
};

const enhance = compose(
Expand Down
34 changes: 34 additions & 0 deletions packages/ra-ui-materialui/src/detail/TabbedShowLayoutTabs.js
Original file line number Diff line number Diff line change
@@ -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 }) => (
<Tabs indicatorColor='primary' {...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,
});
})}
</Tabs>
);

TabbedShowLayoutTabs.propTypes = {
children: PropTypes.node,
match: PropTypes.object,
value: PropTypes.string,
};

export default TabbedShowLayoutTabs;