Skip to content

Commit

Permalink
[RFR] Add options prop to TabbedShowLayout (#2740)
Browse files Browse the repository at this point in the history
* Add options prop to TabbedShowLayout

* Use tabs prop to pass a material-ui's Tabs element

Instead of using an "options" prop to pass props to the <Tabs> in
<TabbedShowLayout>, now a whole <Tabs> custom component can be passed
through the new "tabs" prop.

* Add options prop to TabbedShowLayout

* Use tabs prop to pass a material-ui's Tabs element

Instead of using an "options" prop to pass props to the <Tabs> in
<TabbedShowLayout>, now a whole <Tabs> custom component can be passed
through the new "tabs" prop.

* Remove grandchildren mapping from TabbedShowLayout

Also fix linting.

* Remove unused props and fix misused spread operator

* Pass the rest of the TabbedShowLayoutTabs props to its children

* Pass TabbedShowLayoutTabs rest props to Tabs

Previously it was being passed to its children.

* Fix propTypes
  • Loading branch information
lucas2595 authored and fzaninotto committed Jan 15, 2019
1 parent bee7f09 commit ce9ddda
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
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;

0 comments on commit ce9ddda

Please sign in to comment.