I have a ListGroup with ListGroupItems that get populated by some data. Part of that data is a description, which obviously varies in length.
<ListGroup className="signal-info-container">
{
signalConstants[this.props.signalType].map((signal, i) => (
<ListGroupItem key={i}>
<Row>
<Col xs={3}>
{signal.name}
</Col>
<Col xs={5}>
{signal.description}
</Col>
<Col xs={3} className="aggregation">
<Checkbox inline={true}></Checkbox>
<Checkbox inline={true}></Checkbox>
<Checkbox inline={true}></Checkbox>
<Checkbox inline={true}></Checkbox>
</Col>
</Row>
</ListGroupItem>
))
}
</ListGroup>
Sometimes that description needs to wrap (as seen below).
What I would like to have happen is for the checkboxes in the right column vertically align in the center of the col.
I have tried to override react-bootstrap with some custom css. The following css results in the previous image.
.aggregation {
display: flex;
align-items: center;
}
Not sure how relevant it is, but the columns have a height of 0px. What confuses me is why the single-line descriptions are centered, but multi-line descriptions are not. Here is an image of the 0px cols:
I have noticed that there seems to be some sort of label applied to the checkbox which is getting centered by the applied CSS, but I need it applied on the actual checkbox instead. I have just removed the title attribute from my checkboxes. The effect is still the same (labels weren't showing up anyways).
You need to apply display: flex; align-items: center; to the entire <tr> so it recognizes the multi-line descriptions. So you should add a class to the <Row> that uses these rules.
Try modifying your component as so:
<ListGroup className="signal-info-container">
{
signalConstants[this.props.signalType].map((signal, i) => (
<ListGroupItem key={i}>
<Row>
<Col xs={3}>
{signal.name}
</Col>
<Col xs={5}>
{signal.description}
</Col>
<Col xs={3}>
<CheckboxRow>
<Checkbox title='min' inline={true}></Checkbox>
<Checkbox title='max' inline={true}></Checkbox>
<Checkbox title='avg' inline={true}></Checkbox>
<Checkbox title='sum' inline={true}></Checkbox>
</CheckboxRow>
</Col>
</Row>
</ListGroupItem>
))
}
</ListGroup>
Where CheckboxRow is
const CheckboxRow = ({children}) => (
<div style={
"display": "flex",
"justify-content": "center",
"align-items": "center"
}>
{children}
</div>
)
or extract that CSS out to a stylesheet if you have one.
Reason for adding the extra div layer is that it's safer than trying to override styles on the column components, since it's purpose is not to lay elements our horizontally.
The 'justify-content: center' centers the items horizontally, 'align-items: center' centers the items vertically.
Related
I have this code that maps and displays my website's posts from an array.
import articleContent from '../data/articleContent';
const ArticlesList = () => (
<>
<ArticlesStyle>
<h1 className="article-h1">Nasze artykuły</h1>
{articleContent.map((article, key) =>
<Link className="article-link" key={key} to={`/artykul/${article.name}`}>
<Row className="align-items-center text-center">
<Col xs={4} md={5}>
<h2 style={{ color: '#14B2E6' }}>{article.title}</h2>
</Col>
</Row>
<Row className="align-items-center text-center">
<Col className="text-left" xs={8} md={5}>
<p style={{ color: 'black' }}>{article.content[0].substring(0, 150)}...</p>
</Col>
</Row>
</Link>
)}
</ArticlesStyle>
</>
)
My goal is to automatically display two posts in one row (so two columns in a row I guess) on PC display and one post in a row on mobile. I tried to make some small adjustments to make it work, but I am clueless now.
This is how it looks now on PC, I can't get rid of this marked area - I think it's an issue related to display: flex;.
You can use CSS-grid for this. For web make the number of column 2 and then by using media queries in CSS you can make the number of column 1 in case of mobile width.
Ok, so I managed to solve my own problem.
First of all I added outer (outer to .map function) Row and Col. I wrapped everything inside of .map function into Container.
const ArticlesList = () => (
<>
<ArticlesStyle>
<Row>
<Col className="article-list-grid">
{articleContent.map((article, key) =>
<Container className="wrapper">
<Link className="article-link" key={key} to={`/artykul/${article.name}`}>
<Row className="align-items-center text-center">
<Col xs={true} md={true}>
<h2 style={{ color: '#14B2E6' }}>{article.title}</h2>
</Col>
</Row>
<Row className="align-items-center text-center">
<Col xs={true} md={true}>
<p style={{ color: 'black' }}>{article.content[0].substring(0, 150)}...</p>
</Col>
</Row>
</Link>
</Container>
)}
</Col>
</Row>
</ArticlesStyle>
</>
)
After that everything comes to styling which looks like this:
const ArticlesStyle = styled.div`
.article-list-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.wrapper {
#media (max-width: 600px) {
flex: 100%;
}
#media (min-width: 900px) {
flex: 50%;
}
}
.article-link {
text-decoration: none;
}
`;
The most important thing here is flex: 50% on PC screens which result with 2 columns in a row. Everything looks as I wanted right now:
PC
MOBILE
I'm trying to implement a card component with multiple columns with the first column set as an edit button and the last column as a details button. Something like this
I'm using reactstrap library to do this but but I'm not able to set a background to the whole height of a card instead of just the column height. This is my code
import {
Card,
CardImg,
CardText,
CardBody,
CardTitle,
CardSubtitle,
Button
} from 'reactstrap';
return (<Card style={{
textAlign: "left",
margin:"3%",
padding:"3%"
}}>
<Row style={{
display: "flex"
}}>
<Col sm="3">
<CardImg top="top" style = {{width:"80%", margin: "0.1rem"}} src={logo} alt="Card image cap"/>
</Col>
<Col sm="9">
<CardBody>
<CardTitle tag="h5" style={{fontWeight:"bold"}}>Project title</CardTitle>
<Row style = {{display: "flex"}}><Col sm="6">{data.profName}</Col>
<Col sm="6">{data.dept}</Col>
</Row>
<CardText style={{color:"#000000"}}>{data.description}</CardText>
<Row style={{
display: "flex",
fontSize:"20px"
}}>
<Col sm="3" style={{alignItems:"center"}}><img src="a1.png" alt="" style={{width:"20%"}}/>{data.duration} months</Col>
<Col sm="3" style={{alignItems:"center"}}><img src="a3.png" alt="" style={{width:"20%"}}/>{data.totalSlots} students</Col>
<Col sm="3" style={{alignItems:"center"}}><img src="a2.png" alt="" style={{width:"20%"}}/>INR {data.stipend}</Col>
<Col sm="3" style={{background:"rgb(15, 135, 151)", padding:"0", margin:"0"}}>
<center>
<Link to ={"/Projects/" + data["project-uid"]}><Button style={{
backgroundColor: "#0F8797",
color: "white"
}}>Details</Button></Link>
</center>
</Col>
</Row>
</CardBody>
</Col>
</Row>
</Card>);
Which makes the Details button look like this
Why don't you try putting the buttons outside of the card? You can make a row that contains the card with a button before and a button after. The buttons will be the full height of the row, and you can make the row flex and apply flex-grow to the card, with the buttons having fixed widths.
Am using antd components for ui design, while using these components some of the components works and others not.
Imported all of the components
import {
Table,
Typography,
Select,
Space,
Row,
Col,
Form,
Button,
Layout,
Tag,
Badge,
Title,
Content,
Divider,
Progress,
Text
} from "antd/lib";
<Row>
<Col span={12} />
<Col span={12} pull={5}></Col>
<Layout>
<Content style={{ padding: "30px 20px" }}>
<div style={{ padding: 24, backgroundColor: "#fff" }}>
<Title level={4}>Coverage Report</Title>
<Divider />
<Row justify="space-between">
<Col span={6}></Col>
<Col span={6}>
<Progress type="circle" percent={100} />
</Col>
<Col span={6} style={{ marginTop: "50px" }}>
<Text strong>
{data.length - selectedRowKeys.length} tests are available to test
</Text>
</Col>
<Col span={6}></Col>
</Row>
</div>
</Content>
</Layout>
</Row>
No issue with Row, Col, and Layout components beacause i have already used these components before this code, the issue is with other components like Content, Title, Text and Progress.
Antd version - ^4.7.2
React - ^17.0.1
I believe this is because you aren't importing Content, Title and Text correctly. Looking at docs for Title and Text it is part of Typography.
const {Title, Text} = Typography;
const {Content} = Layout;
How can I make the card appear where there are 2 columns for the 1st card and then another 2 columns far the second card? So for, this is what it shows.
but I wanted it to look like this:
these are my codes for the styling:
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
padding: theme.spacing(2),
},
media: {
height: 300,
},
}));
and these are my codes for the card:
<div className={classes.root}>
<Grid
container
spacing={12}
direction="row"
justify="flex-start"
alignItems="center"
>
{data.map((elem) => (
<Grid item xs={12} sm={6} md={3} key={data.indexOf(elem)}>
<Card>
<CardHeader title={name} subheader={desc} />
<CardMedia
className={classes.media}
image={img}
title={name}
/>
</Card>
</Grid>
))}
</Grid>
</div>
It seems like the cards are stretched to full width, which prevents them from sharing the same flex-row.
There are lots of possible solutions to this. One could be to set a max-width on the cards so they don't fill the whole row. That way they would have space to sit besides each other like in your example.
I am building a web application in react and using reactstrap for certain ui design elements. I have arranged elements in row and columns. Everything else works fine but the button element is not getting aligned properly like the other elements in the row are. The button is slightly below than the other elements. Can someone tell me what i am doing wrong? Any help would be appreciated. Thank You.
App.js
<Container>
<Row>
<Col>
<text>{item1.Title}</text>
</Col>
<Col>
<input type="text" onChange={this.handleNameChange}/>
</Col>
<Col>
<Button onClick={()=>this.handleName(this.state.itemName,item1.Title,item.Title)} color="success" size="sm" >Save</Button>
</Col>
</Row>
</Container>
UPDATE
The button column seems to be having some sort of padding.
The textbox doesnt have any padding
give the 3rd Col a className and use the following css:
.class-col {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
height: 100%;
}
.main-container {
display: flex;
}
And you code:
<Container>
<Row className="main-container">
<Col className="class-col">
<text>{item1.Title}</text>
</Col>
<Col className="class-col">
<input type="text" onChange={this.handleNameChange}/>
</Col>
<Col className="class-col">
<Button onClick={()=>this.handleName(this.state.itemName,item1.Title,item.Title)} color="success" size="sm" >Save</Button>
</Col>
</Row>
</Container>
Give this a try.