I realize there is validation to check whether a Tab
component is the direct child: https://github.com/callemall/material-ui/blob/master/src/tabs/tabs.jsx#L215
How do I avoid this error if I want to wrap the Material UI Tab component with my own custom Tab component?
Warning: Tabs only accepts Tab Components as children.
Found function Tab(props) {
_classCallCheck(this, Tab);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Tab).call(this, props));
_this.displayName = 'Tab';
return _this;
} as child number 1 of Tabs
My component logic:
export default class Tab extends React.Component {
constructor(props){
super(props);
this.displayName = 'Tab';
}
render(){
return (
<MUITab
{...this.props}
className={classNames(
'tab',
{ 'selected': this.props.selected },
this.props.className
)}
style={style}
/>
);
}
}
Thanks for your response, @Aweary. I'm not sure how to access the type
. I tried this.displayName
in the constructor, but that didn't work. Did you mean something like this?
Tab.type = {
displayName: 'Tab'
};
Edit: I was able to figure it out!
All I had to do was write the following:
Tab.displayName = 'Tab';
I'm not sure why this.displayName
didn't work.
@ConAntonakos glad to hear it! I deleted my response because I wasn't 100% sure it was accurate, but I'm glad it helped :+1: :tada:
I'm not sure why this.displayName didn't work.
because displayName
should be a static property not instance member. I would advise against this approach. But it's the best workaround for now. The better solution would have been making Tabs
component customizable enough for these use-cases. So if you want to harden this please open a PR, but if the workaround works out for you then I'm glag your issue was resolved :+1: :smile:
I have this problem too within reagent and can't use the above displayName trick. How can I make the parent Tabs component accept a custom Tab class of mine?
(defn tab []
(reagent/create-class
{:display-name "Tab"
:reagent-render (fn [props & children]
[rui/tab (merge props {:style {:padding-top tab-padding-top}})
(map-keys children)])}))
gives material-ui.inc.js:24946 Warning: Tabs only accepts Tab Components as children.
I just ran across this as well.
For reference, the property that Tabs
validates on its children changed from displayName
to muiName
at some point between then and now.
The following example works as of 0.15.1
:
// CustomTab.jsx
import { Tab as MuiTab } from 'material-ui/Tabs';
const Tab = (props) => (<MuiTab {...props} />);
Tab.muiName = 'Tab';
export default Tab;
Ran across this after upgrading from 14 to 15. My solution after seeing @FaideWW's comment is to do this outside the class:
Foo.muiName = 'Tab';
If you have the proper babel setup, you can use static properties on the class.
class Foo extends Component {
static muiName = 'Tab';
Really just depends on your specific set-up and your standards.
Luckily, this was an easy fix. For those of us who wrap components to generalize/standardize them for use throughout an app, this tiptoes the line of being really bad. If there were not an easy way to fix this warning, I would propose removing it. There is an easy fix, so it seems to be okay to keep.
I guess it depends on opinion, but many are of the opinion that a library for components should not enforce usage in such a way. It should always allow for the flexibility of wrapping components and doing what needs to be done to write composable components. I'm in this camp.
Just ran into this issue again. Contents of my custom tabs won't show. I hope this is on the docket to be fixed in next
.
I am also having this issue. I can add static muiName = "Tab"
or CustomTab.muiName = "Tab"
which gets rid of the warning, but the tab still doesn't render as expected.
My use case is I want to encapsulate my tab logic/template into its own component. Like everyone else in this issue, all I do is return a muiTab that has all the content and logic. Not sure why this is a problem.
Any idea on a potential fix?
Currently this is the only way I can achieve what I want. It's not ideal, but I guess it will have to do. Why is this important? It allows for reusable tabs in different tab groups. I may have 3 different pages that have tab groups, all 3 use custom tab 1 and 2 use custom tab 2.
```javascript
// ./custom-tab-1.js
export default () => {
return (
// ./custom-tab-2.js
export default () => {
return (
// ./page.js
import CustomTab1 from "./custom-tab-1";
import CustomTab2 from "./custom-tab-2";
export default () => {
return (
);
}
At the current time is there any other solution any other than @blackdynamo suggested ?
Even with
class Foo extends Component {
static muiName = 'Tab';
I get rid of the warning but the CSS seem to be messed up 馃槓
@heron182 The Tabs component passes props to the Tab component. Are you passing on the props?
import React from 'react';
import { Tab as MaterialTab } from 'material-ui/Tabs';
class Tab extends React.PureComponent {
getPropsPassedFromParent() {
return {
index: this.props.index,
onClick: this.props.onClick,
selected: this.props.selected,
width: this.props.width,
}
}
render() {
return (
<MaterialTab
{...this.getPropsPassedFromParent()}
label={this.props.label}
style={{ textTransform: 'none' }}
/>
);
}
}
// https://github.com/mui-org/material-ui/issues/3622#issuecomment-227877809
Tab.displayName = Tab.muiName = 'Tab';
export default Tab;
@BenLorantfy TBH I moved along with @blackdynamo's solution and currently am working in other project. Will keep your solution around and if i come up with a "tab" problem again, I'll let you know. Thanks !
Thanks @BenLorantfy! I was having this issue, and it was because I wasn't spreading the all props; I was just using the ones that I was explicitly passing myself. It is not very intuitive that Tabs
manipulates its children's props.
Most helpful comment
I just ran across this as well.
For reference, the property that
Tabs
validates on its children changed fromdisplayName
tomuiName
at some point between then and now.The following example works as of
0.15.1
: