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"
}
})
Related
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',
},
}}
{...}
>
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
I have a problem with a Material-UI Table component and its size and scrollability.
Short:
The Material-UI table component becomes only scrollable, if its parent has a fixed size. If I set the size to fit the parent 100%, it overflows.
Long:
I have a simple WebApp in Reactjs that consists of a header, a body (where the table lives) and a footer. My App component is styled to distribute those three base layout components as follows:
const useStyles = makeStyles((theme) => ({
root: {
height: "100vh",
maxHeight: "100vh",
display: "grid",
gridTemplateRows: "auto 1fr auto",
},
}));
That works just fine. My body component takes up all the available space to fill the full viewport. The component looks as follows:
<div className={classes.root}>
<Controls /> //just some buttons, arranged in one line
<Table /> //my table component, which uses pagination
</div>
The table itself uses pagination and mounts with a default of 10 rows per page.
And the CSS for it looks like that:
root: {
maxHeight: "100%",
display: "grid",
gridTemplateRows: "min-content 1fr",
gap: "25px",
},
The table component itself looks like this:
<div className={classes.root}>
{loading ? loadingAlert : <></>}
<Paper elevation={3} className={classes.tableRoot}>
<TableContainer className={classes.container}>
<Table size="small" stickyHeader aria-label="sticky table">
[...]
The CSS for my Table component looks like that:
const useStyles = makeStyles({
root: {
maxHeight: "100%",
},
tableRoot: {
width: "100%",
maxHeight: "100%",
},
container: {
maxHeight: "100%", <---
},
footer: {
display: "grid",
gridTemplateColumns: "1fr min-content",
},
});
When the user changes the displayed rows per page from 10 to 25, the height of the table changes. In that case, I want the table to take up all the free space within body and become scrollable. If I set the maxHeight of container to a fixed pixel-value, the table becomes scrollable and won't overflow. If I leave it like that, the table overflows and user has to scroll to reach the end of the page.
Can anyone tell me how I can set the height for my container to fit its parent 100% without my table overflowing?
if you use a DataGrid of Material UI, you can use a prop called autoHeight
<DataGrid autoHeight {...data} />
<p>more content</p>
you can check more details in this docs
Is there any way to style elements (from the ratings view) in such a way that there's automatically some space between them? I thought of printing text (white spaces) but that doesn't sound like an ideal solution. What else can I do?
<View style={styles.introContainer}>
<Text style={styles.name}>{firstName}</Text>
<View style={styles.ratings}>
<Icon name="user" size={moderateScale(20)} />
<Icon name="star" size={moderateScale(13)} />
<Text style={styles.rating}> {rating}</Text>
</View>
</View>
ratings: {
flexDirection: 'row',
//alignContent: 'center',
alignItems: 'baseline',
},
introContainer: {
alignItems: 'center',
paddingTop: 50,
width: '100%',
},
add margin or padding to whatever element you want to give it more space
or you could apply a width to a few elements and use
display: flex;
justify-content: space-between;
so they are spaced equally
If you are referring to the children of View component you can try to use:
.ratings > * {
// your css here
}
By using > you are targeting direct children of the parent selector ( in this case the .ratings class selector.
* means any kind of children element, although you should be more specific if you can (all children should be targeted by the same class or be the same html element)
css child combinator
UPDATE
Sorry, there is no support for grid by default in React Native, so option 3 is discarded unless you want to use a third-party library like https://www.npmjs.com/package/react-native-responsive-grid
Option 1:
Give the star icon a right and left margin
Option 2:
Add width and display: flex to the ratings style and set the justifyContent to space-between or space-around
Option 3:
Use grid instead of flex and set a grid-gap
I am trying to scroll a view over another view in React Native.
render() {
return (
<View style={{
flex: 1
}}>
//THIS IS A BACKGROUND VIEW
<BackgroundView />
//THIS IS THE FOREGROUND VIEW
<View style={{
borderWidth: 1,
}}>
<FlatList
data={cards}
refreshing={this.state.isRefreshing}
onRefresh={this.onRefresh}
renderItem={({ item, index }) => <Card {...item} />}
keyExtractor={(item, index) => index}
onEndReached={this.loadMore}
onEndReachedThreshold={2} />
</View>
</View>
)
}
I want the foreground view, which contains the FlatList to scroll over the BackgroundView
I have tried using position:absolute on the ForegroundView but the FlatList stopped working and I could not scroll.
EDIT : Initially the BackgroundView is shown (contains some intro content), with the ForegroundView on the bottom partially, and as the user scrolls on the screen, The ForegroundView is scrolled over it
This is working:
For your background view use the style '...StyleSheet.absoluteFillObject', or:
{ position: ('absolute': 'absolute'),
left: 0,
right: 0,
top: 0,
bottom: 0,
}
As noted in the comment depending of your design, the foreground will often fill the entire View, making the background impossible to interact with.
The only solution I have found is making the foreground positionned absolute and cover the minimal surface as possible. It works if the view is kept simple.
Example here for a button container on the bottom of the screen, that does not overlaps top, left and right of the Background:
bottomButtonContainer: {
position: 'absolute',
flex: 1,
alignItems: 'center',
bottom: 0,
marginVertical: 5,
marginHorizontal: '25%',
width: '50%',
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'center',
},