Material UI tabs not working with Scroll to - javascript

I am trying to scroll to div when clicking on Tab with Material UI Tabs, UseRef and ScrollTo.
Sand box Link: https://codesandbox.io/s/exciting-sound-mrw2v
when clicked on Tab 2, I am expecting to scroll onto Tab2 Contents and Tab 1 contents visible on scrolling.Currently it requires two clicks to scroll onto the div, I am wondering why its behind one click. Any leads appreciated. Thanks!

I edited your example and I added a useEffect hook and if you press a tab 2 is scrolling into this content.
https://codesandbox.io/s/lingering-voice-y45cg

use this syntax
<Tabs
classes={{ root: classes.root, scroller: classes.scroller }}
value={active}
onChange={(event, newValue) => {
setActive(newValue);
}}
indicatorColor="primary"
textColor="primary"
variant={"scrollable"}
scrollButtons={"on"}
>
{cities.map((city, index) => (
<Tab key={index} label={city} value={city} />
))}
</Tabs>
this two line of properties important
variant={"scrollable"}
scrollButtons={"on"}
full example link: https://codesandbox.io/s/material-ui-centered-scrollable-tabs-ud26w?file=/index.js:645-1048

Related

Change Icon color inside the tab MUI

I am trying to change the tab icon colour of the Tab which is highlighted and keep unchanged for the rest but I am unable to figure it out. I am passing MUI component inside the icon button.
<Tab
icon={
<Icon
color={cinchdark}
name={item.icon}
size='small'
/>
}
key={item.name}
label = {
<Typography variant='button'>{item.name} </Typography>
}
{...a11yProps(index)}
/>))}
</Tabs>
WHAT I AM TRYING TO ACHIEVE
HOW IT IS LOOKING RIGHT NOW
For Icon, you can add color in classname in component
className={classes.icon}
icon: {
color: '#F48273',
},
To change the indicator color either you can use props
TabIndicatorProps={{className: classes.tabIndicator}}
and add background color in the class or if this is from your theme you can simply add
indicatorColor="primary"
textColor="primary"
In your Tabs component.

ReactJS: clickable text - how can I disable click outside the text area?

I have a clickable text component with Material UI Typography:
<MDBox mt={2} mb={1}>
<MDTypography variant="body2" style={{color: 'white', cursor:"pointer"}}
onClick={()=>dispatch({type: "goBackToPage1"})}
>
Go back to previous page
</MDTypography>
</MDBox>
As you can see, the Typography takes up the entire row area, such that even if I put the mouse on the green area (on the same row but outside the text area), the mouse still turns into a pointer and you can still click it.
How do I restrict clicking to be strictly on the text, instead the whole row area?
You can try to pass "component" prop to MUI Typography and and set it as span
<Typography component="span">
...
</Typography>

MUI Tab indicator styling override

I am currently trying to customize the MUI tab so that the indicator instead of a line at the bottom is a background color. After research I have found that using the TabIndicatorProps and passing it a style of display:none gets rid of the indicator completely. backgroundColor:"color" changes the line color but I cant figure out how to change it from a line to the whole background.
Some possible solutions I tried but did not work was giving the TabIndicatorProps a height:100% This create the background but masks the text in the tab. After that giving it an opacity: .8 gives me the effect I want but the text is too dark and I can't get it to change as the tab is active.
Expected Tab Image
Current Tab Image
<Box sx={{ width: '100%', bgcolor: 'background.paper' }}>
<Tabs TabIndicatorProps={{
style: {
backgroundColor: '#D2603D',
borderRadius: '5px',
},
}} value={value} onChange={handleChange}>
<Tab textColor='blue' onClick={handleClick} sx={{
backgroundColor: '#F4F5F9',
borderRadius: '5px',
}} label="Daily" />
< Tab sx={{
backgroundColor: '#F4F5F9',
}} label="Weekly" />
<Tab sx={{
backgroundColor: '#F4F5F9',
borderRadius: '5px'
}} label="Monthly" />
</Tabs>
</Box >
I don't think that is possible in a clean way. Either quite dirty workarounds or substantial re-implementation of the functionality is necessary.
The tab labels are <button> elements, the tab indicator is a <span> that lies above these buttons, but you want the labels appear above the indicator.
So you have to either rearrange the stacking of the HTML elements, or add a second label above the indicator.
It is not possible to let the tab indicator slide behind the button text, but in front of the button background.
Some suboptimal ("dirty") workarounds
You could re-arrange the stacking of the HTML elements.
This can be done by using z-index. You have to set the z-index of the buttons, and you need to keep the
button background transparent.
Note that you might have to be careful if there are other elements which already have a z-index,
or should stay behind the buttons, in which case you would need to change the z-index of these other elements as well.
<Tab label="Daily" style={{ zIndex: 1 }} />
<Tab label="Weekly" style={{ zIndex: 1 }} />
<Tab label="Monthly" style={{ zIndex: 1 }} />
You could add the current label as a children of the tab indicator, and set the style to match the original label. You would also need to pass the current label,
and the label would slide with the indicator, or the indicator would be empty while sliding.
const IndicatorLabel = ({ label }) => {
return <span className={'indicator-label'}>
{ label }
</span>;
};
// ...
<Tabs
TabIndicatorProps={{
// ...
children: <IndicatorLabel label={ currentLabel } />
}}
>
// ...
You could set the background color of the <button> dynamically, and not use the indicator at all. Of course, you would lose the sliding effect.
Of course, you could implement you own tab indicator from scratch, and don't use the MUI tab indicator.

