How to position one React component inside another (grid) component - css

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>
</>
);

Related

Semantic UI Resizing Divider Parts?

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>

In React and Material-UI how do I make my Grid items take up 100% of available horizontal space w/o wrapping to the next row?

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.

How to have different horizontal and vertical spacing in MUI Grid?

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>

PopUp to contains other controls like DateTime Picker,dropdownlist

newbie here. I remember in Win10, there is a PopUp UI which can contains many controls like Dropdown box, DatePciker and others. This PopUp can be constructed in Xaml.
I am developing an app for Tablet.
It is possible to use such PopUp in Xamarin forms which contains Dropdown List, DatePicker, Time Picker? It is advisable to do such complex UI ? will it cause problem in Android and iOS?
Problem : How to create PopUp in Xaml
so ,I can use a button to open or close it.
var button = new Button {Text = "Show Popup"};
button.Clicked += (s, e) => popup.Show();
Update
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.View.PopUpDemo"
Title="PopUp Demo"
Icon="itemIcon3">
<Grid>
<Grid>
<!--Your Page xaml-->
<Button x:Name="btnPopUp" Click="ShowPopUp"/>
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
</ContentPage>
I would like to know :
I am using a normal ContentPage.
1) In it, i place your MarkUp <Grid> ,I remove <ContentPage.Content>. Is this correct?
2) Is Frame will be the PopUp ?
3) what code to use in btnPopUp to show the PopUp?
Thanks
Yes you can achieve it without any performance issue. Either you can use an overlay to show pop up as shown below
<Grid>
<Grid>
<!--Your Page xaml-->
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
This one is quite simple. Here i have added grid to achieve this. You can also use other layouts. But for performance grid is better as per xamarin team.
For the second grid i have added Visibility property so that you can wire up with any event.
Here i have added backgroundcolor for popup ##60000000 so that when popup appears background will be transparent with light black color effect.
If you need to have same pop up in multiple screens you can use 3rd party plugin https://github.com/rotorgames/Rg.Plugins.Popup which will make you work easier. For this you have to make a new contentpage, replace the contentpage with
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class=""
BackgroundColor="##60000000"
InputTransparent="True"
HasSystemPadding="True"
CloseWhenBackgroundIsClicked="False">
<pages:PopupPage.Animation>
<animations:MoveAnimation
PositionIn="Bottom"
PositionOut="Bottom"/>
</pages:PopupPage.Animation>
<Grid>
<!--your xaml code-->
</Grid>
Note:Replace contentPage with PopupPage in youpage.xaml.cs. To get popup effect your layout should be like 1st example i shown. Here you can also get nice animation effects. More details you can see in their site.
Now you can call the pop up by calling:navigation.PushPopupAsync(new YourContentPage());
And remove the popup by calling await PopupNavigation.RemovePageAsync(this);
Hope this will be useful for you

xamarin.forms page navigation is too slow

My page has following hierarchy.
<Grid>
<AbsoluteLayout Grid.Row = 0>
// Contains header
</AbsoluteLayout>
<AbsoluteLayout Grid.Row = 1>
<Scrollview>
<Grid>
<AbsoluteLayout Grid.Row = 0>
// Contains Image
</AbsoluteLayout>
<Grid>
<ListView Grid.Row = 0>
// I know its not good thing to use listview inside scrollview but I have to use it.
</ListView>
<Button Grid.Row = 1 Text = "Add Item1"/>
</Grid>
<Grid>
<ListView Grid.Row = 0>
</ListView>
<Button Grid.Row = 1 Text = "Add Item2"/>
</Grid>
</Grid>
</Scrollview>
</AbsoluteLayout>
<AbsoluteLayout Grid.Row = 2>
// Contains Footer
</AbsoluteLayout>
</Grid>
Now when I navigate to this page on click of button it takes around 3-4 seconds to load which is I think too much.
I have used only 2 StackLayout in footer because I read that Stacklayout slows down the application.
Is there any other way so that I can speed up my navigation ?
EDIT - It takes 1 second to jump from constructor to OnAppearing(). In OnAppeaeing() I fill the lists shown in code.
Thank you so much.

Resources