In MUI Grid, to space Grid Item vertically, I provided spacing in Grid Container. It looks good on big screens but on mobile, it results in awkward horizontal spacing between Grid Items.
<Grid container spacing={24}>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
</Grid>
How can I have different vertical and horizontal spacing in Grid?
You must understand how grid works internally. Material UI Grid layout is based on the flexbox model. So, setting container attribute on Grid, sets "display flex" on it. Now items in this flex box can either flow horizontally or vertically, thus either horizontal spacing can be given or vertical spacing can be given but not both.
If you set "direction" attribute to "column" on Grid as shown:
<Grid container direction={'column'} spacing={24}>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
</Grid>
Then spacing provided will act as vertical spacing between the items and items will be arranged vertically.
Now If items are required to arrange horizontally then above code will be changed as shown:
<Grid container direction={'row'} spacing={24}>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
<Grid item xl={6} md={6} sm={12} xs={12}>
<TextField
required
id="outlined-email-input"
label="Customer Name"
name="email"
fullWidth
/>
</Grid>
</Grid>
Here, in this implementation spacing will act as horizontal spacing. Also, this is the default implementation if in case you not specify "direction" attribute.
Now to switch between 2 layouts in mobile and desktop, we can do it as:
Implement a css class using media query that set "display" to "none" for mobile type device and "initial" for desktop type device. Let's name it "display-lg". And in similar way, make class "display-sm" that show element on mobile and hide it on desktop. Apply "display-lg" on grid layout that is to be shown on desktop and "display-sm" on grid layout that is to be shown on mobile.
This approach may seems you long and redundant but it provides you liberty to add more mobile specific changes in your layout in future.
Please feel free to comment if you need more clarity on answer.
This is possible in MUI v5, simply use rowSpacing and columnSpacing instead of spacing. See this example from the docs:
<Grid container rowSpacing={1} columnSpacing={3}>
<Grid item xs={6}>
<Item>1</Item>
</Grid>
<Grid item xs={6}>
<Item>2</Item>
</Grid>
<Grid item xs={6}>
<Item>3</Item>
</Grid>
<Grid item xs={6}>
<Item>4</Item>
</Grid>
</Grid>
Live Demo
Yeah I am wondering the same thing, the docs imply that Grid is based on a 12 "column" layout. So when you want a 75/25 split horizontally between two components its as easy as xs={8} and the other set at xs={4}.
I think OP is asking how to do the same thing but vertically. I too am searching for a solution, but I believe the method does not lie within the Grid component. Will try to use additional CSS to solve the issue I have.
EDIT:
Yup, looks like there is no way to do this within the component itself.
From the documentation
The properties which define the number of grids the component will use for a given breakpoint (xs, sm, md, lg, and xl) are focused on controlling width and do not have similar effects on height within column and column-reverse containers. If used within column or column-reverse containers, these properties may have undesirable effects on the width of the Grid elements.
The components have a attribute called gap, you can pass a string as value, similar to the CSS Grid and CSS FlexBox.
<Grid gap="20px 50px">
//Grid items...
</Grid>
Related
I'm making a News website and I have a component that maps over articles (that i fetched from an API) and displays them in a grid. I also have a separate component that displays Latest News.
I need to position the Latest News widget "inside" the article grid, in a way where the Latest news widget will make up the 3rd and 6th element of the grid. Here's an example:
How do i do this?
Your return can look like this. Remove the first four elements and map the rest. I have considered MUI grid component here but the logic will be same everywhere.
return (
<>
<Grid container spacing={2}>
<Grid item lg={8}>
<Grid container spacing={2}>
<Grid item lg={6}>
{news[0]}
</Grid>
<Grid item lg={6}>
{news[1]}
</Grid>
<Grid item lg={6}>
{news[2]}
</Grid>
<Grid item lg={6}>
{news[3]}
</Grid>
</Grid>
</Grid>
<Grid item lg={4}>
<Grid container>
<Grid item> Latest News</Grid>
</Grid>
</Grid>
{news.slice(4).map((new) => {
return <Grid item lg={4}>{new}</Grid>;
})}
</Grid>
</>
);
I am using Divider component from Semantic-ui for dividing a segment vertically, it divides the segment 50/50 i think is there way to make it 70/30 60/40 basically whichever i like ? Thanks for help!
This can be done in a Segment component by adding a grid and change width props from Grid.column like this:
<Segment>
<Grid stackable>
<Grid.Column width={4}>
<Image src="https://react.semantic-ui.com/images/wireframe/image.png" />
</Grid.Column>
<Grid.Column>
<Divider vertical> or </Divider>
</Grid.Column>
<Grid.Column width={9}>
<Image src="https://react.semantic-ui.com/images/wireframe/paragraph.png" />
</Grid.Column>
</Grid>
</Segment>
I'm using Material-UI in a React 16.10 application. I want to display a table with an icon in the left column and then a label and address, stacked on top of each other in the right column. I want the items in the right column to take up 100% of the available space. So I have this class
fullWidth: {
backgroundColor: "red",
width: "100%",
},
(the background color was just so I could see what was going on). I created this table ...
<Grid container direction="row" alignItems="top" spacing={1} className={classes.fullWidth}>
<Grid item>
<LocationOnIcon />
</Grid>
<Grid item>
<Grid container direction="column" alignItems="center">
<Grid item className={classes.fullWidth} style={{backgroundColor: "yellow"}}>
<TextField
className={`${classes.rootInput} ${classes.input}`}
id="pickupLocationLabel"
value={values.pickUpLocationLabel}
placeholder="Label"
variant="outlined"
disabled={false}
onChange={handleChangePickUpLocationLabel}
fullWidth
/>
</Grid>
<Grid item className={classes.fullWidth}>
<AddressInput
className={classes.textField}
placeholder={values.pickUpLocation?.address}
stage={values.pickUpLocation}
setStage={handleChangeLocation.bind(null, "pickUpLocation")}
setLocation={handleChangeLocation}
/>
</Grid>
</Grid>
</Grid>
</Grid>
However, the items didn't take up 100% of the available width ...
When I added the fullWidth class to the parent container,
<Grid container direction="row" alignItems="top" spacing={1} className={classes.fullWidth}>
<Grid item>
<LocationOnIcon />
</Grid>
<Grid item className={classes.fullWidth}>
<Grid container direction="column" alignItems="center">
<Grid item className={classes.fullWidth} style={{backgroundColor: "yellow"}}>
<TextField
className={`${classes.rootInput} ${classes.input}`}
id="pickupLocationLabel"
value={values.pickUpLocationLabel}
placeholder="Label"
variant="outlined"
disabled={false}
onChange={handleChangePickUpLocationLabel}
fullWidth
/>
</Grid>
<Grid item className={classes.fullWidth}>
<AddressInput
className={classes.textField}
placeholder={values.pickUpLocation?.address}
stage={values.pickUpLocation}
setStage={handleChangeLocation.bind(null, "pickUpLocation")}
setLocation={handleChangeLocation}
/>
</Grid>
</Grid>
</Grid>
</Grid>
Then the items no longer lined up alongside the icon.
How do I adjust things to that they take up 100% of the available width without wrapping to the next row?
Why are you using classes.fullWidth for the sizing of the Grid items? Material-UI offers a Bootstrap type system that allows you to size items in the Grid depending on the size of the screen. Check out the Grid API documentation.
Try ditching classes.fullWidth and replacing it with xs=12 and see if that does the trick and gets the element to take up the full width.
There is also a wrap/nowrap prop you can pass to the Grid item to deal with wrapping.
<ScrollView id="scrollGeneric" height ='auto' visible='false'>
<View id="formView" height='auto'>
<View id='distSlider' top='0' height='100'>
<Label id="lblGeneric" >
Search Distance:
</Label>
<Slider id="sliderDistance" top="50" min="2" max="80" width="50%"/>
<Label id="sliderDistanceText" width='auto' top="50" right="40" />
<Label id="sliderDistanceTextMeasure" width='auto' top="50" right="10" text="km" />
</View>
</View>
</ScrollView>
I have set the height auto for scrollView and formView. However whenever I add more views inside of the formView the size of the window does not expand vertically with it. It will eventually crop out the views that exceed the window height.
The only way to solve this is to manually specify the height of each view within the form view div.
Is there anyway I can avoid doing this, thanks
Have you tried using Ti.UI.SIZE instead for the height? As per the documentation, "height:auto is not recommended for new development and will be deprecated in the future."
I want to create a window that I can style its shape (for example close button). Based on my reading I can not style these sections of a windows as they are not client sections and they are handeled by OS.
To create my own winmdows style, I created a border less windows( style=none) and I am trying to place the buttons on window by myself.
In my design the top of window should have an image on left hand side and close/minimize/maximise buttons on right.
I have this xaml which would shows logo on left and a button on right.
<DockPanel>
<DockPanel DockPanel.Dock="Top" Height="50" Background="DarkGray" Width="Auto" cal:Message.Attach="[Event MouseLeftButtonDown] = [Action MoveWindow]">
<Image DockPanel.Dock="left" Height="47" Source="/Resources/Images/Toplogo.png"/>
<Button DockPanel.Dock="Right" Width="16" Height="14" x:Name="CloseWindow" />
</DockPanel>
But when I run the application, I can see that the logo is on left, but close button is not on the right, but it is in the middle and if I change the window size, logo and button move to the middle of window ( the dockpanel is not resize.)
How can I create such behaviour in xaml?
The DockPanel defaults to `LastChildFill="True"' so the final element within the DockPanel (your button) fills the remaining space.
You can fix it by adding HorizontalAlignment="Right" to the button, or LastChildFill="False" to the inner DockPanel.
I would use a Grid and create two rows. One for the "window bar" and the other for the "content".
Example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</<Grid.ColumnDefinitions>
<!-- Header w/ button -->
<Grid Grid.Row="0" Background="DarkGray" Height="50" Grid.Column="0" HorizontalAlignment="Stretch">
<Image Height="47" Source="/Resources/Images/Toplogo.png" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Button Width="16" Height="14" x:Name="CloseWindow" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
<!-- Body of Window -->
<Grid Grid.Row="1" Grid.Column="0">
</Grid>
</Grid>