How can I reveal an element behind a flatlist and have it interactable in React Native?

I am trying to render an element that is positioned absolutely behind a flatlist and it will be revealed once the user scrolls to the bottom. The issue I am facing is that the element needs to be interactable, and the flatlist root element takes all pointerevents instead of the background element.
const FlatlistOverElement: FC = () => (
<View style={{ flex: 1, width: '100%' }}>
<FlatList
data={data}
style={{ flexGrow: 1 }}
ListFooterComponent={() => (
<View style={{ height: BACKGROUND_ELEMENT_HEIGHT, opacity: 0 }} />
)}
renderItem={RenderItem}
/>
<AbsolutelyPositionedElementBehindFlatList />
</View>
)
I have tried to remove pointerevents from the flatlist, then the flatlist is not scrollable.
I have tried to set the height of the flatlist smaller, and let the content overflow. This allows the user to interact with the element, but for that part of the screen, the user can not scroll the flatlist.
What other approach can I utilise in order to solve this issue ?
You can use zIndex property on the scroll completion. Just provide a higher zIndex value than that of FlatList to absolute component whenever the scroll is completed.
zIndex Layout Props
Thanks for the suggestions. I ended up using a zIndex to put the interactable content in front of the flatlist when having scrolled to the end, as well as adding snap points on both sides of the element. To prevent the user from half revealing the element and not be able to interact with it.

How to readjust positioning of Bootstrap Overlay/Popover in React dynamically?

I am trying to readjust the positioning of an Overlay, containing a Popover, who's content changes dynamically. As it currently stands, the Popover content updates, but the position of the Popover doesn't change. This results in the updated Popover being in the wrong position (kinda floating there).
First state with content displaying correctly.
After content of Popover updates.
Here's my code:
<Form.Group>
<Form.Label>Listing URL</Form.Label>
<Form.Control name="url" ref={this.urlInput} value={this.state.current_listing.listing.url} onChange={this.handleURL} placeholder="Enter URL"/>
<Overlay target={this.urlInput.current} show={this.state.similar_listings.length > 0} placement="right">
<Popover style={{width: "700px", maxWidth: "700px"}} key={seedrandom(this.state.current_listing.url)}>
<Popover.Title as="h3">Similar Listings</Popover.Title>
<Popover.Content>
<ListingAccordion listings={this.state.similar_listings} callback={this.callback} mode="similar"/>
</Popover.Content>
</Popover>
</Overlay>
</Form.Group>
I've tried adding the shouldUpdatePosition prop to the Overlay as mentioned in previous questions, but it didn't fix anything. I also tried with the OverlayTrigger component, but that also had the same issue.
I ended up solving my own question. Hopefully this helps someone. I fixed the positioning issue by forcing React to re-render the Overlay component.
This answer gets all the credit.
All I did was add the random value key to the Overlay, and update the key whenever the contents change.
Overlay:
<Overlay key={this.state.overlayKey} ... > ... </Overlay>
In the function where the contents of the Overlay are being changed:
this.setState({ key: Math.random() });

Categories

Resources