Is it possible to make MUI Tabs to be responsive?
What I have:
What I want to achieve:
You can set flexWrap: 'wrap' in the tab container component which is a flexbox:
<Tabs
// disable the tab indicator because it doesn't work well with wrapped container
TabIndicatorProps={{ sx: { display: 'none' } }}
sx={{
'& .MuiTabs-flexContainer': {
flexWrap: 'wrap',
},
}}
{...}
>
Related
I am working on a react project, where I want to conditionally render a div above an existing div that currently covers the screen with an image. I would like the existing div to reduce in height, by shrinking the size of the image, when the second div conditionally renders. The second div can have a varied height. ( e.g. list of items).
This is simplified version of what I have in my App so far:
function App() {
const [show, setShow] = useState(false);
return (
<div
style={{
border: "solid",
width: "100%",
maxHeight: "100vh"
}}
>
{show && (
<div>
<div style={{ height: "300px", backgroundColor: "red" }}></div>
<button
onClick={() => {
setShow(false);
}}
>
Close
</button>
</div>
)}
<div
style={{
display: "flex",
justifyContent: "center"
}}
>
<img
src="https://i.imgur.com/LiAUjYw.png"
alt="test"
style={{
maxWidth: "100%",
height: "auto"
}}
/>
</div>
<button onClick={() => setShow(true)}>SHow</button>
</div>
);
}
It initially looks like this: https://imgur.com/a/R0e74Xk
And on clicking the 'Show' button, it looks like this: https://imgur.com/a/Iy6osio
As you can see the bottom div gets shifted down, and goes over the container div.
I was wondering how I can make the div responsive enough to change its height when the other element is rendered.
I am fairly new to styling so any help on this would be greatly appreciated.
Thank you.
Here's one simple idea. See how the style is given to the divs like so:
<div
style={{
display: "flex",
justifyContent: "center"
}}
>
Note how the style has this weird {{ }} notation. That's because style accepts an object, and the object here is:
{
display: "flex",
justifyContent: "center"
}
You could take that object and save it as a variable somewhere, for example:
const styleWhenShow = {
display: "flex",
justifyContent: "center",
height: "100px"
}
const styleWhenNoShow = {
display: "flex",
justifyContent: "center",
height: "500px"
}
Since you already have your show state, now it's just a matter of replacing the style prop with:
style={show ? styleWhenShow : styleWhenNoShow}
In case you don't want to repeat some common styles between the show and noshow styles, you can also do something like:
const commonStyle = {
display: "flex",
justifyContent: "center"
}
const styleWhenShow = {
height: "100px"
}
const styleWhenNoShow = {
height: "500px"
}
And set the style prop like:
style={show ? { ...commonStyle, ...styleWhenShow } : { ...commonStyle, ...styleWhenNoShow }}
I'm creating a single-page application (Material-UI based) with an AppBar (+ ToolBar) and a Drawer. At the moment, the Drawer overlaps the AppBar and under no circumstances can I get the Drawer to move down, so it is basically positioned right under the AppBar.
I tried adding some padding, but this does not do anything. I'm using makeStyles for styling of most of the components, and I am wondering if it is even possible to position the Drawer below the AppBar.
Is there any way to position the drawer below the AppBar?
I have a lot of code, but the makeStyle function is simple:
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
},
title: {
flexGrow: 1,
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
drawer: {
paddingTop: 30
},
}));
and the main component (that includes the Drawer:
<div className={classes.root}>
<AppBar position="absolute" >
<Toolbar>
<Typography component="h1" variant="h6" noWrap className={classes.title}>
x
</Typography>
<Switch checked={isDarkTheme} onChange={handleThemeSwitch}/>
<WbIncandescentIcon />
</Toolbar>
</AppBar>
<ServiceDrawer className={classes.drawer}
onOperationSelected={onOperationSelect} serviceList={services} onDrawerOpen={onDrawerOpen} onDrawerClose={onDrawerClose}>
</ServiceDrawer>
<main className={classes.content}>
<div className={classes.toolbar} />
{selectedOperation && <Operation operation={selectedOperation}/>}
</main>
</div>
You need to set the variant of the Drawer to permanent so that it does not create an overlay over the current page, and put it inside the current app layout. Because the Drawer position is fixed, you also have to set the AppBar to fixed so they're on the same stacking context, and the z-index will be applied correctly, to put it in code:
<Drawer variant="permanent"
<AppBar position="fixed"
And finally the zIndex itself
appBar: {
zIndex: theme.zIndex.drawer + 1
},
Reference
https://v4.mui.com/components/drawers/#clipped-under-the-app-bar
This question already has answers here:
How can I horizontally center an element?
(133 answers)
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Flexbox: center horizontally and vertically
(14 answers)
Closed 2 years ago.
I'm trying to center a basic user login in React JS using inline styles, but I can't seem to figure out how to do it. I'm using React Bootstrap and I have currently managed to partially center the form using flexbox, but it's still appearing at the top of the page. What do I need to do so that it appears right in the middle?
Please see the attached image for the current issue.
const LoginPage = () => {
return (
<Container >
<Row
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop:'5px'
}}
>
Enter API Key:
</Row>
<Row
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop:'5px'
}}
>
<Form>
<Form.Control
id='apiKeyString'
name='apiKey'
size='sm'
style={{ width: '250px' }}
onChange={(e) => setApiKey(e.target.value)}
></Form.Control>
</Form>
</Row>
<Row
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop:'5px'
}}
>
<Button type='submit' onClick={submitApiKey} size='sm'>
Submit
</Button>
</Row>
</Container>
);
};
To center vertically you'll have to set the Container inline style to the following:
{
height: '100vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}
This being done you can probably remove all the other styling.
Im creating a web interface which is listing various processes and services. These are all listed in React cards which all support expand/collapse - expanding the cards and showing more information. The information shown in expand will vary in size and information and I don't want the cards to adjust height if a card is expanded. The height is aligned when they are collapsed, but I'm unsure to how to not adjust them when a card is expanded. Example:
This image shows how the card height has been aligned to the card with the most content. This is the exact behaviour I want.
The problem occurs when I expand one of the boxes. The content in the other boxes gets aligned to the new size. I want the expand function to not effect the heigh of the other cards.
The custom class of the cards is listed here:
const infoCard = makeStyles({
root: {
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
height: "-webkit-fill-available"
}
})
const createCards:
const classes = infoCard();
...
...
return (
<React.Fragment>
<Card className={classes.root}>
<CardContent> "Add content" </CardContent>
<Collapse>
<CardContent> "Add content" </CardContent>
</Collapse>
</Card>
</React.Fragment>
)
I also want the result to support having additional rows of card below this row.
Does anyone know how to go around this problem?
Thanks in advance!
You need to add
align-items: flex-start;
to the styles of your root element, its stretch by default, which would stretch all the elements to be at the same height
const infoCard = makeStyles({
root: {
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "space-between",
height: "-webkit-fill-available"
}
})
I am working with React and I need put this button like that:
but I have a big problem because I am forbidden to use margin or other form of positional where I have values with px, or rem, basicaly static positional. Now, I have this code
<div style={{ float: 'right' }}>
<ActionButton style={{
display : 'flex',
flex : '1',
flexDirection: 'row',
alignItems : 'center',
justifyContent : 'center',
height: '40px',
width: '151px',
}} name={<div style = {{
display : 'flex',
flex : '2',
backgroundColor : 'red',
float : 'right'
}}>FILTRAR</div>}
icon={<div style = {{
display : 'flex',
flex : '2',
backgroundColor : 'blue',
width: '24px',
height: '24px',
float : 'left'}}><FilterIcon/></div>}>
</ActionButton>
</div>
And now my button is like that
Parent's styles should already align children (name and icon) by the center, not by the top. And yes, no positioning styles are required, unless there are hardcoded heigh/margin values in children itself.
Desired behavior can be broken because of the implementation of ActionButton.
Anyway, my suggestions to tackle this issue:
use flex-direction: 'row-reverse' instead of floats;
remove display: 'flex' from child elements.
Here is a simplified and working example for web https://codesandbox.io/s/62nynm1wzk, hope it can help you to get started.
Update: here is an example using button instead of div as container, since it is closer to original markup: https://codesandbox.io/s/y7q1vlwkwj
You can use margin in % (ie: 50%) and then use transforms, in percent (ie: transform: translateX(-50%), to adjust position. If you can provide a static stylable html I can produce an example for you.
Try to remove the flex and display style property in name and icon props like below and check it. Because flex:2 will change the width of child element with equal spacing.
<div style={{ float: 'right' }}>
<ActionButton style={{
display : 'flex',
flex : '1',
flexDirection: 'row',
alignItems : 'center',
justifyContent : 'center',
height: '40px',
width: '151px',
}} name={<div style = {{
backgroundColor : 'red',
float : 'right'
}}>FILTRAR</div>}
icon={<div style = {{
backgroundColor : 'blue',
width: '24px',
height: '24px',
float : 'left'}}><FilterIcon/></div>}>
</ActionButton>
</div>