Using material-ui I'm attempting to iterate an array and render a item value as a tab. I'd like to have the tabs grow on load as per this example https://material-ui.com/utils/transitions/#grow.
I'm able to effectively do the iteration and show the tabs as follows;
<Tabs fullWidth value={value} onChange={this.handleChange} scrollable>
{this.props.myArray.map((p, i) =>
<Tab value={p.value} label={`${p.value}`}/>)}
</Tabs>
The logical approach would be;
<Tabs fullWidth value={value} onChange={this.handleChange} scrollable>
{this.props.myArray.map((p, i) =>
<Grow in={true} timeout={500}
<Tab value={p.value} label={`${p.value}`}/>
</Grow>)}
</Tabs>
But this does not work, "p" becomes inaccessible and it does not apply the Grow effect.
Is my best option to use the Tab source and create my own component that implements a transition as outlined here https://reactcommunity.org/react-transition-group/transition?
I'm happy to do this, but would obviously prefer the above method if there is a simple solution.
Thanks!
Related
Consider the following code snippet of a component:
...
...
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
...
...
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={handleChange} aria-label="simple tabs example">
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0}>
Item One
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Three
</TabPanel>
</div>
);
}
I struggle to understand the following component implementation:
<Tab label="Item One" {...a11yProps(0)} />
What does {...a11yProps(0)} mean? Does it mean I pass here properties?
When I look at the API documentation of Tab, I can not find the id and aria-controls properties.
The whole code https://codesandbox.io/s/kz25m
It is a spread operator (... is Javascript spread operator). It basically de-structures / spreads out the value from an array or object.
In your sample code I see your function returns some javascript object. This spread operator pulls out / de-structures all the values from the object and gives each individual values as output
{... a11yProps(0)}
==> This would return -> {...{id: `simple-tab-0`,aria-controls: `simple-tabpanel-0`}}
==> on spreading out the values from the object it would look like
=> {id: `simple-tab-0`,aria-controls: `simple-tabpanel-0`}
Another example with spread operator
let d = {...{"a":1, "b":2, "c":3}}
output: {a: 1, b: 2, c: 3}
Please refer to ES6 website for more on spread operator, destructuring - http://es6-features.org/#SpreadOperator
It's just a function for making a dynamic object and using them as props, to reduce code size.
<Tab label="Item One" id="simple-tab-0" ariaControls="simple-tabpanel-0"/>
About TypeScript and Docs: If you ctrl + click on the Material-UI component, you can see they extends types of component with React.ElementType and inside of this, you can find JSX.IntrinsicElements and each one of HTML element has React.DetailedHTMLProps with props of HTMLAttributes extended with AriaAttributes and DOMAttributes. So naturally, you can pass all of the available attributes for that tag on them!
I am trying to make a select element for cities with material-UI. The problem is that I need to have the same design as the Textfields I have above that element. I used the following
<FormControl variant='outlined' className={classes.city}>
<InputLabel>City</InputLabel>
<Select
label='City'
value={city}
onChange={(event) => setCity(event.target.value)}
>
{cities.map((storeCity, key) => <MenuItem key={key} value={storeCity.id}>{storeCity.name}</MenuItem>)}
</Select>
</FormControl>
Before clicking the element
This gives me the perfect visual output and generally works well. The only problem is that it is slow as the cities array contains more than 200 cities. What should I do to have the same visual effect with faster rendering?
Imagine I have a button somewhere. When clicked, the text on it, now goes to my search bar. How do I make the window scroll to the search bar too after the value is set in the Input element shown below?
<Flex
flexDirection="column"
justifyContent="center"
alignItems="center"
maxWidth="90%"
mt={4}
>
{!filteredBlogPosts.length && 'No posts found.'}
{filteredBlogPosts.map((frontMatter) => (
<>
<BlogPost
key={frontMatter.title + frontMatter.lastPublishedOn}
handleSearch={(anyKey) => setSearchValue(anyKey)}
// Insert your code here, how to scroll after setting the key to search?
{...frontMatter}
/>
</>
))}
</Flex>
And, here is the <Input> field
<Input
aria-label="Search"
borderColor="blue.500"
onChange={(e) => setSearchValue(e.target.value)}
placeholder="Search"
value={searchValue}
//or should I do scroll here? How?
autoFocus
onFocus={e => e.currentTarget.select()}
/>
Is this something easy to do? Please present code examples if possible.
Thanks.
If anyone faces this issue in the future, I solved it using this simple function.
const scrollSearch = myKey => {
window.scrollTo(0, 0);
frontMatter.handleSearch(myKey)
};
And passed the scrollSearch function in button onClick.
I need my tabs to have a tab consisting of a switch but when I implemented it as it was said, I am not able to see it there.
Maybe it's hidden underneath but I tried changing its z-index.
Pass your Switch component as the label prop.
...
<Tab
component="span"
label={
<Switch
checked={isSwitchOn}
onChange={(e) => setSwitch(!isSwitchOn)}
name="toggleType"
/>
}
/>
Tab component does not display children props inside the MuiTab-wrapper element.
Maybe you can use icon props.
<Tab
component="span"
icon={
<Switch
checked={isSwitchOn}
onChange={(e) => setSwitch(!isSwitchOn)}
name="toggleType"
/>
}
/>
I'm working with React.js and Carbon as Design System. I have a Tabs component with multiple Tab and I need to disable one of them if a condition is not satisfied.
I have tried to disable using the carbon class
className="bx--tabs__nav-item--disabled"
and also with prop disabled={true}but none of them works
There is some different way to disable the Tab element?? I know that avoid the onclick event works, but is no the prettiest way.
This is the code of the Tabs component.
<Tabs
tabContentClassName="tab-content"
className="tabs element-header__tabs"
>
<Tab
onClick={(e) =>
onclickHandler(e)
}
label="tab 1"
/>
<Tab
onClick={(e) =>
onclickHandler(e)
)
}
label="tab 2"
/>
<Tab
disabled={true}
onClick={(e) =>
onclickHandler(e)
)
}
label="tab 3"
/>
</Tabs>
For anyone else who stumbles across this...
disable={true}
Now works in the current version of Carbon Tabs. I'm not sure if it didn't work before but it does now...
https://www.carbondesignsystem.com/components/tabs/code